tulih-editor 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +331 -0
  3. package/dist/tulih-editor.css +1 -0
  4. package/dist/tulih-editor.es.js +3051 -0
  5. package/dist/tulih-editor.es.js.map +1 -0
  6. package/dist/tulih-editor.umd.js +8 -0
  7. package/dist/tulih-editor.umd.js.map +1 -0
  8. package/dist/types/core/Editor.d.ts +20 -0
  9. package/dist/types/core/PluginManager.d.ts +22 -0
  10. package/dist/types/core/helpers.d.ts +22 -0
  11. package/dist/types/index.d.ts +5 -0
  12. package/dist/types/plugins/align.d.ts +3 -0
  13. package/dist/types/plugins/autoLinkify.d.ts +3 -0
  14. package/dist/types/plugins/autosave.d.ts +3 -0
  15. package/dist/types/plugins/block.d.ts +3 -0
  16. package/dist/types/plugins/caseTransform.d.ts +3 -0
  17. package/dist/types/plugins/codeBlock.d.ts +3 -0
  18. package/dist/types/plugins/colors.d.ts +3 -0
  19. package/dist/types/plugins/darkMode.d.ts +3 -0
  20. package/dist/types/plugins/direction.d.ts +3 -0
  21. package/dist/types/plugins/dragDrop.d.ts +3 -0
  22. package/dist/types/plugins/emoji.d.ts +3 -0
  23. package/dist/types/plugins/emojiAutocomplete.d.ts +3 -0
  24. package/dist/types/plugins/findReplace.d.ts +3 -0
  25. package/dist/types/plugins/floatingToolbar.d.ts +3 -0
  26. package/dist/types/plugins/fontFamily.d.ts +3 -0
  27. package/dist/types/plugins/fontSize.d.ts +3 -0
  28. package/dist/types/plugins/fullscreen.d.ts +3 -0
  29. package/dist/types/plugins/history.d.ts +3 -0
  30. package/dist/types/plugins/hr.d.ts +3 -0
  31. package/dist/types/plugins/iframe.d.ts +3 -0
  32. package/dist/types/plugins/image.d.ts +3 -0
  33. package/dist/types/plugins/imageProps.d.ts +3 -0
  34. package/dist/types/plugins/imageTools.d.ts +3 -0
  35. package/dist/types/plugins/indent.d.ts +3 -0
  36. package/dist/types/plugins/index.d.ts +2 -0
  37. package/dist/types/plugins/inline.d.ts +3 -0
  38. package/dist/types/plugins/inlineCode.d.ts +3 -0
  39. package/dist/types/plugins/keyboardShortcuts.d.ts +3 -0
  40. package/dist/types/plugins/lineHeight.d.ts +3 -0
  41. package/dist/types/plugins/link.d.ts +3 -0
  42. package/dist/types/plugins/linkTooltip.d.ts +3 -0
  43. package/dist/types/plugins/list.d.ts +3 -0
  44. package/dist/types/plugins/markdown.d.ts +3 -0
  45. package/dist/types/plugins/mediaEmbed.d.ts +3 -0
  46. package/dist/types/plugins/pasteImage.d.ts +3 -0
  47. package/dist/types/plugins/pastePlain.d.ts +3 -0
  48. package/dist/types/plugins/pre.d.ts +3 -0
  49. package/dist/types/plugins/readOnly.d.ts +3 -0
  50. package/dist/types/plugins/shortcutCustomizer.d.ts +3 -0
  51. package/dist/types/plugins/shortcutsHelp.d.ts +3 -0
  52. package/dist/types/plugins/source.d.ts +3 -0
  53. package/dist/types/plugins/specialChars.d.ts +3 -0
  54. package/dist/types/plugins/statusBar.d.ts +3 -0
  55. package/dist/types/plugins/subSuper.d.ts +3 -0
  56. package/dist/types/plugins/table.d.ts +3 -0
  57. package/dist/types/plugins/tableBg.d.ts +3 -0
  58. package/dist/types/plugins/tableTools.d.ts +3 -0
  59. package/dist/types/plugins/toolbarCollapse.d.ts +3 -0
  60. package/dist/types/plugins/unlink.d.ts +3 -0
  61. package/dist/types/plugins/wordCount.d.ts +3 -0
  62. package/dist/types/types.d.ts +226 -0
  63. package/package.json +66 -0
  64. package/src/core/Editor.ts +460 -0
  65. package/src/core/PluginManager.ts +140 -0
  66. package/src/core/helpers.ts +209 -0
  67. package/src/css.d.ts +2 -0
  68. package/src/index.ts +87 -0
  69. package/src/plugins/align.ts +72 -0
  70. package/src/plugins/autoLinkify.ts +34 -0
  71. package/src/plugins/autosave.ts +69 -0
  72. package/src/plugins/block.ts +32 -0
  73. package/src/plugins/caseTransform.ts +54 -0
  74. package/src/plugins/codeBlock.ts +93 -0
  75. package/src/plugins/colors.ts +68 -0
  76. package/src/plugins/darkMode.ts +123 -0
  77. package/src/plugins/direction.ts +30 -0
  78. package/src/plugins/dragDrop.ts +68 -0
  79. package/src/plugins/emoji.ts +188 -0
  80. package/src/plugins/emojiAutocomplete.ts +183 -0
  81. package/src/plugins/findReplace.ts +229 -0
  82. package/src/plugins/floatingToolbar.ts +258 -0
  83. package/src/plugins/fontFamily.ts +41 -0
  84. package/src/plugins/fontSize.ts +32 -0
  85. package/src/plugins/fullscreen.ts +36 -0
  86. package/src/plugins/history.ts +14 -0
  87. package/src/plugins/hr.ts +118 -0
  88. package/src/plugins/iframe.ts +88 -0
  89. package/src/plugins/image.ts +107 -0
  90. package/src/plugins/imageProps.ts +119 -0
  91. package/src/plugins/imageTools.ts +344 -0
  92. package/src/plugins/indent.ts +29 -0
  93. package/src/plugins/index.ts +101 -0
  94. package/src/plugins/inline.ts +17 -0
  95. package/src/plugins/inlineCode.ts +21 -0
  96. package/src/plugins/keyboardShortcuts.ts +92 -0
  97. package/src/plugins/lineHeight.ts +40 -0
  98. package/src/plugins/link.ts +344 -0
  99. package/src/plugins/linkTooltip.ts +63 -0
  100. package/src/plugins/list.ts +141 -0
  101. package/src/plugins/markdown.ts +61 -0
  102. package/src/plugins/mediaEmbed.ts +44 -0
  103. package/src/plugins/pasteImage.ts +61 -0
  104. package/src/plugins/pastePlain.ts +43 -0
  105. package/src/plugins/pre.ts +11 -0
  106. package/src/plugins/readOnly.ts +46 -0
  107. package/src/plugins/shortcutCustomizer.ts +125 -0
  108. package/src/plugins/shortcutsHelp.ts +51 -0
  109. package/src/plugins/source.ts +77 -0
  110. package/src/plugins/specialChars.ts +64 -0
  111. package/src/plugins/statusBar.ts +85 -0
  112. package/src/plugins/subSuper.ts +20 -0
  113. package/src/plugins/table.ts +166 -0
  114. package/src/plugins/tableBg.ts +11 -0
  115. package/src/plugins/tableTools.ts +475 -0
  116. package/src/plugins/toolbarCollapse.ts +14 -0
  117. package/src/plugins/unlink.ts +29 -0
  118. package/src/plugins/wordCount.ts +34 -0
  119. package/src/styles/base.css +258 -0
  120. package/src/styles/editor.css +309 -0
  121. package/src/styles/index.css +6 -0
  122. package/src/types.ts +278 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tulih-editor.umd.js","sources":["../src/core/PluginManager.ts","../src/core/helpers.ts","../src/core/Editor.ts","../src/plugins/block.ts","../src/plugins/inline.ts","../src/plugins/pre.ts","../src/plugins/inlineCode.ts","../src/plugins/subSuper.ts","../src/plugins/keyboardShortcuts.ts","../src/plugins/readOnly.ts","../src/plugins/linkTooltip.ts","../src/plugins/emojiAutocomplete.ts","../src/plugins/statusBar.ts","../src/plugins/codeBlock.ts","../src/plugins/mediaEmbed.ts","../src/plugins/dragDrop.ts","../src/plugins/pastePlain.ts","../src/plugins/findReplace.ts","../src/plugins/indent.ts","../src/plugins/list.ts","../src/plugins/lineHeight.ts","../src/plugins/fontSize.ts","../src/plugins/fontFamily.ts","../src/plugins/specialChars.ts","../src/plugins/colors.ts","../src/plugins/tableBg.ts","../src/plugins/align.ts","../src/plugins/markdown.ts","../src/plugins/link.ts","../src/plugins/image.ts","../src/plugins/imageProps.ts","../src/plugins/imageTools.ts","../src/plugins/iframe.ts","../src/plugins/table.ts","../src/plugins/tableTools.ts","../src/plugins/hr.ts","../src/plugins/unlink.ts","../src/plugins/emoji.ts","../src/plugins/direction.ts","../src/plugins/source.ts","../src/plugins/history.ts","../src/plugins/fullscreen.ts","../src/plugins/toolbarCollapse.ts","../src/plugins/autosave.ts","../src/plugins/autoLinkify.ts","../src/plugins/caseTransform.ts","../src/plugins/shortcutsHelp.ts","../src/plugins/floatingToolbar.ts","../src/plugins/darkMode.ts","../src/plugins/shortcutCustomizer.ts","../src/plugins/index.ts","../src/index.ts"],"sourcesContent":["import type { Plugin, PluginContext, Features, PluginManagerInstance } from '../types';\n\n/**\n * Registry and lifecycle manager for plugins. Resolves toolbar order,\n * dependency order, and one-time CSS injection.\n */\nexport default class PluginManager implements PluginManagerInstance {\n private _plugins: Plugin[] = [];\n private _map: Record<string, Plugin> = {};\n private _injectedCSS = new Set<string>();\n private _cssInjected = false;\n\n register(name: string, plugin: Plugin): this {\n if (this._map[name]) {\n throw new Error('Plugin \"' + name + '\" is already registered');\n }\n plugin.name = name;\n plugin.deps = plugin.deps || [];\n plugin.order = plugin.order || 100;\n this._plugins.push(plugin);\n this._map[name] = plugin;\n return this;\n }\n\n unregister(name: string): void {\n const plugin = this._map[name];\n if (!plugin) return;\n if (plugin.destroy) plugin.destroy(undefined as unknown as PluginContext);\n const idx = this._plugins.indexOf(plugin);\n if (idx !== -1) this._plugins.splice(idx, 1);\n delete this._map[name];\n }\n\n get(name: string): Plugin | null {\n return this._map[name] || null;\n }\n\n has(name: string): boolean {\n return !!this._map[name];\n }\n\n getNames(): string[] {\n return Object.keys(this._map);\n }\n\n private _resolveOrder(): Plugin[] {\n const sorted: Plugin[] = [];\n const visited: Record<string, boolean> = {};\n const visiting: Record<string, boolean> = {};\n const map = this._map;\n\n function visit(name: string): void {\n if (visited[name]) return;\n if (visiting[name]) throw new Error('Circular dependency: ' + name);\n visiting[name] = true;\n const p = map[name];\n if (p && p.deps) {\n p.deps.forEach((dep) => {\n if (!map[dep]) throw new Error('Plugin \"' + name + '\" depends on \"' + dep + '\" but not registered');\n visit(dep);\n });\n }\n visiting[name] = false;\n visited[name] = true;\n sorted.push(map[name]);\n }\n\n const ordered = this._plugins.slice().sort((a, b) => (a.order || 0) - (b.order || 0));\n ordered.forEach((p) => visit(p.name));\n\n return sorted;\n }\n\n initAll(ctx: PluginContext): void {\n this._resolveOrder().forEach((plugin) => {\n if (plugin.init) plugin.init(ctx);\n });\n }\n\n destroyAll(ctx: PluginContext): void {\n const reversed = this._plugins.slice().reverse();\n reversed.forEach((plugin) => {\n if (plugin.destroy) plugin.destroy(ctx);\n });\n }\n\n getToolbarHTML(features: Features, toolbar?: string[][]): string {\n if (toolbar && Array.isArray(toolbar)) {\n const parts: string[] = [];\n toolbar.forEach((group, i) => {\n if (i > 0) parts.push('<div class=\"te-divider\"></div>');\n group.forEach((name) => {\n const p = this._map[name];\n if (!p || features[name] === false) return;\n const html = typeof p.toolbarHTML === 'function' ? p.toolbarHTML(features) : p.toolbarHTML;\n if (html) parts.push(html);\n });\n });\n return parts.join('\\n');\n }\n\n const plugins = this._resolveOrder().filter((p) => features[p.name] !== false && p.toolbarHTML);\n const parts: string[] = [];\n let lastGroup = -1;\n plugins.forEach((p) => {\n const html = typeof p.toolbarHTML === 'function' ? p.toolbarHTML(features) : p.toolbarHTML;\n if (!html) return;\n const group = Math.floor((p.order || 0) / 10);\n if (lastGroup !== -1 && group !== lastGroup) {\n parts.push('<div class=\"te-divider\"></div>');\n }\n parts.push(html);\n lastGroup = group;\n });\n return parts.join('\\n');\n }\n\n getModalHTML(features: Features): string {\n const plugins = this._resolveOrder().filter((p) => features[p.name] !== false && p.modalHTML);\n return plugins\n .map((p) => (typeof p.modalHTML === 'function' ? p.modalHTML(features) : p.modalHTML))\n .filter(Boolean)\n .join('\\n');\n }\n\n injectAllCSS(): void {\n if (this._cssInjected) return;\n this._cssInjected = true;\n this._resolveOrder().forEach((p) => {\n if (!p.css || this._injectedCSS.has(p.name)) return;\n this._injectedCSS.add(p.name);\n const cssText = typeof p.css === 'function' ? p.css({}) : p.css;\n if (!cssText) return;\n const style = document.createElement('style');\n style.setAttribute('data-te-css', p.name);\n style.textContent = cssText;\n document.head.appendChild(style);\n });\n }\n}\n","/**\n * Shared DOM utilities used by the editor core and plugins.\n */\n\nconst blockSelector = 'p,h1,h2,h3,blockquote,pre,ul,ol,li,table,hr,iframe,.te-embed';\nconst inlineTags = ['A', 'B', 'I', 'U', 'S', 'STRONG', 'EM', 'SPAN', 'SMALL', 'MARK', 'CODE', 'KBD', 'SUB', 'SUP'];\n\nfunction qs(selector: string, root?: Document | Element | null): Element | null {\n return (root || document).querySelector(selector);\n}\n\nfunction qsa(selector: string, root?: Document | Element | null): Element[] {\n return Array.prototype.slice.call((root || document).querySelectorAll(selector));\n}\n\nfunction exec(command: string, value?: string): void {\n document.execCommand(command, false, value);\n}\n\nfunction getSelectionHtml(): string {\n const selection = window.getSelection();\n if (!selection || selection.rangeCount === 0) return '';\n const range = selection.getRangeAt(0).cloneRange();\n const div = document.createElement('div');\n div.appendChild(range.cloneContents());\n return div.innerHTML;\n}\n\nfunction hasBlockDescendant(el: Element): boolean {\n return !!el.querySelector(blockSelector);\n}\n\nfunction isInlineElement(el: Node): boolean {\n if (el.nodeType !== 1) return false;\n const tag = (el as Element).tagName;\n if (tag === 'IMG' || tag === 'BR' || tag === 'IFRAME') return true;\n return inlineTags.indexOf(tag) !== -1;\n}\n\nfunction wrapNodeInP(node: Node): HTMLParagraphElement {\n const p = document.createElement('p');\n node.parentNode!.insertBefore(p, node);\n p.appendChild(node);\n return p;\n}\n\nfunction wrapIframe(node: Element | null): HTMLDivElement | undefined {\n if (!node || node.tagName !== 'IFRAME') return;\n const wrapper = document.createElement('div');\n wrapper.className = 'te-embed';\n wrapper.setAttribute('contenteditable', 'false');\n node.setAttribute('contenteditable', 'false');\n node.setAttribute('draggable', 'false');\n node.setAttribute('tabindex', '-1');\n node.parentNode!.insertBefore(wrapper, node);\n wrapper.appendChild(node);\n return wrapper;\n}\n\nfunction normalizeParagraphs(root: Element | null): void {\n if (!root) return;\n let child = root.firstChild;\n while (child) {\n const next = child.nextSibling;\n if (child.nodeType === 3) {\n if ((child.textContent || '').trim() === '') {\n root.removeChild(child);\n } else {\n wrapNodeInP(child);\n }\n } else if (child.nodeType === 1) {\n const el = child as Element;\n const tag = el.tagName;\n if (tag === 'DIV') {\n if (el.classList.contains('te-embed') || el.querySelector('iframe,video,audio,.te-embed')) {\n // keep embed wrappers intact\n } else if (!hasBlockDescendant(el)) {\n const p = document.createElement('p');\n while (el.firstChild) {\n p.appendChild(el.firstChild);\n }\n root.replaceChild(p, el);\n }\n } else if (tag === 'IFRAME') {\n wrapIframe(el);\n } else if (isInlineElement(el)) {\n wrapNodeInP(el);\n }\n }\n child = next;\n }\n}\n\nfunction ensureInitialParagraph(root: Element | null): void {\n if (!root) return;\n if (root.querySelector(blockSelector)) return;\n if (!root.firstChild) {\n const p0 = document.createElement('p');\n p0.innerHTML = '<br>';\n root.appendChild(p0);\n return;\n }\n const p = document.createElement('p');\n while (root.firstChild) {\n p.appendChild(root.firstChild);\n }\n root.appendChild(p);\n}\n\nfunction isInsideEditor(editor: Element, node: Node | null): boolean {\n if (!node) return false;\n if (node === editor) return true;\n return editor.contains(node);\n}\n\nfunction getBlockElement(editor: Element): Element | null {\n const sel = window.getSelection();\n if (!sel || sel.rangeCount === 0) return null;\n let node: Node | null = sel.anchorNode;\n if (node && node.nodeType === 3) node = node.parentNode;\n if (!isInsideEditor(editor, node)) return null;\n if (node && (node as Element).closest) {\n return (node as Element).closest('p,h1,h2,h3,blockquote,pre,li,div');\n }\n return null;\n}\n\nfunction setBtnActive(toolbar: Element | null, selector: string, active: boolean): void {\n if (!toolbar) return;\n const btn = toolbar.querySelector(selector);\n if (!btn) return;\n if (active) btn.classList.add('active');\n else btn.classList.remove('active');\n}\n\nfunction updateToolbarState(\n editor: HTMLElement,\n blockSelect: HTMLSelectElement | null,\n alignSelect: HTMLSelectElement | null,\n toolbar: HTMLElement | null,\n): void {\n const blockEl = getBlockElement(editor);\n if (blockSelect) {\n let tag = '';\n if (blockEl) {\n let t = blockEl.tagName.toLowerCase();\n if (t === 'div' || t === 'li') t = 'p';\n if (['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'blockquote', 'pre'].indexOf(t) !== -1) {\n tag = t;\n }\n }\n blockSelect.value = tag || 'p';\n }\n if (alignSelect) {\n let align = '';\n if (blockEl) {\n try {\n const cs = window.getComputedStyle(blockEl);\n let ta = cs && cs.textAlign ? cs.textAlign.toLowerCase() : '';\n if (ta === 'start') ta = 'left';\n if (ta === 'left' || ta === 'center' || ta === 'right' || ta === 'justify') {\n align = ta;\n }\n } catch (_) { /* ignore */ }\n }\n alignSelect.value = align || '';\n }\n try {\n setBtnActive(toolbar, '[data-cmd=\"bold\"]', document.queryCommandState('bold'));\n setBtnActive(toolbar, '[data-cmd=\"italic\"]', document.queryCommandState('italic'));\n setBtnActive(toolbar, '[data-cmd=\"underline\"]', document.queryCommandState('underline'));\n setBtnActive(toolbar, '[data-cmd=\"strikeThrough\"]', document.queryCommandState('strikeThrough'));\n } catch (_) { /* ignore */ }\n let inOL = false;\n let inUL = false;\n if (blockEl && blockEl.closest) {\n inOL = !!blockEl.closest('ol');\n inUL = !!blockEl.closest('ul');\n }\n setBtnActive(toolbar, '[data-cmd=\"insertOrderedList\"]', inOL);\n setBtnActive(toolbar, '[data-cmd=\"insertUnorderedList\"]', inUL);\n const isQuote = blockEl && blockEl.tagName === 'BLOCKQUOTE';\n const isPre = blockEl && blockEl.tagName === 'PRE';\n setBtnActive(toolbar, '[data-cmd=\"formatBlock\"][data-val=\"blockquote\"]', !!isQuote);\n setBtnActive(toolbar, '[data-cmd=\"formatBlock\"][data-val=\"pre\"]', !!isPre);\n}\n\nfunction escapeHtml(str: string): string {\n return String(str)\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#039;');\n}\n\nfunction removeNode(node: Node | null): void {\n if (node && node.parentNode) {\n node.parentNode.removeChild(node);\n }\n}\n\nexport {\n qs, qsa, exec, getSelectionHtml,\n blockSelector, inlineTags, hasBlockDescendant, isInlineElement,\n wrapNodeInP, wrapIframe, normalizeParagraphs, ensureInitialParagraph,\n isInsideEditor, getBlockElement, setBtnActive, updateToolbarState,\n escapeHtml, removeNode,\n};\n","import * as H from './helpers';\nimport type {\n EditorOptions,\n ResolvedOptions,\n Features,\n EditorUtils,\n PluginContext,\n SanitizeOptions,\n TulihEditorStatic,\n EditorInstance,\n TeEditorElement,\n TeWrapperElement,\n} from '../types';\n\nfunction buildEditorHTML(toolbarHTML: string, modalHTML: string): string {\n return '' +\n '<div class=\"te-container\">' +\n ' <div class=\"te-toolbar mb-0\">' +\n toolbarHTML +\n ' </div>' +\n ' <div class=\"te-editor\" contenteditable=\"true\" placeholder=\"Start typing...\"></div>' +\n modalHTML +\n '</div>';\n}\n\nconst DEFAULT_FEATURES: Features = {\n block: false, inline: false, inlineCode: false, subSuper: false, removeFormat: false,\n codeBlock: false, mediaEmbed: false, dragDrop: false,\n readOnly: false, linkTooltip: false, emojiAutocomplete: false, statusBar: false,\n pastePlain: false, findReplace: false, indent: false, list: false, autoLinkify: false, caseTransform: false, shortcutsHelp: false,\n lineHeight: false, fontSize: false, fontFamily: false, specialChars: false,\n colors: false, tableBg: false, align: false, markdown: false,\n link: false, image: false, imageProps: false, imageTools: false,\n iframe: false, table: false, tableTools: false, hr: false,\n unlink: false, emoji: false, direction: false,\n source: false, history: false, fullscreen: false,\n toolbarCollapse: false, autosave: false, floatingToolbar: false,\n darkMode: false, shortcutCustomizer: false, minimal: false,\n};\n\nconst DEFAULT_SANITIZE: SanitizeOptions = {\n allowedTags: ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'blockquote', 'pre', 'code', 'strong', 'em', 'u', 's', 'span', 'a', 'img', 'iframe', 'ul', 'ol', 'li', 'table', 'thead', 'tbody', 'tfoot', 'tr', 'th', 'td', 'br', 'hr'],\n allowedAttributes: ['href', 'src', 'alt', 'title', 'width', 'height', 'class', 'id', 'style', 'target', 'rel', 'allow', 'allowfullscreen', 'frameborder'],\n};\nconst DEFAULT_URL_SCHEMES = ['http', 'https', 'mailto', 'tel'];\nconst DEFAULT_IMAGE_SCHEMES = ['http', 'https', 'data'];\nconst DEFAULT_IFRAME_ALLOWLIST = ['youtube.com', 'www.youtube.com', 'youtu.be', 'player.vimeo.com', 'vimeo.com'];\nconst DEFAULT_IFRAME_SANDBOX = 'allow-scripts allow-same-origin allow-presentation';\nconst DEFAULT_IFRAME_ALLOW = 'accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share';\n\nexport default class Editor implements EditorInstance {\n features!: Features;\n options!: ResolvedOptions;\n utils!: EditorUtils;\n container: HTMLElement | null = null;\n editor: HTMLElement | null = null;\n toolbar: HTMLElement | null = null;\n textarea!: HTMLTextAreaElement;\n private _ctx: PluginContext | null = null;\n\n constructor(target: string | Element, options: EditorOptions | undefined, TulihEditor: TulihEditorStatic) {\n const el = (typeof target === 'string' ? document.querySelector(target) : target) as HTMLElement | null;\n if (!el) return;\n const isTextarea = String(el.tagName).toUpperCase() === 'TEXTAREA';\n const hasAttr = el.matches && el.matches('textarea[data-tulih-editor]');\n if (!isTextarea && !hasAttr) return;\n const sibling = el.nextElementSibling;\n if (sibling && sibling.querySelector && sibling.querySelector('.te-editor')) return;\n\n const opts: EditorOptions = options || {};\n const textarea = el as HTMLTextAreaElement;\n\n const isMinimal = opts.minimal || (opts.features && opts.features.minimal);\n if (isMinimal) {\n this.features = Object.assign({}, DEFAULT_FEATURES, { floatingToolbar: true, link: true, linkTooltip: true }, opts.features || {});\n } else {\n const allOn: Features = {};\n Object.keys(DEFAULT_FEATURES).forEach((k) => {\n if (k !== 'minimal') allOn[k] = true;\n });\n this.features = Object.assign({}, allOn, opts.features || {});\n }\n this.options = {\n sanitize: Object.assign({}, DEFAULT_SANITIZE, opts.sanitize || {}),\n urlSchemes: Array.isArray(opts.allowedUrlSchemes) ? opts.allowedUrlSchemes : DEFAULT_URL_SCHEMES,\n imageSchemes: Array.isArray(opts.allowedImageSchemes) ? opts.allowedImageSchemes : DEFAULT_IMAGE_SCHEMES,\n iframeAllowlist: Array.isArray(opts.iframeAllowlist) ? opts.iframeAllowlist : DEFAULT_IFRAME_ALLOWLIST,\n iframeSandbox: typeof opts.iframeSandbox === 'string' ? opts.iframeSandbox : DEFAULT_IFRAME_SANDBOX,\n iframeAllow: typeof opts.iframeAllow === 'string' ? opts.iframeAllow : DEFAULT_IFRAME_ALLOW,\n readOnly: !!opts.readOnly,\n };\n\n const self = this;\n\n function sanitizeHTML(html: string, sanOpts?: Partial<SanitizeOptions>): string {\n const allowedTags = new Set((sanOpts && sanOpts.allowedTags) || []);\n const allowedAttrs = new Set((sanOpts && sanOpts.allowedAttributes) || []);\n const container = document.createElement('div');\n container.innerHTML = String(html || '');\n const walker = document.createTreeWalker(container, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT, null);\n const toUnwrap: Element[] = [];\n const comments: Node[] = [];\n while (walker.nextNode()) {\n const node = walker.currentNode as Element;\n if (node.nodeType === 8) { comments.push(node); continue; }\n const tag = node.tagName ? node.tagName.toLowerCase() : '';\n if (tag && !allowedTags.has(tag)) {\n toUnwrap.push(node);\n continue;\n }\n if (node.attributes) {\n const attrs = Array.prototype.slice.call(node.attributes) as Attr[];\n attrs.forEach((attr) => {\n const aname = attr.name.toLowerCase();\n if (aname.startsWith('on')) { node.removeAttribute(attr.name); return; }\n if (!allowedAttrs.has(aname)) { node.removeAttribute(attr.name); return; }\n if (aname === 'href' && attr.value) { if (!isSafeUrl(attr.value, self.options.urlSchemes)) { node.removeAttribute(attr.name); } }\n if (aname === 'src' && attr.value && tag === 'img') { if (!isSafeUrl(attr.value, self.options.imageSchemes)) { node.removeAttribute(attr.name); } }\n });\n }\n if (tag === 'iframe') {\n const src = node.getAttribute('src') || '';\n if (!isAllowedIframeUrl(src)) {\n toUnwrap.push(node);\n } else {\n if (self.options.iframeSandbox) node.setAttribute('sandbox', self.options.iframeSandbox);\n if (self.options.iframeAllow) node.setAttribute('allow', self.options.iframeAllow);\n node.setAttribute('frameborder', '0');\n (node as HTMLElement).style.maxWidth = '100%';\n (node as HTMLElement).style.border = '0';\n }\n }\n }\n comments.forEach((c) => { if (c.parentNode) c.parentNode.removeChild(c); });\n toUnwrap.forEach((node) => {\n if (!node.parentNode) return;\n while (node.firstChild) { node.parentNode.insertBefore(node.firstChild, node); }\n node.parentNode.removeChild(node);\n });\n return container.innerHTML;\n }\n\n function isSafeUrl(url: string, schemes: string[]): boolean {\n try {\n const u = new URL(url, window.location.origin);\n return schemes.indexOf(u.protocol.replace(':', '')) !== -1;\n } catch (_) { return false; }\n }\n\n function isAllowedIframeUrl(url: string): boolean {\n try {\n const u = new URL(url, window.location.origin);\n const host = u.hostname.toLowerCase();\n return self.options.iframeAllowlist.some((allowed) => host === allowed || host.endsWith('.' + allowed));\n } catch (_) { return false; }\n }\n\n this.utils = { sanitizeHTML, isSafeUrl, isAllowedIframeUrl };\n\n const toolbarHTML = TulihEditor.pluginManager.getToolbarHTML(self.features, opts.toolbar);\n const modalHTML = TulihEditor.pluginManager.getModalHTML(self.features);\n const wrapper = document.createElement('div') as TeWrapperElement;\n wrapper.innerHTML = buildEditorHTML(toolbarHTML, modalHTML);\n el.style.display = 'none';\n el.parentNode!.insertBefore(wrapper, el.nextSibling);\n\n const editorEl = wrapper.querySelector('.te-editor') as TeEditorElement;\n const toolbarEl = wrapper.querySelector('.te-toolbar') as HTMLElement;\n\n try { const raw = textarea.value || ''; const safeInit = sanitizeHTML(raw, self.options.sanitize); editorEl.innerHTML = safeInit; } catch (_) { /* ignore */ }\n try { H.normalizeParagraphs(editorEl); H.ensureInitialParagraph(editorEl); } catch (_) { /* ignore */ }\n try { H.ensureInitialParagraph(editorEl); } catch (_) { /* ignore */ }\n\n if (opts.height) {\n editorEl.style.height = typeof opts.height === 'number' ? opts.height + 'px' : String(opts.height);\n editorEl.style.overflow = 'auto';\n }\n\n this.container = wrapper;\n this.editor = editorEl;\n this.toolbar = toolbarEl;\n this.textarea = textarea;\n\n try { document.execCommand('defaultParagraphSeparator', false, 'p'); } catch (_) { /* ignore */ }\n\n function updateActiveStates(): void {\n try {\n ['bold', 'italic', 'underline', 'strikeThrough'].forEach((cmd) => {\n const btn = toolbarEl.querySelector('[data-cmd=\"' + cmd + '\"]');\n if (!btn) return;\n if (document.queryCommandState(cmd)) btn.classList.add('active');\n else btn.classList.remove('active');\n });\n const undoBtn = toolbarEl.querySelector('[data-cmd=\"undo\"]') as HTMLButtonElement | null;\n const redoBtn = toolbarEl.querySelector('[data-cmd=\"redo\"]') as HTMLButtonElement | null;\n const h = editorEl._tableHist;\n if (undoBtn) {\n const canUndo = document.queryCommandEnabled('undo') || (h && h.undo.length > 0);\n undoBtn.toggleAttribute('disabled', !canUndo);\n }\n if (redoBtn) {\n const canRedo = document.queryCommandEnabled('redo') || (h && h.redo.length > 0);\n redoBtn.toggleAttribute('disabled', !canRedo);\n }\n const sel = window.getSelection();\n let node: Node | null = sel && sel.anchorNode;\n if (node && node.nodeType === 3) node = node.parentNode;\n const elNode = node as Element | null;\n const inOL = elNode && elNode.closest && elNode.closest('ol');\n const inUL = elNode && elNode.closest && elNode.closest('ul');\n const olBtn = toolbarEl.querySelector('[data-cmd=\"insertOrderedList\"]');\n const ulBtn = toolbarEl.querySelector('[data-cmd=\"insertUnorderedList\"]');\n if (olBtn) olBtn.classList.toggle('active', !!inOL);\n if (ulBtn) ulBtn.classList.toggle('active', !!inUL);\n } catch (_) { /* ignore */ }\n }\n\n document.addEventListener('selectionchange', () => {\n if (wrapper.contains(document.activeElement)) { updateActiveStates(); }\n });\n\n toolbarEl.querySelectorAll('[data-cmd]').forEach((btn) => {\n btn.addEventListener('click', () => {\n const cmd = btn.getAttribute('data-cmd');\n const val = btn.getAttribute('data-val') || undefined;\n if (cmd === 'createLink' || cmd === 'insertImage' || cmd === 'insertIframe' || cmd === 'insertTable' || cmd === 'editSource' || cmd === 'indent' || cmd === 'outdent' || cmd === 'findReplace' || cmd === 'togglePastePlain' || cmd === 'specialChars' || cmd === 'fullscreen' || cmd === 'emoji' || cmd === 'codeBlock' || cmd === 'toggleReadOnly' || cmd === 'shortcutsHelp' || cmd === 'alignLeft' || cmd === 'alignCenter' || cmd === 'alignRight' || cmd === 'alignJustify' || cmd === 'toggleDark' || cmd === 'customizeShortcuts') {\n return;\n }\n function clearFrHighlights(): void {\n editorEl.querySelectorAll('.te-fr-match, .te-fr-active').forEach((m) => {\n const parent = m.parentNode;\n if (!parent) return;\n while (m.firstChild) parent.insertBefore(m.firstChild, m);\n parent.removeChild(m);\n });\n }\n if (cmd === 'undo') {\n const h = editorEl._tableHist;\n if (h && h.undo.length) {\n clearFrHighlights();\n h.redo.push(editorEl.innerHTML);\n editorEl.contentEditable = 'false';\n editorEl.innerHTML = h.undo.pop() as string;\n editorEl.contentEditable = 'true';\n clearFrHighlights();\n editorEl.focus();\n updateActiveStates();\n return;\n }\n }\n if (cmd === 'redo') {\n const h = editorEl._tableHist;\n if (h && h.redo.length) {\n clearFrHighlights();\n h.undo.push(editorEl.innerHTML);\n editorEl.contentEditable = 'false';\n editorEl.innerHTML = h.redo.pop() as string;\n editorEl.contentEditable = 'true';\n clearFrHighlights();\n editorEl.focus();\n updateActiveStates();\n return;\n }\n }\n document.execCommand(cmd as string, false, val);\n editorEl.focus();\n updateActiveStates();\n });\n });\n\n wrapper.querySelectorAll('[data-te-close]').forEach((x) => {\n x.addEventListener('click', () => {\n const modal = (x as Element).closest('.te-modal');\n if (modal) modal.classList.remove('is-open');\n });\n });\n\n try { H.ensureInitialParagraph(editorEl); } catch (_) { /* ignore */ }\n\n function saveSel(): void {\n const s = window.getSelection();\n if (s && s.rangeCount > 0) { wrapper.__savedRange = s.getRangeAt(0).cloneRange(); }\n }\n function restoreSel(): void {\n const r = wrapper.__savedRange;\n if (!r) return;\n const s = window.getSelection();\n if (!s) return;\n s.removeAllRanges();\n s.addRange(r);\n }\n\n function insertImageFile(file: File | Blob): void {\n const handler = TulihEditor.onUploadImage || function (f: File | Blob, cb: (url: string) => void): void {\n const r = new FileReader();\n r.onload = () => { cb(r.result as string); };\n r.readAsDataURL(f);\n };\n handler(file, (url) => {\n if (!url) return;\n const name = (file as File).name || '';\n const html = '<img src=\"' + url.replace(/\"/g, '&quot;') + '\" alt=\"' + name.replace(/\"/g, '&quot;') + '\" style=\"max-width:100%;\" />';\n document.execCommand('insertHTML', false, html);\n });\n }\n\n function cleanWordHtml(html: string): string {\n if (!html) return '';\n let out = String(html);\n if (out.indexOf('mso-') === -1 && out.indexOf('xmlns:o') === -1 && out.indexOf('google-docs') === -1) return out;\n out = out.replace(/<!--[\\s\\S]*?-->/g, '');\n out = out.replace(/<meta[^>]*>/gi, '');\n out = out.replace(/<link[^>]*>/gi, '');\n out = out.replace(/<o:[^>]*>[\\s\\S]*?<\\/o:[^>]*>/gi, '');\n out = out.replace(/<w:[^>]*>[\\s\\S]*?<\\/w:[^>]*>/gi, '');\n out = out.replace(/<style[^>]*>[\\s\\S]*?<\\/style>/gi, '');\n out = out.replace(/ class=\"[^\"]*Mso[^\"]*\"/gi, '');\n out = out.replace(/ class=\"[^\"]*\" style=\"\"/gi, '');\n out = out.replace(/ style=\"[^\"]*mso-[^;]*[^\"]*\"/gi, '');\n out = out.replace(/<span[^>]*style=\"[^\"]*mso-[^\"]*\"[^>]*>/gi, '<span>');\n out = out.replace(/<span[^>]*><\\/span>/gi, '');\n out = out.replace(/(<(p|h[1-6]|div|span|b|i|u|strong|em))[^>]*>/gi, '$1>');\n return out;\n }\n\n editorEl.addEventListener('paste', (e: ClipboardEvent) => {\n try {\n const files = e.clipboardData && e.clipboardData.files;\n if (files && files.length > 0) {\n let pasted = false;\n for (let fi = 0; fi < files.length; fi++) {\n if (/^image\\//i.test(files[fi].type)) {\n if (!pasted) { e.preventDefault(); pasted = true; }\n insertImageFile(files[fi]);\n }\n }\n if (pasted) return;\n }\n const items = e.clipboardData && e.clipboardData.items;\n if (items && items.length > 0) {\n for (let ii = 0; ii < items.length; ii++) {\n if (items[ii].kind === 'file' && /^image\\//i.test(items[ii].type)) {\n e.preventDefault();\n const imgFile = items[ii].getAsFile();\n if (imgFile) { insertImageFile(imgFile); }\n return;\n }\n }\n }\n if (window.navigator && window.navigator.clipboard && typeof window.navigator.clipboard.read === 'function') {\n window.navigator.clipboard.read().then((clipItems) => {\n for (let ci = 0; ci < clipItems.length; ci++) {\n const ciTypes = clipItems[ci].types || [];\n for (let ct = 0; ct < ciTypes.length; ct++) {\n if (/^image\\//i.test(ciTypes[ct])) {\n clipItems[ci].getType(ciTypes[ct]).then((blob) => {\n insertImageFile(blob);\n });\n break;\n }\n }\n }\n }).catch(() => { /* ignore */ });\n }\n e.preventDefault();\n const rawHtml = (e.clipboardData && e.clipboardData.getData('text/html')) || '';\n const text = (e.clipboardData && e.clipboardData.getData('text/plain')) || '';\n const toInsert = cleanWordHtml(rawHtml) || (text ? '<p>' + text.replace(/\\n/g, '<br>') + '</p>' : '');\n const safe = sanitizeHTML(toInsert, self.options.sanitize);\n document.execCommand('insertHTML', false, safe);\n setTimeout(() => { try { H.ensureInitialParagraph(editorEl); H.normalizeParagraphs(editorEl); } catch (_) { /* ignore */ } }, 0);\n } catch (_) { setTimeout(() => { H.normalizeParagraphs(editorEl); }, 0); }\n });\n\n editorEl.addEventListener('focus', () => { try { H.ensureInitialParagraph(editorEl); } catch (_) { /* ignore */ } });\n editorEl.addEventListener('input', () => {\n setTimeout(() => { try { H.ensureInitialParagraph(editorEl); H.normalizeParagraphs(editorEl); } catch (_) { /* ignore */ } }, 0);\n });\n\n const ctx: PluginContext = {\n wrapper,\n editor: editorEl,\n toolbar: toolbarEl,\n textarea,\n features: self.features,\n options: self.options,\n utils: self.utils,\n TulihEditor,\n saveSel,\n restoreSel,\n updateActiveStates,\n };\n\n if (isMinimal) {\n wrapper.classList.add('te-minimal');\n }\n\n self._ctx = ctx;\n\n TulihEditor.pluginManager.initAll(ctx);\n\n TulihEditor.instances.push(this);\n }\n\n getContent(): string {\n return this.editor ? this.editor.innerHTML : '';\n }\n\n setContent(html: string): void {\n if (!this.editor) return;\n const safe = this.utils.sanitizeHTML(html, this.options.sanitize);\n this.editor.innerHTML = safe;\n try { H.ensureInitialParagraph(this.editor); H.normalizeParagraphs(this.editor); } catch (_) { /* ignore */ }\n }\n\n getText(): string {\n return this.editor ? this.editor.textContent || '' : '';\n }\n\n getWordCount(): number {\n const text = this.getText().trim();\n if (!text) return 0;\n return text.split(/\\s+/).length;\n }\n\n getCharCount(): number {\n return this.getText().length;\n }\n\n setReadOnly(ro: boolean): void {\n if (!this._ctx) return;\n const ctx = this._ctx;\n const isRo = ctx.editor.contentEditable === 'false';\n if (ro === isRo) return;\n const btn = ctx.wrapper.querySelector('[data-cmd=\"toggleReadOnly\"]') as HTMLElement | null;\n if (btn) btn.click();\n }\n\n isReadOnly(): boolean {\n return !!(this._ctx && this._ctx.editor && this._ctx.editor.contentEditable === 'false');\n }\n\n destroy(): void {\n if (!this.container || !this.container.parentNode) return;\n const instances = this._ctx ? this._ctx.TulihEditor.instances : [];\n const myIdx = instances.indexOf(this);\n if (myIdx !== -1) instances.splice(myIdx, 1);\n if (this._ctx) this._ctx.TulihEditor.pluginManager.destroyAll(this._ctx);\n const textarea = this.textarea;\n if (textarea && this.editor) {\n textarea.value = this.editor.innerHTML;\n textarea.style.display = '';\n }\n this.container.parentNode.removeChild(this.container);\n this.editor = null;\n this.container = null;\n this.toolbar = null;\n this._ctx = null;\n }\n}\n","import type { Plugin, PluginContext } from '../types';\n\nconst block: Plugin = {\n name: 'block',\n order: 10,\n toolbarHTML: '' +\n '<select class=\"te-block form-select form-select-sm\">' +\n ' <option value=\"p\">Paragraph</option>' +\n ' <option value=\"h1\">Heading 1</option>' +\n ' <option value=\"h2\">Heading 2</option>' +\n ' <option value=\"h3\">Heading 3</option>' +\n ' <option value=\"h4\">Heading 4</option>' +\n ' <option value=\"h5\">Heading 5</option>' +\n ' <option value=\"h6\">Heading 6</option>' +\n ' <option value=\"blockquote\">Quote</option>' +\n ' <option value=\"pre\">Code</option>' +\n '</select>',\n init(ctx: PluginContext): void {\n if (!ctx.features.block) return;\n const sel = ctx.wrapper.querySelector('.te-block') as HTMLSelectElement | null;\n if (!sel) return;\n sel.addEventListener('change', () => {\n const v = sel.value;\n if (!v) return;\n document.execCommand('formatBlock', false, v);\n ctx.editor.focus();\n ctx.updateActiveStates();\n });\n },\n};\n\nexport default block;\n","import type { Plugin, PluginContext } from '../types';\n\nconst inline: Plugin = {\n name: 'inline',\n order: 20,\n toolbarHTML: '' +\n '<button type=\"button\" class=\"btn btn-sm btn-light\" title=\"Bold\" data-cmd=\"bold\"><i class=\"ti ti-bold\"></i></button>' +\n '<button type=\"button\" class=\"btn btn-sm btn-light\" title=\"Italic\" data-cmd=\"italic\"><i class=\"ti ti-italic\"></i></button>' +\n '<button type=\"button\" class=\"btn btn-sm btn-light\" title=\"Underline\" data-cmd=\"underline\"><i class=\"ti ti-underline\"></i></button>' +\n '<button type=\"button\" class=\"btn btn-sm btn-light\" title=\"Strikethrough\" data-cmd=\"strikeThrough\"><s>S</s></button>' +\n '<div class=\"te-divider\"></div>' +\n '<button type=\"button\" class=\"btn btn-sm btn-light\" title=\"Quote\" data-cmd=\"formatBlock\" data-val=\"blockquote\"><strong>\"</strong></button>',\n init(ctx: PluginContext): void {\n }\n};\n\nexport default inline;\n","import type { Plugin, PluginContext } from '../types';\n\nconst pre: Plugin = {\n name: 'pre',\n order: 21,\n toolbarHTML: '<button type=\"button\" class=\"btn btn-sm btn-light\" title=\"Preformatted\" data-cmd=\"formatBlock\" data-val=\"pre\"><i class=\"ti ti-code\"></i></button>',\n init(ctx: PluginContext): void {\n }\n};\n\nexport default pre;\n","import type { Plugin, PluginContext } from '../types';\nimport * as H from '../core/helpers';\n\nconst inlineCode: Plugin = {\n name: 'inlineCode',\n order: 22,\n toolbarHTML: '<button type=\"button\" class=\"btn btn-sm btn-light\" title=\"Inline code\" data-cmd=\"inlineCode\"><i class=\"ti ti-code-circle\"></i></button>',\n init(ctx: PluginContext): void {\n if (!ctx.features.inlineCode) return;\n var btn = ctx.wrapper.querySelector('[data-cmd=\"inlineCode\"]') as HTMLElement | null;\n if (!btn) return;\n btn.addEventListener('click', function () {\n var txt = H.escapeHtml(window.getSelection()!.toString() || 'code');\n var html = '<code>' + txt + '</code>';\n document.execCommand('insertHTML', false, html);\n ctx.editor.focus();\n });\n }\n};\n\nexport default inlineCode;\n","import type { Plugin, PluginContext } from '../types';\n\nconst subSuper: Plugin = {\n name: 'subSuper',\n order: 26,\n toolbarHTML: '' +\n '<button type=\"button\" class=\"btn btn-sm btn-light\" title=\"Subscript\" data-cmd=\"subscript\">x₂</button>' +\n '<button type=\"button\" class=\"btn btn-sm btn-light\" title=\"Superscript\" data-cmd=\"superscript\">x²</button>',\n init(ctx: PluginContext): void {\n if (!ctx.features.subSuper) return;\n ctx.wrapper.querySelectorAll('[data-cmd=\"subscript\"],[data-cmd=\"superscript\"]').forEach(function (btn) {\n btn.addEventListener('click', function () {\n document.execCommand(btn.getAttribute('data-cmd')!, false, undefined);\n ctx.editor.focus();\n });\n });\n }\n};\n\nexport default subSuper;\n","import type { Plugin, PluginContext, TeEditorElement } from '../types';\n\nvar STORAGE_KEY = 'te-shortcut-map';\nvar DEFAULT_MAP = {\n 'Bold': {key:'b', ctrl:true, shift:false},\n 'Italic': {key:'i', ctrl:true, shift:false},\n 'Underline': {key:'u', ctrl:true, shift:false},\n 'Strike': {key:'s', ctrl:true, shift:false},\n 'Undo': {key:'z', ctrl:true, shift:false},\n 'Redo': {key:'z', ctrl:true, shift:true},\n 'RedoAlt': {key:'y', ctrl:true, shift:false},\n 'Link': {key:'k', ctrl:true, shift:false}\n};\n\nfunction loadMap(){\n try {\n var raw = localStorage.getItem(STORAGE_KEY);\n if(raw) return JSON.parse(raw);\n } catch(_){}\n return JSON.parse(JSON.stringify(DEFAULT_MAP));\n}\n\nconst keyboardShortcuts: Plugin = {\n name: 'keyboardShortcuts',\n order: 5,\n init(ctx: PluginContext): void {\n if(ctx.features.keyboardShortcuts === false) return;\n var editor = ctx.editor as TeEditorElement;\n var map = loadMap();\n\n editor.addEventListener('keydown', function(e: KeyboardEvent){\n if(!e.ctrlKey && !e.metaKey) return;\n for(var name in map){\n var s = map[name];\n if(e.key.toLowerCase() === s.key && e.ctrlKey === s.ctrl && e.shiftKey === s.shift){\n e.preventDefault();\n if(name === 'Bold'){ document.execCommand('bold'); }\n else if(name === 'Italic'){ document.execCommand('italic'); }\n else if(name === 'Underline'){ document.execCommand('underline'); }\n else if(name === 'Strike'){ document.execCommand('strikeThrough'); }\n else if(name === 'Undo'){\n var h = editor._tableHist;\n if(h && h.undo.length){\n editor.querySelectorAll('.te-fr-match, .te-fr-active').forEach(function(el){\n var p = el.parentNode; if(!p) return;\n while(el.firstChild) p.insertBefore(el.firstChild, el);\n p.removeChild(el);\n });\n h.redo.push(editor.innerHTML);\n editor.contentEditable = 'false';\n editor.innerHTML = h.undo.pop()!;\n editor.contentEditable = 'true';\n editor.querySelectorAll('.te-fr-match, .te-fr-active').forEach(function(el){\n var p = el.parentNode; if(!p) return;\n while(el.firstChild) p.insertBefore(el.firstChild, el);\n p.removeChild(el);\n });\n editor.focus();\n } else { document.execCommand('undo'); editor.focus(); }\n }\n else if(name === 'Redo' || name === 'RedoAlt'){\n var h = editor._tableHist;\n if(h && h.redo.length){\n editor.querySelectorAll('.te-fr-match, .te-fr-active').forEach(function(el){\n var p = el.parentNode; if(!p) return;\n while(el.firstChild) p.insertBefore(el.firstChild, el);\n p.removeChild(el);\n });\n h.undo.push(editor.innerHTML);\n editor.contentEditable = 'false';\n editor.innerHTML = h.redo.pop()!;\n editor.contentEditable = 'true';\n editor.querySelectorAll('.te-fr-match, .te-fr-active').forEach(function(el){\n var p = el.parentNode; if(!p) return;\n while(el.firstChild) p.insertBefore(el.firstChild, el);\n p.removeChild(el);\n });\n editor.focus();\n } else { document.execCommand('redo'); editor.focus(); }\n }\n else if(name === 'Link'){\n var linkBtn = ctx.wrapper.querySelector('[data-cmd=\"createLink\"]') as HTMLButtonElement | null;\n if(linkBtn) linkBtn.click();\n }\n return;\n }\n }\n });\n }\n};\n\nexport default keyboardShortcuts;\n","import type { Plugin, PluginContext } from '../types';\n\nfunction applyReadOnly(ctx: PluginContext, ro: boolean): void {\n var btn = ctx.wrapper.querySelector('[data-cmd=\"toggleReadOnly\"]');\n if(ro){\n ctx.editor.contentEditable = 'false';\n ctx.wrapper.classList.add('te-readonly');\n if(btn) btn.innerHTML = '<i class=\"ti ti-lock-open\"></i>';\n } else {\n ctx.editor.contentEditable = 'true';\n ctx.wrapper.classList.remove('te-readonly');\n if(btn) btn.innerHTML = '<i class=\"ti ti-lock\"></i>';\n }\n if(btn) btn.classList.toggle('active', ro);\n}\n\nconst readOnly: Plugin = {\n name: 'readOnly',\n order: 75,\n css: '' +\n '.te-readonly-btn.active { background: #fff3cd; border-color: #ffecb5; }' +\n '.te-readonly .te-toolbar select,' +\n '.te-readonly .te-toolbar input,' +\n '.te-readonly .te-toolbar .btn {' +\n ' opacity: .5; pointer-events: none;' +\n '}' +\n '.te-readonly .te-editor { background: #f8f9fa; cursor: default; }',\n toolbarHTML: '',\n init(ctx: PluginContext): void {\n if(ctx.features.readOnly === false) return;\n\n if(ctx.options.readOnly) {\n applyReadOnly(ctx, true);\n }\n\n var btn = ctx.wrapper.querySelector('[data-cmd=\"toggleReadOnly\"]');\n if(!btn) return;\n\n btn.addEventListener('click', function(){\n var isRo = ctx.editor.contentEditable !== 'false';\n applyReadOnly(ctx, !isRo);\n });\n }\n};\n\nexport default readOnly;\n","import type { Plugin, PluginContext } from '../types';\n\nconst linkTooltip: Plugin = {\n name: 'linkTooltip',\n order: 4,\n css: '' +\n '.te-link-tooltip {' +\n ' position: fixed; z-index: 9999;' +\n ' background: #333; color: #fff;' +\n ' padding: 4px 8px; border-radius: 4px;' +\n ' font-size: .75rem; line-height: 1.4;' +\n ' max-width: 300px; overflow: hidden;' +\n ' text-overflow: ellipsis; white-space: nowrap;' +\n ' pointer-events: none; opacity: 0;' +\n ' transition: opacity .15s;' +\n '}' +\n '.te-link-tooltip.show { opacity: 1; }',\n init(ctx: PluginContext): void {\n if(ctx.features.linkTooltip === false) return;\n var editor = ctx.editor;\n\n var tooltip = document.createElement('div');\n tooltip.className = 'te-link-tooltip';\n document.body.appendChild(tooltip);\n var hideTimer: ReturnType<typeof setTimeout> | null = null;\n\n editor.addEventListener('mouseover', function(e: MouseEvent){\n var a = (e.target as HTMLElement) && (e.target as HTMLElement).closest && (e.target as HTMLElement).closest('a') as HTMLAnchorElement | null;\n if(!a || !editor.contains(a)){ hide(); return; }\n clearTimeout(hideTimer!);\n var href = a.getAttribute('href') || '';\n tooltip.textContent = href;\n position(e);\n tooltip.classList.add('show');\n });\n\n editor.addEventListener('mousemove', function(e: MouseEvent){\n if(!tooltip.classList.contains('show')) return;\n position(e);\n });\n\n editor.addEventListener('mouseout', function(e: MouseEvent){\n var a = (e.target as HTMLElement) && (e.target as HTMLElement).closest && (e.target as HTMLElement).closest('a');\n if(!a) return;\n hideTimer = setTimeout(hide, 200);\n });\n\n function position(e: MouseEvent): void {\n var x = e.clientX + 12;\n var y = e.clientY + 12;\n if(x + 310 > window.innerWidth) x = window.innerWidth - 310;\n if(y + 30 > window.innerHeight) y = e.clientY - 30;\n tooltip.style.left = x + 'px';\n tooltip.style.top = y + 'px';\n }\n\n function hide(): void {\n tooltip.classList.remove('show');\n }\n }\n};\n\nexport default linkTooltip;\n","import type { Plugin, PluginContext } from '../types';\nimport * as H from '../core/helpers';\n\nvar EMOJIS = '😀😃😄😁😆😅🤣😂🙂🙃😉😊😇🥰😍🤩😘😗😚😋😛😜🤪😝🤑🤗🤭🤫🤔🤐🤨😐😑😶😏😒🙄😬🤥😌😔😪🤤😴😷🤒🤕🤢🤮🤧🥵🥶🥴😵🤯🤠🥳🥸😎🤓🧐😕😟🙁😮😯😲😳🥺😦😧😨😰😥😢😭😱😖😣😞😓😩😫🥱😤😡😠🤬😈👿💀☠💩🤡👹👺👻👽👾🤖'.match(/.{1,2}/g) || [];\n\nvar EMOJI_NAMES: Record<string, string> = {\n '😀':'grinning laugh happy','😃':'grinning smile','😄':'smile happy','😁':'beaming grin','😆':'laughing grinning',\n '🤣':'rolling floor laugh','😂':'tears joy cry',\n '🙂':'slight smile','🙃':'upside down','😉':'winking wink','😊':'blush smile','😇':'innocent angel',\n '🥰':'love heart','😍':'heart eyes','🤩':'star struck','😘':'kiss blowing','😗':'kissing','😚':'kiss closed',\n '😋':'savor yum','😛':'tongue','😜':'wink tongue silly','🤪':'crazy wild','😝':'squint tongue',\n '🤑':'money tongue','🤗':'hug','🤭':'hand over mouth secret','🤫':'shush quiet silent',\n '🤔':'thinking think','🤐':'zipper mouth secret','🤨':'raised eyebrow suspicious',\n '😐':'neutral straight','😑':'expressionless blank','😶':'no mouth silent',\n '😏':'smirk smug','😒':'unamified','🙄':'eye roll',\n '😬':'grimace awkward','🤥':'lying liar nose',\n '😌':'relieved','😔':'pensive sad','😪':'sleepy tired','🤤':'drooling','😴':'sleeping zzz',\n '😷':'mask sick','🤒':'fever','🤕':'hurt bandage','🤢':'nauseous sick','🤮':'vomiting','🤧':'sneeze',\n '🥵':'hot sweat','🥶':'cold freeze','🥴':'dizzy','😵':'dizzy confused','🤯':'mind blown exploding',\n '🤠':'cowboy','🥳':'party celebration','🥸':'disguise','😎':'sunglasses cool','🤓':'nerd geek','🧐':'monocle',\n '😕':'confused','😟':'worried','🙁':'frown sad','😮':'surprised shock','😯':'hushed','😲':'astonished',\n '😳':'flushed embarrassed','🥺':'pleading puppy eyes',\n '😦':'frown','😧':'anguish','😨':'fearful afraid','😰':'anxious worry','😥':'disappointed',\n '😢':'cry sad tear','😭':'sobbing cry','😱':'scream horror','😖':'confounded','😣':'struggle',\n '😞':'disappointed','😓':'sweat','😩':'weary','😫':'tired exhausted','🥱':'yawn sleepy',\n '😤':'frustrated','😡':'angry rage','😠':'angry mad','🤬':'cursing swear',\n '😈':'devil evil grin','👿':'devil evil angry','💀':'skull death','☠':'skull crossbones danger',\n '💩':'poop','🤡':'clown','👹':'ogre monster','👺':'goblin',\n '👻':'ghost halloween','👽':'alien ufo','👾':'alien monster','🤖':'robot',\n '💋':'kiss lips',\n '👋':'wave hello bye','✋':'raised hand stop','👌':'ok perfect',\n '🤏':'pinching small','🤞':'crossed fingers luck','🤟':'love gesture','🤘':'horns rock','🤙':'call me',\n '👈':'point left','👉':'point right','👆':'point up','🖕':'middle finger',\n '👍':'thumbs up like','👎':'thumbs down dislike',\n '✊':'fist raised power','👊':'fist punch','🤛':'fist left','🤜':'fist right',\n '👏':'clap applause','🙌':'celebration','👐':'open hands','🤲':'palms together pray',\n '🤝':'handshake deal','🙏':'pray please thank',\n '✍':'writing','💅':'nail polish',\n '👂':'ear listen','👃':'nose smell','👣':'footsteps','👀':'eyes','👅':'tongue','👄':'mouth lips'\n};\n\nconst emojiAutocomplete: Plugin = {\n name: 'emojiAutocomplete',\n order: 6,\n css: '' +\n '.te-emoji-ac {' +\n ' position: fixed; z-index: 9999;' +\n ' background: #fff; border: 1px solid #dee2e6;' +\n ' border-radius: .375rem; box-shadow: 0 6px 20px rgba(0,0,0,.15);' +\n ' padding: .25rem; display: none;' +\n ' max-height: 160px; overflow-y: auto;' +\n ' min-width: 120px;' +\n '}' +\n '.te-emoji-ac-item {' +\n ' display: flex; align-items: center; gap: 6px;' +\n ' padding: 4px 8px; cursor: pointer;' +\n ' border-radius: .25rem; font-size: 1rem;' +\n '}' +\n '.te-emoji-ac-item:hover, .te-emoji-ac-item.active {' +\n ' background: #e7f1ff;' +\n '}',\n init(ctx: PluginContext): void {\n if(ctx.features.emojiAutocomplete === false) return;\n var editor = ctx.editor;\n\n var popup = document.createElement('div');\n popup.className = 'te-emoji-ac';\n document.body.appendChild(popup);\n\n var query = '';\n var activeIdx = 0;\n var items: Element[] = [];\n\n function buildItems(filter: string){\n filter = filter || '';\n popup.innerHTML = '';\n items = [];\n activeIdx = 0;\n var f = filter.toLowerCase();\n EMOJIS.forEach(function(e){\n var name = (EMOJI_NAMES[e] || '').toLowerCase();\n if(f && name.indexOf(f) === -1) return;\n var div = document.createElement('div');\n div.className = 'te-emoji-ac-item';\n div.textContent = e;\n div.setAttribute('data-emoji', e);\n popup.appendChild(div);\n });\n items = Array.prototype.slice.call(popup.children);\n if(items.length === 0){ popup.style.display = 'none'; return; }\n items[0].classList.add('active');\n popup.style.display = 'block';\n position();\n }\n\n function position(){\n var sel = window.getSelection();\n if(!sel || !sel.rangeCount) return;\n var r = sel.getRangeAt(0);\n var rect = r.getBoundingClientRect();\n popup.style.left = Math.max(4, rect.left) + 'px';\n popup.style.top = (rect.bottom + 4) + 'px';\n var pr = popup.getBoundingClientRect();\n if(pr.right > window.innerWidth - 4){\n popup.style.left = (window.innerWidth - pr.width - 4) + 'px';\n }\n if(pr.bottom > window.innerHeight - 4){\n popup.style.top = (rect.top - pr.height - 4) + 'px';\n }\n }\n\n function insertEmoji(emoji: string){\n editor.focus();\n var sel = window.getSelection();\n if(sel && sel.rangeCount > 0 && query){\n var range = sel.getRangeAt(0);\n var len = query.length + 1;\n if(range.startOffset >= len && range.startContainer.nodeType === 3){\n range.setStart(range.startContainer, range.startOffset - len);\n range.deleteContents();\n }\n }\n document.execCommand('insertText', false, emoji);\n popup.style.display = 'none';\n query = '';\n }\n\n function move(dir: number){\n if(items.length === 0) return;\n items[activeIdx].classList.remove('active');\n activeIdx = (activeIdx + dir + items.length) % items.length;\n items[activeIdx].classList.add('active');\n (items[activeIdx] as HTMLElement).scrollIntoView({ block: 'nearest' });\n }\n\n editor.addEventListener('keydown', function(e: KeyboardEvent){\n if(popup.style.display === 'none') return;\n if(e.key === 'ArrowDown'){ e.preventDefault(); move(1); return; }\n if(e.key === 'ArrowUp'){ e.preventDefault(); move(-1); return; }\n if(e.key === 'Enter' || e.key === 'Tab'){\n e.preventDefault();\n var active = popup.querySelector('.active');\n if(active){\n var emoji = active.getAttribute('data-emoji');\n if(emoji) insertEmoji(emoji);\n }\n return;\n }\n if(e.key === 'Escape'){ popup.style.display = 'none'; query = ''; return; }\n });\n\n editor.addEventListener('input', function(){\n var sel = window.getSelection();\n if(!sel || !sel.rangeCount || !sel.anchorNode) return;\n var node = sel.anchorNode;\n var text = node.textContent || '';\n var offset = sel.anchorOffset;\n var before = text.slice(0, offset);\n var colon = before.lastIndexOf(':');\n if(colon !== -1 && before.indexOf(' ', colon) === -1 && colon !== offset - 1){\n query = before.slice(colon + 1);\n if(query.indexOf(':') !== -1){ popup.style.display = 'none'; return; }\n buildItems(query);\n } else if(colon !== -1 && colon === offset - 1){\n query = '';\n buildItems('');\n } else {\n popup.style.display = 'none';\n query = '';\n }\n });\n\n popup.addEventListener('mousedown', function(e: MouseEvent){\n var item = (e.target as HTMLElement) && (e.target as HTMLElement).closest && (e.target as HTMLElement).closest('.te-emoji-ac-item');\n if(!item) return;\n e.preventDefault();\n var emoji = (item as HTMLElement).getAttribute('data-emoji');\n if(emoji) insertEmoji(emoji);\n });\n }\n};\n\nexport default emojiAutocomplete;\n","import type { Plugin, PluginContext } from '../types';\n\nconst statusBar: Plugin = {\n name: 'statusBar',\n order: 100,\n css: '' +\n '.te-statusbar {' +\n ' display: flex; justify-content: space-between; gap: 1rem;' +\n ' padding: 4px 8px; font-size: .75rem; color: #6c757d;' +\n ' background: #f8f9fa; border: 1px solid #dee2e6;' +\n ' border-top: none; border-radius: 0 0 .375rem .375rem;' +\n '}' +\n '.te-statusbar .te-status-tag {' +\n ' font-weight: 600;' +\n ' font-family: monospace;' +\n '}',\n init(ctx: PluginContext): void {\n if(ctx.features.statusBar === false) return;\n var editor = ctx.editor;\n\n var bar = document.createElement('div');\n bar.className = 'te-statusbar';\n bar.innerHTML = '<span class=\"te-status-tag\"></span><span class=\"te-status-right\"><span class=\"te-status-words\">0 words</span><span class=\"te-status-chars\">0 characters</span></span>';\n editor.parentNode!.insertBefore(bar, editor.nextSibling);\n\n function getActiveTag(): string {\n var sel = window.getSelection();\n if(!sel || sel.rangeCount === 0) return '';\n var n: Node | null = sel.anchorNode;\n if(n && n.nodeType === 3) n = n.parentNode;\n if(!n || !editor.contains(n)) return '';\n var tag = '';\n var el: HTMLElement | null = n as HTMLElement;\n while(el && el !== editor){\n var t = el.tagName ? el.tagName.toLowerCase() : '';\n if(['p','h1','h2','h3','h4','h5','h6','div','blockquote','pre','li','td','th','ol','ul','table','thead','tbody','tfoot','tr'].indexOf(t) !== -1){\n tag = t;\n break;\n }\n el = el.parentElement;\n }\n return tag;\n }\n\n function update(): void {\n var sel = window.getSelection();\n var hasSel = sel && !sel.isCollapsed && editor.contains(sel.anchorNode) && editor.contains(sel.focusNode);\n var text = editor.textContent || '';\n var words = text.trim() ? text.trim().split(/\\s+/).length : 0;\n var chars = text.length;\n var tagEl = bar.querySelector('.te-status-tag') as HTMLElement | null;\n var rightEl = bar.querySelector('.te-status-right') as HTMLElement | null;\n if(tagEl) tagEl.textContent = getActiveTag();\n if(rightEl){\n var wEl = rightEl.querySelector('.te-status-words') as HTMLElement | null;\n var cEl = rightEl.querySelector('.te-status-chars') as HTMLElement | null;\n if(!wEl || !cEl){\n rightEl.innerHTML = '<span class=\"te-status-words\"></span><span class=\"te-status-chars\"></span>';\n wEl = rightEl.querySelector('.te-status-words') as HTMLElement | null;\n cEl = rightEl.querySelector('.te-status-chars') as HTMLElement | null;\n }\n if(wEl) wEl.textContent = words + ' word' + (words !== 1 ? 's' : '');\n if(cEl) cEl.textContent = chars + ' character' + (chars !== 1 ? 's' : '');\n if(hasSel){\n var selText = sel!.toString();\n var selWords = selText.trim() ? selText.trim().split(/\\s+/).length : 0;\n var txt = selWords + ' word' + (selWords !== 1 ? 's' : '') + ', ' + selText.length + ' char selected | ' + words + ' word' + (words !== 1 ? 's' : '') + ', ' + chars + ' characters';\n if(wEl) wEl.style.display = 'none';\n if(cEl) cEl.textContent = txt;\n } else {\n if(wEl) wEl.style.display = '';\n }\n }\n }\n\n editor.addEventListener('input', update);\n editor.addEventListener('paste', function(){ setTimeout(update, 100); });\n document.addEventListener('selectionchange', function(){\n if(document.activeElement === editor || editor.contains(document.activeElement)) update();\n });\n update();\n }\n};\n\nexport default statusBar;\n","import type { Plugin, PluginContext } from '../types';\n\nvar LANGUAGES = [\n { id: 'none', label: 'Plain text' },\n { id: 'markup', label: 'HTML' },\n { id: 'css', label: 'CSS' },\n { id: 'javascript', label: 'JavaScript' },\n { id: 'php', label: 'PHP' },\n { id: 'python', label: 'Python' },\n { id: 'java', label: 'Java' },\n { id: 'c', label: 'C' },\n { id: 'cpp', label: 'C++' },\n { id: 'sql', label: 'SQL' },\n { id: 'bash', label: 'Bash' },\n { id: 'json', label: 'JSON' },\n { id: 'typescript', label: 'TypeScript' },\n { id: 'go', label: 'Go' },\n { id: 'rust', label: 'Rust' },\n { id: 'ruby', label: 'Ruby' }\n];\n\nconst codeBlock: Plugin = {\n name: 'codeBlock',\n order: 23,\n css: '' +\n '.te-codeblock-popup {' +\n ' position: absolute; z-index: 3000;' +\n ' background: #fff; border: 1px solid #dee2e6;' +\n ' border-radius: .375rem; box-shadow: 0 6px 20px rgba(0,0,0,.15);' +\n ' padding: .5rem; min-width: 160px;' +\n '}' +\n '.te-codeblock-popup select {' +\n ' width: 100%; margin-bottom: .5rem;' +\n '}' +\n '.te-codeblock-popup .btn { width: 100%; }' +\n '.te-editor pre {' +\n ' background: #1e1e2e; border: 1px solid #45475a;' +\n ' border-left: 4px solid #89b4fa;' +\n ' border-radius: .375rem; padding: .75rem;' +\n ' overflow-x: auto; margin: .5rem 0;' +\n ' font-family: \"JetBrains Mono\", \"Fira Code\", \"Cascadia Code\", Consolas, monospace;' +\n ' font-size: .875rem; line-height: 1.6;' +\n ' color: #cdd6f4;' +\n '}' +\n '.te-editor pre code {' +\n ' background: none; padding: 0; font-size: inherit;' +\n ' line-height: inherit; color: inherit;' +\n '}',\n toolbarHTML: '<button type=\"button\" class=\"btn btn-sm btn-light\" title=\"Code block\" data-cmd=\"codeBlock\"><i class=\"ti ti-codeblock\"></i></button>',\n init(ctx: PluginContext): void {\n if(ctx.features.codeBlock === false) return;\n var btn = ctx.wrapper.querySelector('[data-cmd=\"codeBlock\"]') as HTMLButtonElement | null;\n if(!btn) return;\n\n var popup = document.createElement('div');\n popup.className = 'te-codeblock-popup';\n popup.style.display = 'none';\n popup.innerHTML = '' +\n '<select class=\"te-codeblock-lang form-select form-select-sm\">' +\n LANGUAGES.map(function(l){ return '<option value=\"' + l.id + '\">' + l.label + '</option>'; }).join('') +\n '</select>' +\n '<button type=\"button\" class=\"btn btn-sm btn-primary te-codeblock-insert\">Insert</button>';\n document.body.appendChild(popup);\n\n btn.addEventListener('click', function(e: MouseEvent){\n var rect = btn!.getBoundingClientRect();\n popup.style.left = (window.scrollX + rect.left) + 'px';\n popup.style.top = (window.scrollY + rect.bottom + 4) + 'px';\n popup.style.display = popup.style.display === 'none' ? 'block' : 'none';\n });\n\n (popup.querySelector('.te-codeblock-insert') as HTMLButtonElement).addEventListener('click', function(){\n var lang = (popup.querySelector('.te-codeblock-lang') as HTMLSelectElement).value;\n var sel = window.getSelection();\n var text = sel ? sel.toString() : '';\n if(!text) text = 'code';\n var cls = lang && lang !== 'none' ? ' class=\"language-' + lang + '\"' : '';\n var html = '<pre><code' + cls + '>' + text.replace(/</g,'&lt;').replace(/>/g,'&gt;') + '</code></pre>';\n document.execCommand('insertHTML', false, html);\n popup.style.display = 'none';\n ctx.editor.focus();\n });\n\n document.addEventListener('click', function(e: MouseEvent){\n if(popup.style.display === 'none') return;\n if(!popup.contains(e.target as Node) && e.target !== btn){\n popup.style.display = 'none';\n }\n });\n }\n};\n\nexport default codeBlock;\n","import type { Plugin, PluginContext } from '../types';\nimport * as H from '../core/helpers';\n\nvar EMBED_PROVIDERS: { match: RegExp; embed: (id: string) => string }[] = [\n {\n match: /(?:https?:\\/\\/)?(?:www\\.)?(?:youtube\\.com\\/(?:watch\\?v=|embed\\/|shorts\\/)|youtu\\.be\\/)([a-zA-Z0-9_-]{11})/,\n embed: function(id){ return '<iframe src=\"https://www.youtube.com/embed/' + id + '\" style=\"max-width:100%;border:0;aspect-ratio:16/9;\" allowfullscreen></iframe>'; }\n },\n {\n match: /(?:https?:\\/\\/)?(?:www\\.)?vimeo\\.com\\/(\\d+)/,\n embed: function(id){ return '<iframe src=\"https://player.vimeo.com/video/' + id + '\" style=\"max-width:100%;border:0;aspect-ratio:16/9;\" allowfullscreen></iframe>'; }\n }\n];\n\nconst mediaEmbed: Plugin = {\n name: 'mediaEmbed',\n order: 2,\n init(ctx: PluginContext): void {\n if(ctx.features.mediaEmbed === false) return;\n var editor = ctx.editor;\n\n editor.addEventListener('paste', function(e: ClipboardEvent){\n var text = (e.clipboardData && e.clipboardData.getData('text/plain')) || '';\n if(!text) return;\n text = text.trim();\n\n for(var i = 0; i < EMBED_PROVIDERS.length; i++){\n var m = text.match(EMBED_PROVIDERS[i].match);\n if(m && m[1]){\n e.preventDefault();\n e.stopImmediatePropagation();\n var html = EMBED_PROVIDERS[i].embed(m[1]);\n document.execCommand('insertHTML', false, html);\n setTimeout(function(){\n try { H.normalizeParagraphs(editor); H.ensureInitialParagraph(editor); } catch(_){ }\n }, 0);\n return;\n }\n }\n }, true);\n }\n};\n\nexport default mediaEmbed;\n","import type { Plugin, PluginContext } from '../types';\n\nconst dragDrop: Plugin = {\n name: 'dragDrop',\n order: 3,\n css: '' +\n '.te-editor.te-dragover {' +\n ' outline: 3px dashed rgba(13,110,253,.5);' +\n ' outline-offset: -6px;' +\n ' background: rgba(13,110,253,.03);' +\n '}',\n init(ctx: PluginContext): void {\n if(ctx.features.dragDrop === false) return;\n var editor = ctx.editor;\n\n function isImageFile(file: File): boolean {\n return file && /^image\\/(png|jpe?g|gif|webp|svg\\+xml|bmp)$/i.test(file.type);\n }\n\n function readFile(file: File | Blob, cb: (url: string) => void): void {\n var reader = new FileReader();\n reader.onload = function(){ cb(reader.result as string); };\n reader.readAsDataURL(file);\n }\n\n editor.addEventListener('dragenter', function(e: DragEvent){\n e.preventDefault();\n e.stopPropagation();\n editor.classList.add('te-dragover');\n });\n\n editor.addEventListener('dragover', function(e: DragEvent){\n e.preventDefault();\n e.stopPropagation();\n });\n\n editor.addEventListener('dragleave', function(e: DragEvent){\n e.preventDefault();\n e.stopPropagation();\n if(!editor.contains(e.relatedTarget as Node)){\n editor.classList.remove('te-dragover');\n }\n });\n\n editor.addEventListener('drop', function(e: DragEvent){\n e.preventDefault();\n e.stopPropagation();\n editor.classList.remove('te-dragover');\n\n var files = e.dataTransfer && e.dataTransfer.files;\n if(!files || files.length === 0) return;\n\n for(var i = 0; i < files.length; i++){\n var file = files[i];\n if(!isImageFile(file)) continue;\n\n var handler = (ctx.TulihEditor && ctx.TulihEditor.onUploadImage) || readFile;\n handler(file, function(url: string){\n if(!url) return;\n var html = '<img src=\"' + url.replace(/\"/g,'&quot;') + '\" alt=\"' + (file.name || '').replace(/\"/g,'&quot;') + '\" style=\"max-width:100%;\" />';\n document.execCommand('insertHTML', false, html);\n });\n }\n });\n }\n};\n\nexport default dragDrop;\n","import type { Plugin, PluginContext } from '../types';\nimport * as H from '../core/helpers';\n\nconst pastePlain: Plugin = {\n name: 'pastePlain',\n order: 24,\n css: '' +\n '.te-pasteplain-btn.active { background: #e7f1ff; border-color: #b6d4fe; }',\n toolbarHTML: '<button type=\"button\" class=\"btn btn-sm btn-light te-pasteplain-btn\" title=\"Paste as plain text\" data-cmd=\"togglePastePlain\"><i class=\"ti ti-clipboard\"></i></button>',\n init(ctx: PluginContext): void {\n if(!ctx.features.pastePlain) return;\n var editor = ctx.editor;\n ctx._pastePlain = false;\n\n var btn = ctx.wrapper.querySelector('[data-cmd=\"togglePastePlain\"]');\n if(btn){\n btn.addEventListener('click', function(){\n ctx._pastePlain = !ctx._pastePlain;\n (btn as HTMLElement).classList.toggle('active', ctx._pastePlain as boolean);\n });\n }\n\n editor.addEventListener('paste', function(e: ClipboardEvent){\n if(!ctx._pastePlain) return;\n e.stopImmediatePropagation();\n e.preventDefault();\n var text = (e.clipboardData && e.clipboardData.getData('text/plain')) || '';\n if(text){\n var safe = H.escapeHtml(text);\n var html = '<p>' + safe.replace(/\\n{2,}/g, '</p><p>').replace(/\\n/g, '<br>') + '</p>';\n document.execCommand('insertHTML', false, html);\n }\n setTimeout(function(){\n try {\n H.normalizeParagraphs(editor);\n H.ensureInitialParagraph(editor);\n } catch(_){}\n }, 0);\n }, true);\n }\n};\n\nexport default pastePlain;\n","import type { Plugin, PluginContext, TeEditorElement } from '../types';\n\nconst findReplace: Plugin = {\n name: 'findReplace',\n order: 31,\n css: '' +\n '.te-fr-popup {' +\n ' position: absolute; z-index: 3000;' +\n ' background: #fff; border: 1px solid #dee2e6;' +\n ' border-radius: .5rem; box-shadow: 0 6px 20px rgba(0,0,0,.15);' +\n ' padding: .75rem; width: 320px;' +\n '}' +\n '.te-fr-popup .te-fr-row { display: flex; gap: .5rem; margin-bottom: .5rem; }' +\n '.te-fr-popup .te-fr-row:last-child { margin-bottom: 0; }' +\n '.te-fr-popup input { flex: 1; }' +\n '.te-fr-popup .btn { white-space: nowrap; }' +\n '.te-fr-count { font-size: .8rem; color: #6c757d; padding: .25rem .5rem; }' +\n '.te-fr-match { background: #fff3cd; outline: 2px solid #ffc107; }' +\n '.te-fr-active { background: #f0ad4e; outline: 2px solid #e68600; }',\n toolbarHTML: '<button type=\"button\" class=\"btn btn-sm btn-light\" title=\"Find & Replace\" data-cmd=\"findReplace\"><i class=\"ti ti-search\"></i></button>',\n init(ctx: PluginContext): void {\n if(!ctx.features.findReplace) return;\n var editor = ctx.editor as TeEditorElement;\n var popup = document.createElement('div');\n popup.className = 'te-fr-popup';\n popup.style.display = 'none';\n popup.innerHTML = '' +\n '<div class=\"te-fr-row\">' +\n '<input type=\"text\" class=\"form-control form-control-sm te-fr-find\" placeholder=\"Find...\" />' +\n '<button type=\"button\" class=\"btn btn-sm btn-outline-primary te-fr-prev\" title=\"Previous\">&uarr;</button>' +\n '<button type=\"button\" class=\"btn btn-sm btn-primary te-fr-next\" title=\"Next\">&darr;</button>' +\n '</div>' +\n '<div class=\"te-fr-row\">' +\n '<input type=\"text\" class=\"form-control form-control-sm te-fr-replace\" placeholder=\"Replace...\" />' +\n '<button type=\"button\" class=\"btn btn-sm btn-outline-secondary te-fr-replace-btn\">Replace</button>' +\n '<button type=\"button\" class=\"btn btn-sm btn-outline-secondary te-fr-replace-all\">All</button>' +\n '</div>' +\n '<div class=\"te-fr-row\">' +\n '<span class=\"te-fr-count\"></span>' +\n '<button type=\"button\" class=\"btn btn-sm btn-outline-secondary te-fr-close ms-auto\" title=\"Close\">&times;</button>' +\n '</div>';\n document.body.appendChild(popup);\n\n var findInp = popup.querySelector('.te-fr-find') as HTMLInputElement;\n var replaceInp = popup.querySelector('.te-fr-replace') as HTMLInputElement;\n var countEl = popup.querySelector('.te-fr-count') as HTMLElement;\n\n function escapeRe(s: string){\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n }\n\n function clearHighlights(){\n editor.querySelectorAll('.te-fr-match, .te-fr-active').forEach(function(el){\n var parent = el.parentNode;\n if(!parent) return;\n while(el.firstChild) parent.insertBefore(el.firstChild, el);\n parent.removeChild(el);\n });\n editor.normalize();\n }\n\n function selectMatch(el: Element | null){\n editor.querySelectorAll('.te-fr-active').forEach(function(a){ a.classList.remove('te-fr-active'); a.classList.add('te-fr-match'); });\n if(!el) return;\n el.classList.remove('te-fr-match');\n el.classList.add('te-fr-active');\n (el as HTMLElement).scrollIntoView({ block: 'nearest' });\n var range = document.createRange();\n range.selectNodeContents(el);\n var sel = window.getSelection()!;\n sel.removeAllRanges();\n sel.addRange(range);\n }\n\n var highlights: Element[] = [];\n var currentIdx = -1;\n\n function doFind(){\n clearHighlights();\n var text = findInp.value.trim();\n if(!text) return;\n var nodes: Node[] = [];\n var walker = document.createTreeWalker(editor, NodeFilter.SHOW_TEXT, null);\n while(walker.nextNode()) nodes.push(walker.currentNode);\n highlights = [];\n nodes.forEach(function(node){\n var nodeText = node.textContent!;\n var re2 = new RegExp(escapeRe(text), 'gi');\n var matches: { idx: number; len: number }[] = [];\n var match: RegExpExecArray | null;\n while((match = re2.exec(nodeText)) !== null){\n matches.push({ idx: match.index, len: match[0].length });\n }\n // Process matches in reverse order to avoid index drift\n for(var i = matches.length - 1; i >= 0; i--){\n var m = matches[i];\n var span = document.createElement('span');\n span.className = 'te-fr-match';\n span.textContent = nodeText.substring(m.idx, m.idx + m.len);\n var after = (node as Text).splitText(m.idx + m.len);\n var mid = (node as Text).splitText(m.idx);\n mid.parentNode!.replaceChild(span, mid);\n highlights.push(span);\n }\n });\n countEl.textContent = highlights.length + ' matches';\n }\n\n function goNext(){\n if(!highlights.length){ doFind(); if(!highlights.length) return; currentIdx = 0; }\n else currentIdx = (currentIdx + 1) % highlights.length;\n selectMatch(highlights[currentIdx]);\n }\n function goPrev(){\n if(!highlights.length){ doFind(); if(!highlights.length) return; currentIdx = highlights.length - 1; }\n else currentIdx = (currentIdx - 1 + highlights.length) % highlights.length;\n selectMatch(highlights[currentIdx]);\n }\n function doFindAndSelect(dir: number){\n doFind();\n if(!highlights.length) return;\n currentIdx = dir === 1 ? 0 : highlights.length - 1;\n selectMatch(highlights[currentIdx]);\n }\n\n popup.querySelector('.te-fr-next')!.addEventListener('click', goNext);\n popup.querySelector('.te-fr-prev')!.addEventListener('click', goPrev);\n function closePopup(){\n popup.style.display = 'none';\n clearHighlights();\n editor.focus();\n }\n\n findInp.addEventListener('input', function(){ doFind(); });\n findInp.addEventListener('keydown', function(e: KeyboardEvent){\n if(e.key === 'Enter') { e.preventDefault(); doFindAndSelect(1); }\n if(e.key === 'Escape') { e.preventDefault(); closePopup(); }\n });\n replaceInp.addEventListener('keydown', function(e: KeyboardEvent){\n if(e.key === 'Enter') { e.preventDefault(); (popup.querySelector('.te-fr-replace-btn') as HTMLButtonElement).click(); }\n if(e.key === 'Escape') { e.preventDefault(); closePopup(); }\n });\n function saveUndoState(){\n clearHighlights();\n if(!editor._tableHist) editor._tableHist = {undo:[], redo:[]};\n editor._tableHist.undo.push(editor.innerHTML);\n if(editor._tableHist.undo.length > 50) editor._tableHist.undo.shift();\n editor._tableHist.redo = [];\n }\n\n function updateUndoRedoBtns(){\n var btn = ctx.wrapper.querySelector('[data-cmd=\"undo\"]') as HTMLButtonElement | null;\n var rbtn = ctx.wrapper.querySelector('[data-cmd=\"redo\"]') as HTMLButtonElement | null;\n var h = editor._tableHist;\n if(btn) btn.toggleAttribute('disabled', !h || !h.undo.length);\n if(rbtn) rbtn.toggleAttribute('disabled', !h || !h.redo.length);\n }\n\n popup.querySelector('.te-fr-replace-btn')!.addEventListener('click', function(){\n if(!highlights.length) return;\n var active = editor.querySelector('.te-fr-active');\n if(!active) return;\n saveUndoState();\n var text = replaceInp.value;\n var parent = active.parentNode;\n if(parent) parent.replaceChild(document.createTextNode(text), active);\n // Update highlights\n highlights.splice(currentIdx, 1);\n countEl.textContent = highlights.length + ' matches';\n if(highlights.length){\n currentIdx = Math.min(currentIdx, highlights.length - 1);\n selectMatch(highlights[currentIdx]);\n } else {\n countEl.textContent = '0 matches';\n }\n updateUndoRedoBtns();\n });\n popup.querySelector('.te-fr-replace-all')!.addEventListener('click', function(){\n var findText = findInp.value.trim();\n var replaceText = replaceInp.value;\n if(!findText) return;\n saveUndoState();\n clearHighlights();\n var re = new RegExp(escapeRe(findText), 'gi');\n var walker = document.createTreeWalker(editor, NodeFilter.SHOW_TEXT, null);\n var nodes: Node[] = [];\n while(walker.nextNode()) nodes.push(walker.currentNode);\n var count = 0;\n nodes.forEach(function(node){\n var text = node.textContent!;\n if(!re.test(text)) return;\n re.lastIndex = 0;\n node.textContent = text.replace(re, function(){ count++; return replaceText; });\n });\n countEl.textContent = count + ' replaced';\n highlights = [];\n currentIdx = -1;\n updateUndoRedoBtns();\n });\n popup.querySelector('.te-fr-close')!.addEventListener('click', closePopup);\n\n var btn = ctx.wrapper.querySelector('[data-cmd=\"findReplace\"]') as HTMLButtonElement | null;\n if(!btn) return;\n btn.addEventListener('click', function(e: MouseEvent){\n var rect = (btn as HTMLButtonElement).getBoundingClientRect();\n popup.style.left = (window.scrollX + rect.left) + 'px';\n popup.style.top = (window.scrollY + rect.bottom + 4) + 'px';\n popup.style.display = popup.style.display === 'none' ? 'block' : 'none';\n if(popup.style.display !== 'none'){\n findInp.value = '';\n replaceInp.value = '';\n countEl.textContent = '';\n clearHighlights();\n highlights = [];\n currentIdx = -1;\n findInp.focus();\n }\n });\n document.addEventListener('click', function(e: MouseEvent){\n if(popup.style.display === 'none') return;\n if(!popup.contains(e.target as Node) && e.target !== btn){\n popup.style.display = 'none';\n clearHighlights();\n }\n });\n }\n};\n\nexport default findReplace;\n","import type { Plugin, PluginContext } from '../types';\n\nconst indent: Plugin = {\n name: 'indent',\n order: 25,\n toolbarHTML: '' +\n '<button type=\"button\" class=\"btn btn-sm btn-light\" title=\"Indent\" data-cmd=\"indent\"><i class=\"ti ti-indent-increase\"></i></button>' +\n '<button type=\"button\" class=\"btn btn-sm btn-light\" title=\"Outdent\" data-cmd=\"outdent\"><i class=\"ti ti-indent-decrease\"></i></button>',\n init(ctx: PluginContext): void {\n if (!ctx.features.indent) return;\n // Buttons may be absent when a custom `toolbar` layout omits this group.\n const indentBtn = ctx.wrapper.querySelector('[data-cmd=\"indent\"]');\n if (indentBtn) {\n indentBtn.addEventListener('click', function () {\n document.execCommand('indent', false, undefined);\n ctx.editor.focus();\n });\n }\n const outdentBtn = ctx.wrapper.querySelector('[data-cmd=\"outdent\"]');\n if (outdentBtn) {\n outdentBtn.addEventListener('click', function () {\n document.execCommand('outdent', false, undefined);\n ctx.editor.focus();\n });\n }\n }\n};\n\nexport default indent;\n","import type { Plugin, PluginContext } from '../types';\n\nvar CLS_RE = /\\bte-list-\\S+/g;\n\nvar OL_STYLES = [\n { val: 'decimal', label: '1.', cls: '' },\n { val: 'upper-alpha', label: 'A.', cls: 'te-list-upper-alpha' },\n { val: 'lower-alpha', label: 'a.', cls: 'te-list-lower-alpha' },\n { val: 'upper-roman', label: 'I.', cls: 'te-list-upper-roman' },\n { val: 'lower-roman', label: 'i.', cls: 'te-list-lower-roman' }\n];\n\nvar UL_STYLES = [\n { val: 'disc', label: '•', cls: '' },\n { val: 'circle', label: '○', cls: 'te-list-circle' },\n { val: 'square', label: '■', cls: 'te-list-square' }\n];\n\nfunction setListStyle(list: HTMLElement | null, val: string, cls: string){\n if(!list) return;\n list.className = (list.className || '').replace(CLS_RE, '').trim();\n if(cls) list.classList.add(cls);\n list.style.listStyleType = val || '';\n}\n\nfunction findAncestorList(node: Node | null): HTMLElement | null {\n while(node && (node as Element).nodeType === 1){\n if((node as Element).tagName === 'OL' || (node as Element).tagName === 'UL') return node as HTMLElement;\n node = (node as Element).parentElement;\n }\n return null;\n}\n\nfunction buildOptions(styles: { val: string; label: string; cls: string }[]){\n var html = '<option value=\"\">—</option>';\n for(var i = 0; i < styles.length; i++){\n html += '<option value=\"' + styles[i].val + '\">' + styles[i].label + '</option>';\n }\n return html;\n}\n\nfunction handleSelect(ctx: PluginContext, select: HTMLSelectElement, tag: string, styles: { val: string; label: string; cls: string }[]){\n var val = select.value;\n select.value = '';\n\n var sel = window.getSelection();\n if(!sel || !sel.anchorNode) return;\n var node: Node | null = sel.anchorNode;\n if(node.nodeType === 3) node = node.parentNode;\n\n var list = findAncestorList(node);\n var execCmd = tag === 'OL' ? 'insertOrderedList' : 'insertUnorderedList';\n\n if(!val){\n if(list && list.tagName === tag){\n document.execCommand(execCmd, false, undefined);\n }\n ctx.editor.focus();\n return;\n }\n\n var matched: { val: string; label: string; cls: string } | null = null;\n for(var i = 0; i < styles.length; i++){\n if(styles[i].val === val){ matched = styles[i]; break; }\n }\n if(!matched) return;\n\n if(list){\n if(list.tagName === tag){\n setListStyle(list, val, matched.cls);\n } else {\n document.execCommand(execCmd, false, undefined);\n var afterNode: Node | null = sel.focusNode;\n if(afterNode && afterNode.nodeType === 3) afterNode = afterNode.parentNode;\n var newList = findAncestorList(afterNode);\n if(newList && newList.tagName === tag) setListStyle(newList, val, matched.cls);\n }\n } else {\n document.execCommand(execCmd, false, undefined);\n var afterNode: Node | null = sel.focusNode;\n if(afterNode && afterNode.nodeType === 3) afterNode = afterNode.parentNode;\n var newList = findAncestorList(afterNode);\n if(newList) setListStyle(newList, val, matched.cls);\n }\n ctx.editor.focus();\n}\n\nconst list: Plugin = {\n name: 'list',\n order: 25,\n css: '' +\n '.te-list-select { width: auto; }' +\n '.te-editor ol.te-list-upper-alpha { list-style-type: upper-alpha; }' +\n '.te-editor ol.te-list-lower-alpha { list-style-type: lower-alpha; }' +\n '.te-editor ol.te-list-upper-roman { list-style-type: upper-roman; }' +\n '.te-editor ol.te-list-lower-roman { list-style-type: lower-roman; }' +\n '.te-editor ul.te-list-circle { list-style-type: circle; }' +\n '.te-editor ul.te-list-square { list-style-type: square; }',\n toolbarHTML: '' +\n '<select class=\"te-list-ol form-select form-select-sm te-list-select\" title=\"Ordered list style\">' +\n buildOptions(OL_STYLES) +\n '</select>' +\n '<select class=\"te-list-ul form-select form-select-sm te-list-select\" title=\"Unordered list style\">' +\n buildOptions(UL_STYLES) +\n '</select>',\n init(ctx: PluginContext): void {\n if(ctx.features.list === false) return;\n\n var olSel = ctx.wrapper.querySelector('.te-list-ol') as HTMLSelectElement | null;\n var ulSel = ctx.wrapper.querySelector('.te-list-ul') as HTMLSelectElement | null;\n\n if(olSel){\n olSel.addEventListener('change', function(){\n handleSelect(ctx, olSel!, 'OL', OL_STYLES);\n });\n }\n\n if(ulSel){\n ulSel.addEventListener('change', function(){\n handleSelect(ctx, ulSel!, 'UL', UL_STYLES);\n });\n }\n\n ctx.editor.addEventListener('keydown', function(e: KeyboardEvent){\n if(e.key === 'Tab'){\n var sel = window.getSelection();\n if(!sel || !sel.anchorNode) return;\n var node: Node | null = sel.anchorNode;\n if(node.nodeType === 3) node = node.parentNode;\n var list = findAncestorList(node);\n if(list){\n e.preventDefault();\n document.execCommand(e.shiftKey ? 'outdent' : 'indent', false, undefined);\n ctx.editor.focus();\n }\n }\n });\n }\n};\n\nexport default list;\n","import type { Plugin, PluginContext } from '../types';\n\nconst lineHeight: Plugin = {\n name: 'lineHeight',\n order: 26,\n css: '' +\n '.te-lh-select { width: auto; }',\n toolbarHTML: '' +\n '<select class=\"te-lh form-select form-select-sm te-lh-select\" title=\"Line height\">' +\n ' <option value=\"\" disabled selected>Line Height</option>' +\n ' <option value=\"1\">1</option>' +\n ' <option value=\"1.15\">1.15</option>' +\n ' <option value=\"1.5\">1.5</option>' +\n ' <option value=\"1.8\">1.8</option>' +\n ' <option value=\"2\">2</option>' +\n ' <option value=\"2.5\">2.5</option>' +\n ' <option value=\"3\">3</option>' +\n '</select>',\n init(ctx: PluginContext): void {\n if(!ctx.features.lineHeight) return;\n var sel = ctx.wrapper.querySelector('.te-lh') as HTMLSelectElement | null;\n if(!sel) return;\n sel.addEventListener('change', function(){\n var v = sel!.value;\n if(!v) return;\n document.execCommand('formatBlock', false, 'p');\n var s = window.getSelection();\n if(!s || !s.rangeCount) return;\n var node: Node | null = s.anchorNode;\n if(node && node.nodeType === 3) node = node.parentNode;\n var block = node && (node as Element).closest && (node as Element).closest('p,h1,h2,h3,h4,h5,h6,div,li,blockquote');\n if(block && ctx.wrapper.contains(block)){\n (block as HTMLElement).style.lineHeight = v;\n }\n ctx.editor.focus();\n });\n }\n};\n\nexport default lineHeight;\n","import type { Plugin, PluginContext } from '../types';\nimport * as H from '../core/helpers';\n\nvar FONT_SIZES = ['8', '9', '10', '11', '12', '13', '14', '16', '18', '20', '22', '24', '26', '28', '36', '48', '72'];\n\nconst fontSize: Plugin = {\n name: 'fontSize',\n order: 27,\n css: '' +\n '.te-fontsize-select { width: auto; }',\n toolbarHTML: '' +\n '<span class=\"te-dropdown-icon te-dropdown-icon-text\">Aa</span>' +\n '<select class=\"te-fontsize form-select form-select-sm te-fontsize-select\" title=\"Font size\">' +\n ' <option value=\"\">Normal</option>' +\n FONT_SIZES.map(function (s) { return '<option value=\"' + s + '\">' + s + '</option>'; }).join('') +\n '</select>',\n init(ctx: PluginContext): void {\n if (!ctx.features.fontSize) return;\n var sel = ctx.wrapper.querySelector('.te-fontsize') as HTMLSelectElement | null;\n if (!sel) return;\n sel.addEventListener('change', function () {\n var v = sel!.value;\n if (!v) return;\n var txt = H.escapeHtml(window.getSelection()!.toString() || 'text');\n var html = '<span style=\"font-size:' + v + 'px\">' + txt + '</span>';\n document.execCommand('insertHTML', false, html);\n ctx.editor.focus();\n });\n }\n};\n\nexport default fontSize;\n","import type { Plugin, PluginContext } from '../types';\n\nvar FONTS = [\n 'Arial',\n 'Arial Black',\n 'Comic Sans MS',\n 'Courier New',\n 'Georgia',\n 'Impact',\n 'Lucida Console',\n 'Tahoma',\n 'Times New Roman',\n 'Trebuchet MS',\n 'Verdana'\n];\n\nconst fontFamily: Plugin = {\n name: 'fontFamily',\n order: 28,\n css: '' +\n '.te-fontfamily-select { width: auto; }',\n toolbarHTML: '' +\n '<span class=\"te-dropdown-icon\"><i class=\"ti ti-typography\"></i></span>' +\n '<select class=\"te-fontfamily form-select form-select-sm te-fontfamily-select\" title=\"Font family\">' +\n ' <option value=\"\">Normal</option>' +\n FONTS.map(function(f){ return '<option value=\"' + f + '\">' + f + '</option>'; }).join('') +\n '</select>',\n init(ctx: PluginContext): void {\n if(!ctx.features.fontFamily) return;\n var sel = ctx.wrapper.querySelector('.te-fontfamily') as HTMLSelectElement | null;\n if(!sel) return;\n sel.addEventListener('change', function(){\n var v = sel!.value;\n if(!v) return;\n document.execCommand('fontName', false, v);\n ctx.editor.focus();\n });\n }\n};\n\nexport default fontFamily;\n","import type { Plugin, PluginContext } from '../types';\n\nvar CHARS = '©®™§±•·†‡•¶′″←↑→↓↔↕⇒⇔∞≈≠≤≥√∛∜÷×∑∏∫∂∇∅∈∉∋∧∨∩∪⊂⊃⊆⊇¬∧∨⇒⇔∀∃∄∵∴∷∠∟∡∥∦∼≅≜≛≝≟≠≡≢≤≥≦≧≨≩≪≫≬≭≮≯≰≱≲≳≴≵≶≷≸≹≺≻≼≽≾≿⊀⊁⊂⊃⊄⊅⊆⊇⊈⊉⊊⊋⊌⊍⊎⊏⊐⊑⊒⊓⊔⊕⊖⊗⊘⊙⊚⊛⊜⊝⊞⊟⊠⊡⊢⊣⊤⊥⊦⊧⊨⊩⊪⊫⊬⊭⊮⊯⊰⊱⊲⊳⊴⊵⊶⊷⊸⊹⊺⊻⊼⊽⊾⊿⋀⋁⋂⋃⋄⋅⋆⋇⋈⋉⋊⋋⋌⋍⋎⋏⋐⋑⋒⋓⋔⋕⋖⋗⋘⋙⋚⋛⋜⋝⋞⋟€£¥₩₽₨₪₫₭₮₰₱₲₳₴₵₶₷₸₹₺₻₼₽₾₿'.split('');\n\nconst specialChars: Plugin = {\n name: 'specialChars',\n order: 29,\n css: '' +\n '.te-sc-popup {' +\n ' position: absolute; z-index: 3000;' +\n ' display: grid; grid-template-columns: repeat(10, 1fr); gap: 2px;' +\n ' background: #fff; border: 1px solid #dee2e6;' +\n ' border-radius: .5rem; box-shadow: 0 6px 20px rgba(0,0,0,.15);' +\n ' padding: .5rem; max-width: 320px; max-height: 200px; overflow-y: auto;' +\n '}' +\n '.te-sc-popup button {' +\n ' background: none; border: none; font-size: 1rem;' +\n ' padding: .25rem; cursor: pointer; border-radius: .25rem; text-align: center;' +\n '}' +\n '.te-sc-popup button:hover { background: #f0f0f0; }',\n toolbarHTML: '<button type=\"button\" class=\"btn btn-sm btn-light\" title=\"Special characters\" data-cmd=\"specialChars\"><i class=\"ti ti-hash\"></i></button>',\n init(ctx: PluginContext): void {\n if(!ctx.features.specialChars) return;\n\n var popup = document.createElement('div');\n popup.className = 'te-sc-popup';\n popup.style.display = 'none';\n CHARS.forEach(function(ch){\n var btn = document.createElement('button');\n btn.type = 'button';\n btn.textContent = ch;\n btn.setAttribute('data-sc', ch);\n popup.appendChild(btn);\n });\n document.body.appendChild(popup);\n\n var btn = ctx.wrapper.querySelector('[data-cmd=\"specialChars\"]') as HTMLElement | null;\n if(btn){\n btn.addEventListener('click', function(e: MouseEvent){\n var rect = (btn as HTMLElement).getBoundingClientRect();\n popup.style.left = (window.scrollX + rect.left) + 'px';\n popup.style.top = (window.scrollY + rect.bottom + 4) + 'px';\n popup.style.display = popup.style.display === 'none' ? 'grid' : 'none';\n });\n }\n\n popup.addEventListener('click', function(e: MouseEvent){\n var ch = (e.target as HTMLElement) && (e.target as HTMLElement).getAttribute('data-sc');\n if(!ch) return;\n document.execCommand('insertHTML', false, ch);\n popup.style.display = 'none';\n ctx.editor.focus();\n });\n\n document.addEventListener('click', function(e: MouseEvent){\n if(popup.style.display === 'none') return;\n if(!popup.contains(e.target as Node) && e.target !== btn){\n popup.style.display = 'none';\n }\n });\n }\n};\n\nexport default specialChars;\n","import type { Plugin, PluginContext } from '../types';\n\nconst colors: Plugin = {\n name: 'colors',\n order: 30,\n css: '' +\n '.te-color-btn {' +\n ' position: relative; padding: .15rem .35rem !important;' +\n ' min-width: 28px; text-align: center;' +\n '}' +\n '.te-color-preview {' +\n ' display: block; font-size: 1rem; line-height: 1;' +\n '}' +\n '.te-color-preview::after {' +\n ' content: \"\"; display: block;' +\n ' height: 3px; border-radius: 1px;' +\n ' margin-top: 2px;' +\n '}' +\n '.te-fore-btn .te-color-preview::after {' +\n ' background: currentColor;' +\n '}' +\n '.te-back-btn .te-color-preview::after {' +\n ' background: var(--te-back-color, #ffff00);' +\n '}' +\n '.te-color-input {' +\n ' position: absolute; top: 0; left: 0;' +\n ' width: 100%; height: 100%;' +\n ' opacity: 0; cursor: pointer;' +\n ' border: none; padding: 0;' +\n '}',\n toolbarHTML: '' +\n '<button type=\"button\" class=\"btn btn-sm btn-light te-color-btn te-fore-btn\" title=\"Text color\">' +\n '<span class=\"te-color-preview\" style=\"color:#000000\">A</span>' +\n '<input type=\"color\" class=\"te-color-input te-fore-color\" value=\"#000000\">' +\n '</button>' +\n '<button type=\"button\" class=\"btn btn-sm btn-light te-color-btn te-back-btn\" title=\"Background color\">' +\n '<span class=\"te-color-preview\" style=\"--te-back-color:#ffff00;color:#000\">A</span>' +\n '<input type=\"color\" class=\"te-color-input te-back-color\" value=\"#ffff00\">' +\n '</button>',\n init(ctx: PluginContext): void {\n if(!ctx.features.colors) return;\n\n var foreInput = ctx.wrapper.querySelector('.te-fore-color') as HTMLInputElement | null;\n var foreBtn = ctx.wrapper.querySelector('.te-fore-btn') as HTMLElement | null;\n if(foreBtn && foreInput){\n foreInput.addEventListener('change', function(){\n var preview = foreBtn!.querySelector('.te-color-preview') as HTMLElement;\n preview.style.color = foreInput!.value;\n document.execCommand('foreColor', false, foreInput!.value);\n ctx.editor.focus();\n });\n }\n\n var backInput = ctx.wrapper.querySelector('.te-back-color') as HTMLInputElement | null;\n var backBtn = ctx.wrapper.querySelector('.te-back-btn') as HTMLElement | null;\n if(backBtn && backInput){\n backInput.addEventListener('change', function(){\n var preview = backBtn!.querySelector('.te-color-preview') as HTMLElement;\n preview.style.setProperty('--te-back-color', backInput!.value);\n try{ document.execCommand('hiliteColor', false, backInput!.value); }\n catch(_){ document.execCommand('backColor', false, backInput!.value); }\n ctx.editor.focus();\n });\n }\n }\n};\n\nexport default colors;\n","import type { Plugin, PluginContext } from '../types';\n\nconst tableBg: Plugin = {\n name: 'tableBg',\n order: 56,\n init(ctx: PluginContext): void {\n // tableBg moved to tableTools floating bar\n },\n};\n\nexport default tableBg;\n","import type { Plugin, PluginContext } from '../types';\n\nvar ALIGN_CMDS: Record<string, { exec: string; match: string }> = {\n alignLeft: { exec: 'justifyLeft', match: 'left' },\n alignCenter: { exec: 'justifyCenter', match: 'center' },\n alignRight: { exec: 'justifyRight', match: 'right' },\n alignJustify: { exec: 'justifyFull', match: 'justify' }\n};\n\nfunction getBlockAlignment(node: Node | null): string {\n if(!node || node.nodeType === 3) node = node ? node.parentNode : null;\n if(!node) return '';\n var el = (node as Element).closest ? (node as Element).closest('p,h1,h2,h3,h4,h5,h6,li,div,blockquote') : null;\n if(!el) return '';\n try {\n var cs = window.getComputedStyle(el);\n var ta = cs.textAlign.toLowerCase();\n if(ta === 'start') return 'left';\n return ta;\n } catch(_){ return ''; }\n}\n\nconst align: Plugin = {\n name: 'align',\n order: 40,\n css: '',\n toolbarHTML: '' +\n '<button type=\"button\" class=\"btn btn-sm btn-light te-align-btn\" title=\"Align left\" data-cmd=\"alignLeft\"><i class=\"ti ti-align-left\"></i></button>' +\n '<button type=\"button\" class=\"btn btn-sm btn-light te-align-btn\" title=\"Align center\" data-cmd=\"alignCenter\"><i class=\"ti ti-align-center\"></i></button>' +\n '<button type=\"button\" class=\"btn btn-sm btn-light te-align-btn\" title=\"Align right\" data-cmd=\"alignRight\"><i class=\"ti ti-align-right\"></i></button>' +\n '<button type=\"button\" class=\"btn btn-sm btn-light te-align-btn\" title=\"Justify\" data-cmd=\"alignJustify\"><i class=\"ti ti-align-justified\"></i></button>',\n init(ctx: PluginContext): void {\n if(!ctx.features.align) return;\n var names = Object.keys(ALIGN_CMDS);\n\n names.forEach(function(name){\n var btn = ctx.wrapper.querySelector('[data-cmd=\"' + name + '\"]') as HTMLElement | null;\n if(!btn) return;\n var cmd = ALIGN_CMDS[name];\n btn.addEventListener('click', function(){\n var align = getBlockAlignment(window.getSelection()!.anchorNode);\n\n if(align === cmd.match){\n document.execCommand('justifyLeft', false, undefined);\n } else {\n document.execCommand(cmd.exec, false, undefined);\n }\n ctx.editor.focus();\n updateActive();\n });\n });\n\n function updateActive(): void {\n var node = window.getSelection()!.anchorNode;\n if(!node || !ctx.wrapper.contains(node)) return;\n var align = getBlockAlignment(node);\n names.forEach(function(name){\n var btn = ctx.wrapper.querySelector('[data-cmd=\"' + name + '\"]') as HTMLElement | null;\n if(!btn) return;\n btn.classList.toggle('active', align === ALIGN_CMDS[name].match);\n });\n }\n\n document.addEventListener('selectionchange', function(){\n if(document.activeElement === ctx.editor || ctx.editor.contains(document.activeElement)){\n updateActive();\n }\n });\n }\n};\n\nexport default align;\n","import type { Plugin, PluginContext } from '../types';\n\nvar RULES: Array<{ re: RegExp; cmd: string; val: string | null }> = [\n { re: /^#{6}\\s$/, cmd: 'formatBlock', val: 'h6' },\n { re: /^#{5}\\s$/, cmd: 'formatBlock', val: 'h5' },\n { re: /^#{4}\\s$/, cmd: 'formatBlock', val: 'h4' },\n { re: /^#{3}\\s$/, cmd: 'formatBlock', val: 'h3' },\n { re: /^#{2}\\s$/, cmd: 'formatBlock', val: 'h2' },\n { re: /^#{1}\\s$/, cmd: 'formatBlock', val: 'h1' },\n { re: /^>\\s$/, cmd: 'formatBlock', val: 'blockquote' },\n { re: /^[-*]\\s$/, cmd: 'insertUnorderedList', val: null },\n { re: /^1[.)]\\s$/, cmd: 'insertOrderedList', val: null },\n];\n\nconst markdown: Plugin = {\n name: 'markdown',\n order: 5,\n init(ctx: PluginContext): void {\n if(!ctx.features.markdown) return;\n\n ctx.editor.addEventListener('keydown', function(e: KeyboardEvent){\n if(e.key !== ' ' && e.key !== 'Enter') return;\n\n var sel = window.getSelection();\n if(!sel || sel.rangeCount === 0 || !sel.isCollapsed) return;\n var node = sel.anchorNode;\n if(!node || node.nodeType !== 3) return;\n var text = node.textContent || '';\n\n for(var i = 0; i < RULES.length; i++){\n var rule = RULES[i];\n if(!rule.re.test(text)) continue;\n\n e.preventDefault();\n\n if(e.key === 'Enter'){\n node.textContent = text.slice(0, -1);\n setTimeout(function(){\n document.execCommand(rule.cmd, false, rule.val || undefined);\n }, 0);\n return;\n }\n\n node.textContent = '';\n document.execCommand(rule.cmd, false, rule.val || undefined);\n ctx.editor.focus();\n return;\n }\n\n if(e.key === 'Enter' && text.trim() === ''){\n var parent = node.parentNode as HTMLElement | null;\n if(parent && (parent.tagName === 'BLOCKQUOTE' || parent.tagName === 'PRE')){\n e.preventDefault();\n document.execCommand('formatBlock', false, 'p');\n }\n }\n });\n }\n};\n\nexport default markdown;\n","import type { Plugin, PluginContext } from '../types';\n\nconst link: Plugin = {\n name: 'link',\n order: 50,\n toolbarHTML: '<button type=\"button\" class=\"btn btn-sm btn-light\" title=\"Link\" data-cmd=\"createLink\"><i class=\"ti ti-link\"></i></button>',\n css: '' +\n '.te-link-tools {' +\n ' position: fixed; display: none; z-index: 3000;' +\n ' background: #fff; border: 1px solid #dee2e6;' +\n ' border-radius: .375rem; box-shadow: 0 6px 20px rgba(0,0,0,.15);' +\n ' padding: .25rem .35rem; gap: .2rem; align-items: center;' +\n ' white-space: nowrap;' +\n '}' +\n '.te-link-tools .btn {' +\n ' padding: .2rem .45rem !important; font-size: .75rem !important; line-height: 1 !important;' +\n '}' +\n '.te-link-tools .btn i,' +\n '.te-link-tools .btn svg {' +\n ' width: 12px !important; height: 12px !important;' +\n ' pointer-events: none;' +\n '}' +\n '.te-link-tools .te-divider-v {' +\n ' display: inline-block; width: 1px; height: 14px;' +\n ' background: #dee2e6; margin: 0 .15rem; vertical-align: middle;' +\n '}' +\n '.te-link-edit-popup {' +\n ' position: fixed; display: none; z-index: 3001;' +\n ' background: #fff; border: 1px solid #dee2e6;' +\n ' border-radius: .375rem; box-shadow: 0 6px 20px rgba(0,0,0,.15);' +\n ' padding: .35rem; gap: .25rem; align-items: center;' +\n ' white-space: nowrap;' +\n '}' +\n '.te-link-edit-popup input {' +\n ' width: 220px; padding: .2rem .4rem; font-size: .8rem;' +\n ' border: 1px solid #dee2e6; border-radius: .25rem; outline: none;' +\n '}' +\n '.te-link-edit-popup input:focus {' +\n ' border-color: #86b7fe; box-shadow: 0 0 0 2px rgba(13,110,253,.15);' +\n '}' +\n '.te-link-edit-popup .btn {' +\n ' padding: .2rem .5rem !important; font-size: .75rem !important; line-height: 1 !important;' +\n '}',\n modalHTML: '' +\n '<div class=\"te-link-modal te-modal\" aria-hidden=\"true\">' +\n ' <div class=\"te-modal-backdrop\" data-te-close></div>' +\n ' <div class=\"te-modal-dialog\">' +\n ' <div class=\"te-modal-header\">' +\n ' <h5 class=\"te-modal-title m-0\">Insert Link</h5>' +\n ' <button type=\"button\" class=\"btn-close\" data-te-close aria-label=\"Close\"></button>' +\n ' </div>' +\n ' <form class=\"te-link-form\">' +\n ' <div class=\"te-modal-body\">' +\n ' <div class=\"mb-3\">' +\n ' <label class=\"form-label\">URL</label>' +\n ' <input type=\"url\" class=\"te-link-url form-control\" placeholder=\"https://example.com\" required>' +\n ' </div>' +\n ' <div class=\"mb-3\">' +\n ' <label class=\"form-label\">Text (optional)</label>' +\n ' <input type=\"text\" class=\"te-link-text form-control\" placeholder=\"Link text\">' +\n ' </div>' +\n ' <div class=\"mb-3\">' +\n ' <label class=\"form-label\">Rel (optional)</label>' +\n ' <input type=\"text\" class=\"te-link-rel form-control\" placeholder=\"noopener noreferrer, nofollow, ugc, sponsored\">' +\n ' </div>' +\n ' <div class=\"form-check\">' +\n ' <input class=\"te-link-blank form-check-input\" type=\"checkbox\" checked>' +\n ' <label class=\"form-check-label\">Open in new tab</label>' +\n ' </div>' +\n ' </div>' +\n ' <div class=\"te-modal-footer\">' +\n ' <button type=\"button\" class=\"btn btn-outline-secondary\" data-te-close>Cancel</button>' +\n ' <button type=\"submit\" class=\"btn btn-primary\">Insert</button>' +\n ' </div>' +\n ' </form>' +\n ' </div>' +\n '</div>',\n init(ctx: PluginContext): void {\n if(!ctx.features.link) return;\n var editingLink: HTMLAnchorElement | null = null;\n\n var linkTools = document.createElement('div');\n linkTools.className = 'te-link-tools';\n linkTools.innerHTML = '' +\n '<button type=\"button\" class=\"btn btn-sm btn-light\" data-te-link=\"edit\" title=\"Edit link\"><i class=\"ti ti-edit\"></i> Edit</button>' +\n '<button type=\"button\" class=\"btn btn-sm btn-light\" data-te-link=\"remove\" title=\"Remove link\"><i class=\"ti ti-link-off\"></i> Remove</button>';\n document.body.appendChild(linkTools);\n\n var linkEditPopup = document.createElement('div');\n linkEditPopup.className = 'te-link-edit-popup';\n linkEditPopup.innerHTML = '' +\n '<input type=\"url\" class=\"te-link-edit-url\" placeholder=\"https://example.com\" />' +\n '<button type=\"button\" class=\"btn btn-sm btn-primary\" data-te-link-edit=\"apply\">Apply</button>' +\n '<button type=\"button\" class=\"btn btn-sm btn-light\" data-te-link-edit=\"cancel\">Cancel</button>';\n document.body.appendChild(linkEditPopup);\n\n function posLinkTools(a: HTMLAnchorElement): void {\n var rect = a.getBoundingClientRect();\n var er = ctx.editor.getBoundingClientRect();\n linkTools.style.display = 'flex';\n linkTools.style.visibility = 'hidden';\n var tw = linkTools.offsetWidth;\n var th = linkTools.offsetHeight;\n var left = rect.left + rect.width / 2 - tw / 2;\n if(left < er.left) left = er.left;\n if(left + tw > er.right) left = er.right - tw;\n linkTools.style.left = left + 'px';\n var spaceBelow = window.innerHeight - rect.bottom;\n var top = (spaceBelow >= th + 6) ? (rect.bottom + 6) : (rect.top - th - 6);\n if(top < er.top) top = rect.bottom + 6;\n linkTools.style.top = top + 'px';\n linkTools.style.visibility = '';\n }\n\n function hideLinkTools(): void {\n linkTools.style.display = 'none';\n editingLink = null;\n }\n\n var _editPopupTime = 0;\n\n function hideEditPopup(_from?: string): void {\n if(Date.now() - _editPopupTime < 200) return;\n linkEditPopup.style.display = 'none';\n }\n\n function showEditPopup(link: HTMLAnchorElement): void {\n _editPopupTime = Date.now();\n var rect = link.getBoundingClientRect();\n var er = ctx.editor.getBoundingClientRect();\n linkEditPopup.style.display = 'flex';\n linkEditPopup.style.visibility = 'hidden';\n var pw = linkEditPopup.offsetWidth || 350;\n var ph = linkEditPopup.offsetHeight || 32;\n var left = rect.left + rect.width / 2 - pw / 2;\n if(left < er.left) left = er.left;\n if(left + pw > er.right) left = er.right - pw;\n linkEditPopup.style.left = left + 'px';\n var spaceBelow = window.innerHeight - rect.bottom;\n linkEditPopup.style.top = ((spaceBelow >= ph + 6) ? (rect.bottom + 6) : (rect.top - ph - 6)) + 'px';\n linkEditPopup.style.visibility = '';\n (linkEditPopup.querySelector('.te-link-edit-url') as HTMLInputElement).value = link.getAttribute('href') || '';\n setTimeout(function(){ (linkEditPopup.querySelector('.te-link-edit-url') as HTMLInputElement).focus(); }, 0);\n }\n\n function openLinkModal(): void {\n ctx.saveSel();\n var m = ctx.wrapper.querySelector('.te-link-modal');\n if(m) m.classList.add('is-open');\n }\n\n function closeLinkModal(): void {\n var m = ctx.wrapper.querySelector('.te-link-modal');\n if(m) m.classList.remove('is-open');\n }\n\n function fillModal(a: HTMLAnchorElement): void {\n var u = ctx.wrapper.querySelector('.te-link-url') as HTMLInputElement | null;\n var t = ctx.wrapper.querySelector('.te-link-text') as HTMLInputElement | null;\n var r = ctx.wrapper.querySelector('.te-link-rel') as HTMLInputElement | null;\n var b = ctx.wrapper.querySelector('.te-link-blank') as HTMLInputElement | null;\n var sub = ctx.wrapper.querySelector('.te-link-form button[type=\"submit\"]') as HTMLButtonElement | null;\n if(u) u.value = a.getAttribute('href') || '';\n if(t) t.value = a.textContent || '';\n if(r) r.value = a.getAttribute('rel') || '';\n if(b) b.checked = a.getAttribute('target') === '_blank';\n if(sub) sub.textContent = 'Update';\n }\n\n function getSelectedText(): string {\n var sel = window.getSelection();\n return (sel && sel.toString().trim()) || '';\n }\n\n var btn = ctx.wrapper.querySelector('[data-cmd=\"createLink\"]');\n if(btn){\n btn.addEventListener('click', function(){\n editingLink = null;\n hideLinkTools();\n hideEditPopup();\n var u = ctx.wrapper.querySelector('.te-link-url') as HTMLInputElement | null;\n var t = ctx.wrapper.querySelector('.te-link-text') as HTMLInputElement | null;\n var r = ctx.wrapper.querySelector('.te-link-rel') as HTMLInputElement | null;\n var b = ctx.wrapper.querySelector('.te-link-blank') as HTMLInputElement | null;\n var sub = ctx.wrapper.querySelector('.te-link-form button[type=\"submit\"]') as HTMLButtonElement | null;\n if(u) u.value = '';\n if(t) t.value = getSelectedText() || '';\n if(r) r.value = '';\n if(b) b.checked = true;\n if(sub) sub.textContent = 'Insert';\n openLinkModal();\n });\n }\n\n ctx.editor.addEventListener('click', function(e: MouseEvent){\n var a = (e.target as HTMLElement).closest && (e.target as HTMLElement).closest('a') as HTMLAnchorElement | null;\n if(!a || !ctx.editor.contains(a)) return;\n if(!ctx.wrapper.contains(a)) return;\n if(e.ctrlKey || e.metaKey) e.preventDefault();\n e.stopPropagation();\n hideEditPopup('editor.click');\n editingLink = a;\n fillModal(a);\n posLinkTools(a);\n });\n\n linkTools.addEventListener('mousedown', function(e: MouseEvent){\n e.preventDefault();\n e.stopPropagation();\n var actionBtn = (e.target as HTMLElement).closest && (e.target as HTMLElement).closest('[data-te-link]') as HTMLElement | null;\n if(!actionBtn) return;\n var action = actionBtn.getAttribute('data-te-link');\n var link = editingLink;\n\n if(action === 'edit'){\n if(link && ctx.editor.contains(link)){\n editingLink = link;\n showEditPopup(link);\n setTimeout(function(){ linkTools.style.display = 'none'; }, 0);\n }\n }\n else if(action === 'remove'){\n hideLinkTools();\n if(link && ctx.editor.contains(link)){\n var parent = link.parentNode!;\n while(link.firstChild){\n parent.insertBefore(link.firstChild, link);\n }\n parent.removeChild(link);\n ctx.editor.focus();\n }\n }\n });\n\n function updateLink(url: string): void {\n if(!editingLink || !ctx.editor.contains(editingLink)) return;\n if(!/^https?:\\/\\//i.test(url) && !/^mailto:/i.test(url) && !/^tel:/i.test(url)) url = 'https://' + url;\n editingLink.setAttribute('href', url);\n hideEditPopup('updateLink');\n editingLink = null;\n ctx.editor.focus();\n }\n\n linkEditPopup.addEventListener('click', function(e: MouseEvent){ e.stopPropagation(); });\n\n linkEditPopup.addEventListener('mousedown', function(e: MouseEvent){\n e.preventDefault();\n e.stopPropagation();\n var actionBtn = (e.target as HTMLElement).closest && (e.target as HTMLElement).closest('[data-te-link-edit]') as HTMLElement | null;\n if(!actionBtn) return;\n var action = actionBtn.getAttribute('data-te-link-edit');\n\n if(action === 'cancel'){\n hideEditPopup();\n editingLink = null;\n ctx.editor.focus();\n return;\n }\n\n if(action === 'apply'){\n var url = (linkEditPopup.querySelector('.te-link-edit-url') as HTMLInputElement).value.trim();\n if(!url) return;\n updateLink(url);\n }\n });\n\n linkEditPopup.addEventListener('keydown', function(e: KeyboardEvent){\n if(e.key === 'Enter'){\n e.preventDefault();\n var url = (linkEditPopup.querySelector('.te-link-edit-url') as HTMLInputElement).value.trim();\n if(!url) return;\n updateLink(url);\n }\n if(e.key === 'Escape'){\n hideEditPopup();\n editingLink = null;\n ctx.editor.focus();\n }\n });\n\n linkTools.addEventListener('click', function(e: MouseEvent){ e.stopPropagation(); });\n\n document.addEventListener('click', function(e: MouseEvent){\n if(linkTools.style.display !== 'none' && !linkTools.contains(e.target as Node)){\n hideLinkTools();\n }\n if(linkEditPopup.style.display !== 'none' && !linkEditPopup.contains(e.target as Node)){\n var fromTools = (e.target as HTMLElement).closest && (e.target as HTMLElement).closest('.te-link-tools');\n if(!fromTools){\n if(Date.now() - _editPopupTime < 200){\n // too soon after showing edit popup, don't close\n } else {\n hideEditPopup('doc.click');\n editingLink = null;\n }\n }\n }\n });\n\n var form = ctx.wrapper.querySelector('.te-link-form');\n if(form){\n form.addEventListener('submit', function(e: Event){\n e.preventDefault();\n var url = ((ctx.wrapper.querySelector('.te-link-url') as HTMLInputElement).value || '').trim();\n var text = ((ctx.wrapper.querySelector('.te-link-text') as HTMLInputElement).value || '').trim();\n var blank = (ctx.wrapper.querySelector('.te-link-blank') as HTMLInputElement).checked;\n var rel = ((ctx.wrapper.querySelector('.te-link-rel') as HTMLInputElement).value || '').trim();\n if(!url) return;\n var isOk = ctx.utils.isSafeUrl ? ctx.utils.isSafeUrl(url, (ctx.options as any).urlSchemes || ['http','https']) : true;\n if(!isOk) return;\n\n if(editingLink && ctx.editor.contains(editingLink)){\n editingLink.setAttribute('href', url);\n if(blank) editingLink.setAttribute('target', '_blank');\n else editingLink.removeAttribute('target');\n if(rel) editingLink.setAttribute('rel', rel);\n else editingLink.removeAttribute('rel');\n if(text) editingLink.textContent = text;\n closeLinkModal();\n ctx.editor.focus();\n return;\n }\n\n ctx.restoreSel();\n var relFinal = rel || (blank ? 'noopener noreferrer' : '');\n var displayText = (text || url).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/\"/g,'&quot;');\n var a = '<a href=\"' + url.replace(/\"/g,'&quot;') + '\"' +\n (blank ? ' target=\"_blank\"' : '') +\n (relFinal ? ' rel=\"' + relFinal.replace(/\"/g,'&quot;') + '\"' : '') +\n '>' + displayText + '</a>';\n document.execCommand('insertHTML', false, a);\n closeLinkModal();\n ctx.editor.focus();\n });\n }\n\n var closeBtns = ctx.wrapper.querySelectorAll('[data-te-close]');\n for(var i = 0; i < closeBtns.length; i++){\n closeBtns[i].addEventListener('click', function(){ editingLink = null; });\n }\n }\n};\n\nexport default link;\n","import type { Plugin, PluginContext } from '../types';\n\nconst image: Plugin = {\n name: 'image',\n order: 51,\n toolbarHTML: '<button type=\"button\" class=\"btn btn-sm btn-light\" title=\"Image\" data-cmd=\"insertImage\"><i class=\"ti ti-photo\"></i></button>',\n modalHTML: '' +\n '<div class=\"te-image-modal te-modal\" aria-hidden=\"true\">' +\n ' <div class=\"te-modal-backdrop\" data-te-close></div>' +\n ' <div class=\"te-modal-dialog\">' +\n ' <div class=\"te-modal-header\">' +\n ' <h5 class=\"te-modal-title m-0\">Insert Image</h5>' +\n ' <button type=\"button\" class=\"btn-close\" data-te-close aria-label=\"Close\"></button>' +\n ' </div>' +\n ' <form class=\"te-image-form\">' +\n ' <div class=\"te-modal-body\">' +\n ' <div class=\"mb-3\">' +\n ' <label class=\"form-label\">Image URL</label>' +\n ' <input type=\"text\" class=\"te-image-url form-control\" placeholder=\"/path/to/image.jpg or https://...\" required>' +\n ' <div class=\"mt-2\"><button type=\"button\" class=\"te-image-browse btn btn-sm btn-outline-secondary\"><i class=\"ti ti-folder\"></i> Browse...</button></div>' +\n ' </div>' +\n ' <div class=\"mb-3\">' +\n ' <label class=\"form-label\">Alt text (optional)</label>' +\n ' <input type=\"text\" class=\"te-image-alt form-control\" placeholder=\"Description\">' +\n ' </div>' +\n ' </div>' +\n ' <div class=\"te-modal-footer\">' +\n ' <button type=\"button\" class=\"btn btn-outline-secondary\" data-te-close>Cancel</button>' +\n ' <button type=\"submit\" class=\"btn btn-primary\">Insert</button>' +\n ' </div>' +\n ' </form>' +\n ' </div>' +\n '</div>',\n init(ctx: PluginContext): void {\n if(!ctx.features.image) return;\n var btn = ctx.wrapper.querySelector('[data-cmd=\"insertImage\"]');\n if(btn){\n btn.addEventListener('click', function(){\n ctx.saveSel();\n var m = ctx.wrapper.querySelector('.te-image-modal');\n if(m) m.classList.add('is-open');\n });\n }\n var inputUrl = ctx.wrapper.querySelector('.te-image-url') as HTMLInputElement | null;\n\n var browseBtn = ctx.wrapper.querySelector('.te-image-browse');\n if(browseBtn){\n browseBtn.addEventListener('click', function(e: Event){\n e.preventDefault();\n if(ctx.TulihEditor && typeof ctx.TulihEditor.onBrowseImage === 'function'){\n ctx.TulihEditor.onBrowseImage({ container: ctx.wrapper, editor: ctx.editor }, function(url: string){\n if(url && inputUrl){ inputUrl.value = url; inputUrl.focus(); }\n });\n return;\n }\n var fi = document.createElement('input');\n fi.type = 'file';\n fi.accept = 'image/*';\n fi.style.display = 'none';\n document.body.appendChild(fi);\n fi.addEventListener('change', function(){\n var file = fi.files && fi.files[0];\n if(!file){ document.body.removeChild(fi); return; }\n var r = new FileReader();\n r.onload = function(){\n if(inputUrl){\n inputUrl.value = r.result as string;\n inputUrl.focus();\n }\n document.body.removeChild(fi);\n };\n r.readAsDataURL(file);\n });\n fi.click();\n });\n }\n var form = ctx.wrapper.querySelector('.te-image-form') as HTMLFormElement | null;\n if(form){\n form.addEventListener('submit', function(e: Event){\n e.preventDefault();\n var src = ((ctx.wrapper.querySelector('.te-image-url') as HTMLInputElement).value || '').trim();\n var alt = ((ctx.wrapper.querySelector('.te-image-alt') as HTMLInputElement).value || '').trim();\n if(!src) return;\n var ok = ctx.utils.isSafeUrl ? ctx.utils.isSafeUrl(src, (ctx.options as any).imageSchemes || ['http','https','data']) : true;\n if(!ok) return;\n ctx.restoreSel();\n ctx.editor.focus();\n var img = document.createElement('img');\n img.src = src;\n if(alt) img.alt = alt;\n var sel = window.getSelection();\n if(sel && sel.rangeCount > 0){\n var range = sel.getRangeAt(0);\n range.deleteContents();\n range.insertNode(img);\n range.setStartAfter(img);\n range.collapse(true);\n sel.removeAllRanges();\n sel.addRange(range);\n }\n form!.closest('.te-modal')!.classList.remove('is-open');\n });\n }\n }\n};\n\nexport default image;\n","import type { Plugin, PluginContext } from '../types';\n\nconst imageProps: Plugin = {\n name: 'imageProps',\n order: 52,\n deps: ['image'],\n modalHTML: '' +\n '<div class=\"te-image-props-modal te-modal\" aria-hidden=\"true\">' +\n ' <div class=\"te-modal-backdrop\" data-te-close></div>' +\n ' <div class=\"te-modal-dialog\">' +\n ' <div class=\"te-modal-header\">' +\n ' <h5 class=\"te-modal-title m-0\">Image Properties</h5>' +\n ' <button type=\"button\" class=\"btn-close\" data-te-close aria-label=\"Close\"></button>' +\n ' </div>' +\n ' <form class=\"te-image-props-form\">' +\n ' <div class=\"te-modal-body\">' +\n ' <div class=\"row g-2 mb-3\">' +\n ' <div class=\"col\">' +\n ' <label class=\"form-label\">Width</label>' +\n ' <input type=\"number\" min=\"0\" class=\"te-image-props-width form-control\" placeholder=\"e.g. 800\">' +\n ' </div>' +\n ' <div class=\"col\">' +\n ' <label class=\"form-label\">Height</label>' +\n ' <input type=\"number\" min=\"0\" class=\"te-image-props-height form-control\" placeholder=\"e.g. 600\">' +\n ' </div>' +\n ' </div>' +\n ' <div class=\"mb-3\">' +\n ' <label class=\"form-label\">Alt</label>' +\n ' <input type=\"text\" class=\"te-image-props-alt form-control\" placeholder=\"Alternative text\">' +\n ' </div>' +\n ' <div class=\"row g-2\">' +\n ' <div class=\"col\">' +\n ' <label class=\"form-label\">Class</label>' +\n ' <input type=\"text\" class=\"te-image-props-class form-control\" placeholder=\"class-1 class-2\">' +\n ' </div>' +\n ' <div class=\"col\">' +\n ' <label class=\"form-label\">ID</label>' +\n ' <input type=\"text\" class=\"te-image-props-id form-control\" placeholder=\"optional-id\">' +\n ' </div>' +\n ' </div>' +\n ' <div class=\"mb-3 mt-3\">' +\n ' <label class=\"form-label\">Style (inline CSS)</label>' +\n ' <input type=\"text\" class=\"te-image-props-style form-control\" placeholder=\"max-width:100%; height:auto;\">' +\n ' </div>' +\n ' </div>' +\n ' <div class=\"te-modal-footer\">' +\n ' <button type=\"button\" class=\"btn btn-outline-secondary\" data-te-close>Cancel</button>' +\n ' <button type=\"submit\" class=\"btn btn-primary\">Apply</button>' +\n ' </div>' +\n ' </form>' +\n ' </div>' +\n '</div>',\n init(ctx: PluginContext): void {\n if(!ctx.features.image || !ctx.features.imageProps) return;\n var modal = ctx.wrapper.querySelector('.te-image-props-modal') as HTMLElement | null;\n var form = ctx.wrapper.querySelector('.te-image-props-form') as HTMLFormElement | null;\n var altInp = ctx.wrapper.querySelector('.te-image-props-alt') as HTMLInputElement | null;\n var wInp = ctx.wrapper.querySelector('.te-image-props-width') as HTMLInputElement | null;\n var hInp = ctx.wrapper.querySelector('.te-image-props-height') as HTMLInputElement | null;\n var clsInp = ctx.wrapper.querySelector('.te-image-props-class') as HTMLInputElement | null;\n var idInp = ctx.wrapper.querySelector('.te-image-props-id') as HTMLInputElement | null;\n var styleInp = ctx.wrapper.querySelector('.te-image-props-style') as HTMLInputElement | null;\n var currentImg: HTMLImageElement | null = null;\n\n ctx.editor.addEventListener('dblclick', function(e: MouseEvent){\n var img = e.target && ((e.target as Element).closest && (e.target as Element).closest('img')) as HTMLImageElement | null;\n if(img && ctx.wrapper.contains(img) && modal){\n currentImg = img;\n if(altInp) altInp.value = img.getAttribute('alt') || '';\n if(wInp) wInp.value = img.getAttribute('width') || '';\n if(hInp) hInp.value = img.getAttribute('height') || '';\n if(clsInp) clsInp.value = img.getAttribute('class') || '';\n if(idInp) idInp.value = img.getAttribute('id') || '';\n if(styleInp) styleInp.value = img.getAttribute('style') || '';\n modal.classList.add('is-open');\n }\n });\n\n if(form){\n form.addEventListener('submit', function(e: Event){\n e.preventDefault();\n if(!currentImg){\n if(modal) modal.classList.remove('is-open');\n return;\n }\n var alt = (altInp && altInp.value) || '';\n var w = (wInp && wInp.value) || '';\n var h = (hInp && hInp.value) || '';\n var cls = (clsInp && clsInp.value) || '';\n var idv = (idInp && idInp.value) || '';\n var style = (styleInp && styleInp.value) || '';\n if(style){\n var safeCss: string[] = [];\n style.split(';').forEach(function(decl){\n var idx = decl.indexOf(':');\n if(idx === -1) return;\n var prop = decl.slice(0, idx).trim().toLowerCase();\n var val = decl.slice(idx + 1).trim();\n var SAFE = ['color','background-color','font-family','font-size','font-style','font-weight','text-align','text-decoration','line-height','letter-spacing','word-spacing','margin','margin-top','margin-right','margin-bottom','margin-left','padding','padding-top','padding-right','padding-bottom','padding-left','border','border-collapse','border-color','border-style','border-width','border-radius','width','height','max-width','max-height','min-width','min-height','float','clear','vertical-align','direction','white-space'];\n if(SAFE.indexOf(prop) !== -1) safeCss.push(prop + ':' + val);\n });\n style = safeCss.join(';');\n }\n\n if(alt) currentImg.setAttribute('alt', alt); else currentImg.removeAttribute('alt');\n if(w) currentImg.setAttribute('width', w); else currentImg.removeAttribute('width');\n if(h) currentImg.setAttribute('height', h); else currentImg.removeAttribute('height');\n if(cls) currentImg.setAttribute('class', cls); else currentImg.removeAttribute('class');\n if(idv) currentImg.setAttribute('id', idv); else currentImg.removeAttribute('id');\n if(style) currentImg.setAttribute('style', style); else currentImg.removeAttribute('style');\n\n if(modal) modal.classList.remove('is-open');\n currentImg = null;\n });\n }\n }\n};\n\nexport default imageProps;\n","import type { Plugin, PluginContext } from '../types';\n\nconst imageTools: Plugin = {\n name: 'imageTools',\n order: 56,\n deps: ['image', 'imageProps'],\n css: '' +\n '.te-image-tools {' +\n ' position: absolute; display: none; z-index: 2000;' +\n ' background: #fff; border: 1px solid #dee2e6;' +\n ' border-radius: .375rem; box-shadow: 0 6px 20px rgba(0,0,0,.15);' +\n ' padding: .375rem; gap: .25rem; align-items: center;' +\n '}' +\n '.te-image-tools .btn { padding: .2rem .4rem; font-size: .8rem; }' +\n '.te-image-tools svg, .te-image-tools i { pointer-events: none; }' +\n '.te-image-tools .te-image-tools-alt {' +\n ' width: 130px; height: 26px; font-size: .8rem;' +\n ' padding: 0 .35rem; border: 1px solid #dee2e6; border-radius: .25rem;' +\n '}' +\n '.te-image-tools .te-image-tools-alt:focus { outline: none; border-color: #86b7fe; box-shadow: 0 0 0 2px rgba(13,110,253,.25); }' +\n '.te-image-tools .te-divider-v {' +\n ' width: 1px; height: 20px; background: #dee2e6;' +\n '}' +\n '.te-image-tools .active { background: #e7f1ff; border-color: #b6d4fe; }' +\n '.te-editor img.te-focused {' +\n ' outline: 3px solid rgba(13,110,253,.4);' +\n ' outline-offset: 1px;' +\n '}' +\n '.te-image-resize {' +\n ' position: absolute; display: none; z-index: 2001;' +\n ' width: 10px; height: 10px;' +\n ' background: #0d6efd; border: 2px solid #fff;' +\n ' border-radius: 50%; cursor: nwse-resize;' +\n ' box-shadow: 0 1px 4px rgba(0,0,0,.3);' +\n '}' +\n '.te-image-resize:hover { transform: scale(1.2); }' +\n '.te-figure {' +\n ' display: inline-block; margin: .5rem 0;' +\n ' text-align: center; max-width: 100%;' +\n '}' +\n '.te-figure figcaption {' +\n ' font-size: .85rem; color: #6c757d;' +\n ' padding: .25rem .5rem; font-style: italic;' +\n '}',\n init(ctx: PluginContext): void {\n if(!ctx.features.image || !ctx.features.imageTools) return;\n\n var wrapper = ctx.wrapper;\n var editor = ctx.editor;\n var currentImage: HTMLImageElement | null = null;\n\n var tools = document.createElement('div');\n tools.className = 'te-image-tools';\n tools.innerHTML = '' +\n '<input type=\"text\" class=\"te-image-tools-alt\" placeholder=\"Alt text\" title=\"Alt text (Enter to apply)\" />' +\n '<div class=\"te-divider-v\"></div>' +\n '<button type=\"button\" class=\"btn btn-sm btn-light\" data-te-image=\"align-default\" title=\"Inline\"><i class=\"ti ti-align-left\"></i></button>' +\n '<button type=\"button\" class=\"btn btn-sm btn-light\" data-te-image=\"align-left\" title=\"Float left\"><i class=\"ti ti-align-left\"></i></button>' +\n '<button type=\"button\" class=\"btn btn-sm btn-light\" data-te-image=\"align-center\" title=\"Center\"><i class=\"ti ti-align-center\"></i></button>' +\n '<button type=\"button\" class=\"btn btn-sm btn-light\" data-te-image=\"align-right\" title=\"Float right\"><i class=\"ti ti-align-right\"></i></button>' +\n '<button type=\"button\" class=\"btn btn-sm btn-light\" data-te-image=\"caption\" title=\"Caption (toggle)\"><i class=\"ti ti-typography\"></i></button>' +\n '<div class=\"te-divider-v\"></div>' +\n '<button type=\"button\" class=\"btn btn-sm btn-light\" data-te-image=\"width-100\" title=\"Width 100%\">100%</button>' +\n '<button type=\"button\" class=\"btn btn-sm btn-light\" data-te-image=\"width-75\" title=\"Width 75%\">75%</button>' +\n '<button type=\"button\" class=\"btn btn-sm btn-light\" data-te-image=\"width-50\" title=\"Width 50%\">50%</button>' +\n '<button type=\"button\" class=\"btn btn-sm btn-light\" data-te-image=\"width-orig\" title=\"Original size\">Orig</button>' +\n '<div class=\"te-divider-v\"></div>' +\n '<button type=\"button\" class=\"btn btn-sm btn-light\" data-te-image=\"border\" title=\"Toggle border\">Brdr</button>' +\n '<button type=\"button\" class=\"btn btn-sm btn-light\" data-te-image=\"rounded\" title=\"Toggle rounded corners\">Rnd</button>' +\n '<div class=\"te-divider-v\"></div>' +\n '<button type=\"button\" class=\"btn btn-sm btn-outline-secondary\" data-te-image=\"props\" title=\"Image Properties\"><i class=\"ti ti-settings\"></i></button>' +\n '<button type=\"button\" class=\"btn btn-sm btn-outline-danger\" data-te-image=\"delete\" title=\"Delete image\"><i class=\"ti ti-x\"></i></button>';\n document.body.appendChild(tools);\n\n var resizeHandle = document.createElement('div');\n resizeHandle.className = 'te-image-resize';\n document.body.appendChild(resizeHandle);\n\n function getAlign(img: HTMLImageElement): string {\n var st = img.style;\n if(st.float === 'left') return 'left';\n if(st.float === 'right') return 'right';\n if(st.display === 'block' && st.marginLeft === 'auto' && st.marginRight === 'auto') return 'center';\n return 'default';\n }\n\n function setAlign(img: HTMLImageElement, align: string): void {\n if(align === 'default'){\n img.style.float = '';\n img.style.display = '';\n img.style.marginLeft = '';\n img.style.marginRight = '';\n } else if(align === 'left'){\n img.style.float = 'left';\n img.style.display = '';\n img.style.marginLeft = '0';\n img.style.marginRight = '1em';\n } else if(align === 'right'){\n img.style.float = 'right';\n img.style.display = '';\n img.style.marginLeft = '1em';\n img.style.marginRight = '0';\n } else if(align === 'center'){\n img.style.float = '';\n img.style.display = 'block';\n img.style.marginLeft = 'auto';\n img.style.marginRight = 'auto';\n }\n }\n\n function clearImageFocus(): void {\n if(!editor) return;\n var prev = editor.querySelector('.te-focused') as HTMLElement | null;\n if(prev) prev.classList.remove('te-focused');\n }\n\n function showResizeHandle(img: HTMLImageElement): void {\n var rect = img.getBoundingClientRect();\n resizeHandle.style.left = (window.scrollX + rect.right - 5) + 'px';\n resizeHandle.style.top = (window.scrollY + rect.bottom - 5) + 'px';\n resizeHandle.style.display = 'block';\n }\n\n function updateAlignBtns(img: HTMLImageElement): void {\n var align = getAlign(img);\n tools.querySelectorAll('[data-te-image^=\"align-\"]').forEach(function(b){\n b.classList.toggle('active', b.getAttribute('data-te-image') === 'align-' + align);\n });\n }\n\n function posTools(img: HTMLImageElement): void {\n var rect = img.getBoundingClientRect();\n var altInp = tools.querySelector('.te-image-tools-alt') as HTMLInputElement | null;\n if(altInp) altInp.value = img.getAttribute('alt') || '';\n tools.style.display = 'flex';\n tools.style.left = (window.scrollX + rect.left) + 'px';\n tools.style.visibility = 'hidden';\n var toolsH = tools.offsetHeight;\n var editorRect = wrapper.getBoundingClientRect();\n var below = rect.bottom + 6 + toolsH;\n var above = rect.top - 6 - toolsH;\n if(below > editorRect.bottom && above > editorRect.top){\n tools.style.top = (window.scrollY + rect.top - 6 - toolsH) + 'px';\n } else {\n tools.style.top = (window.scrollY + rect.bottom + 6) + 'px';\n }\n tools.style.visibility = '';\n showResizeHandle(img);\n updateAlignBtns(img);\n var capBtn = tools.querySelector('[data-te-image=\"caption\"]');\n if(capBtn) capBtn.classList.toggle('active', !!(img.parentNode && (img.parentNode as Element).tagName === 'FIGURE'));\n var brdrBtn = tools.querySelector('[data-te-image=\"border\"]');\n if(brdrBtn){\n var b = img.style.border || '';\n brdrBtn.classList.toggle('active', !!(b && b !== 'none'));\n }\n var rndBtn = tools.querySelector('[data-te-image=\"rounded\"]');\n if(rndBtn){\n var r = img.style.borderRadius || '';\n rndBtn.classList.toggle('active', !!(r && r !== '0px' && r !== ''));\n }\n }\n\n function hideTools(): void {\n tools.style.display = 'none';\n resizeHandle.style.display = 'none';\n clearImageFocus();\n currentImage = null;\n }\n\n editor.addEventListener('click', function(e: MouseEvent){\n var img = e.target && ((e.target as Element).closest ? (e.target as Element).closest('img') : null) as HTMLImageElement | null;\n if(img && wrapper.contains(img)){\n e.stopPropagation();\n currentImage = img;\n clearImageFocus();\n img.classList.add('te-focused');\n img.setAttribute('tabindex', '-1');\n try { img.focus({preventScroll: true}); } catch(_){ }\n posTools(img);\n } else {\n if(!tools.contains(e.target as Node) && e.target !== resizeHandle){\n hideTools();\n }\n }\n });\n\n editor.addEventListener('dblclick', function(){\n hideTools();\n });\n\n document.addEventListener('selectionchange', function(){\n if(!currentImage) return;\n if(document.activeElement !== currentImage &&\n !tools.contains(document.activeElement)){\n var sel = window.getSelection();\n if(!sel || sel.isCollapsed){\n hideTools();\n }\n }\n });\n\n tools.addEventListener('click', function(e: MouseEvent){\n var actionBtn = e.target && (e.target as Element).closest('[data-te-image]') as HTMLElement | null;\n var action = actionBtn && actionBtn.getAttribute('data-te-image');\n if(!action || !currentImage) return;\n e.preventDefault();\n e.stopPropagation();\n\n if(action === 'width-100'){\n currentImage.setAttribute('width', '100%');\n if(currentImage.style) currentImage.style.maxWidth = '100%';\n posTools(currentImage);\n }\n else if(action === 'width-75'){\n currentImage.setAttribute('width', '75%');\n posTools(currentImage);\n }\n else if(action === 'width-50'){\n currentImage.setAttribute('width', '50%');\n posTools(currentImage);\n }\n else if(action === 'width-orig'){\n currentImage.removeAttribute('width');\n currentImage.removeAttribute('height');\n if(currentImage.style) currentImage.style.maxWidth = '';\n posTools(currentImage);\n }\n else if(action === 'delete'){\n var parent = currentImage.parentNode;\n if(parent) parent.removeChild(currentImage);\n hideTools();\n }\n else if(action === 'props'){\n var dblClick = new MouseEvent('dblclick', { bubbles: true });\n currentImage.dispatchEvent(dblClick);\n hideTools();\n }\n else if(action.indexOf('align-') === 0){\n var a = action.replace('align-', '');\n setAlign(currentImage, a);\n updateAlignBtns(currentImage);\n posTools(currentImage);\n }\n else if(action === 'border'){\n var curBorder = currentImage.style.border || '';\n if(curBorder && curBorder !== 'none'){\n currentImage.style.border = '';\n currentImage.removeAttribute('border');\n } else {\n currentImage.style.border = '2px solid #dee2e6';\n }\n posTools(currentImage);\n }\n else if(action === 'rounded'){\n var curRadius = currentImage.style.borderRadius || '';\n if(curRadius && curRadius !== '0px'){\n currentImage.style.borderRadius = '';\n } else {\n currentImage.style.borderRadius = '8px';\n }\n posTools(currentImage);\n }\n else if(action === 'caption'){\n var fig = currentImage.parentNode as Element | null;\n if(fig && fig.tagName === 'FIGURE' && fig.classList.contains('te-figure')){\n var parent = fig.parentNode;\n var img = fig.querySelector('img') || fig.querySelector('figcaption');\n if(img){\n parent!.insertBefore(img, fig);\n parent!.removeChild(fig);\n }\n } else {\n var figure = document.createElement('figure');\n figure.className = 'te-figure';\n var caption = document.createElement('figcaption');\n caption.textContent = 'Caption';\n currentImage.parentNode!.insertBefore(figure, currentImage);\n figure.appendChild(currentImage);\n figure.appendChild(caption);\n caption.contentEditable = 'true';\n }\n posTools(currentImage);\n }\n });\n\n tools.addEventListener('keydown', function(e: KeyboardEvent){\n if(e.key === 'Enter' && currentImage){\n var altInp = tools.querySelector('.te-image-tools-alt') as HTMLInputElement | null;\n if(altInp){\n var val = altInp.value.trim();\n if(val) currentImage.setAttribute('alt', val);\n else currentImage.removeAttribute('alt');\n }\n }\n });\n\n var resizeData: { startX: number; parentW: number; startPct: number; startH: number } | null = null;\n resizeHandle.addEventListener('mousedown', function(e: MouseEvent){\n e.preventDefault();\n e.stopPropagation();\n if(!currentImage) return;\n var parentW = currentImage.parentNode ? (currentImage.parentNode as HTMLElement).clientWidth : currentImage.clientWidth;\n var currentPct = ((currentImage.clientWidth / parentW) * 100);\n var rect = currentImage.getBoundingClientRect();\n resizeData = {\n startX: e.clientX,\n parentW: parentW,\n startPct: currentPct,\n startH: rect.height\n };\n document.addEventListener('mousemove', onResize);\n document.addEventListener('mouseup', onResizeEnd);\n });\n\n function onResize(e: MouseEvent): void {\n if(!resizeData || !currentImage) return;\n var dx = e.clientX - resizeData.startX;\n var pctDelta = (dx / resizeData.parentW) * 100;\n var newPct = Math.max(5, resizeData.startPct + pctDelta);\n currentImage.style.width = newPct + '%';\n currentImage.style.height = 'auto';\n currentImage.removeAttribute('width');\n currentImage.removeAttribute('height');\n showResizeHandle(currentImage);\n }\n\n function onResizeEnd(): void {\n document.removeEventListener('mousemove', onResize);\n document.removeEventListener('mouseup', onResizeEnd);\n resizeData = null;\n if(currentImage) posTools(currentImage);\n }\n\n window.addEventListener('scroll', function(){\n if(currentImage && tools.style.display !== 'none') posTools(currentImage);\n });\n window.addEventListener('resize', function(){\n if(currentImage && tools.style.display !== 'none') posTools(currentImage);\n });\n }\n};\n\nexport default imageTools;\n","import type { Plugin, PluginContext } from '../types';\nimport * as H from '../core/helpers';\n\nconst iframe: Plugin = {\n name: 'iframe',\n order: 53,\n toolbarHTML: '<button type=\"button\" class=\"btn btn-sm btn-light\" title=\"Iframe\" data-cmd=\"insertIframe\"><i class=\"ti ti-video\"></i></button>',\n modalHTML: '' +\n '<div class=\"te-iframe-modal te-modal\" aria-hidden=\"true\">' +\n ' <div class=\"te-modal-backdrop\" data-te-close></div>' +\n ' <div class=\"te-modal-dialog\">' +\n ' <div class=\"te-modal-header\">' +\n ' <h5 class=\"te-modal-title m-0\">Insert Iframe</h5>' +\n ' <button type=\"button\" class=\"btn-close\" data-te-close aria-label=\"Close\"></button>' +\n ' </div>' +\n ' <form class=\"te-iframe-form\">' +\n ' <div class=\"te-modal-body\">' +\n ' <div class=\"mb-3\">' +\n ' <label class=\"form-label\">Src URL</label>' +\n ' <input type=\"url\" class=\"te-iframe-src form-control\" placeholder=\"https://...\" required>' +\n ' </div>' +\n ' <div class=\"row g-2 mb-3\">' +\n ' <div class=\"col\">' +\n ' <label class=\"form-label\">Width (px)</label>' +\n ' <input type=\"number\" min=\"0\" class=\"te-iframe-width form-control\" placeholder=\"640\">' +\n ' </div>' +\n ' <div class=\"col\">' +\n ' <label class=\"form-label\">Height (px)</label>' +\n ' <input type=\"number\" min=\"0\" class=\"te-iframe-height form-control\" placeholder=\"360\">' +\n ' </div>' +\n ' </div>' +\n ' <div class=\"mb-3\">' +\n ' <label class=\"form-label\">Allow (optional)</label>' +\n ' <input type=\"text\" class=\"te-iframe-allow form-control\" placeholder=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\">' +\n ' </div>' +\n ' <div class=\"form-check mb-2\">' +\n ' <input class=\"te-iframe-allowfullscreen form-check-input\" type=\"checkbox\" checked>' +\n ' <label class=\"form-check-label\">Allow Fullscreen</label>' +\n ' </div>' +\n ' <div class=\"mb-2\">' +\n ' <label class=\"form-label\">Title (accessibility, optional)</label>' +\n ' <input type=\"text\" class=\"te-iframe-title form-control\" placeholder=\"Embedded content description\">' +\n ' </div>' +\n ' </div>' +\n ' <div class=\"te-modal-footer\">' +\n ' <button type=\"button\" class=\"btn btn-outline-secondary\" data-te-close>Cancel</button>' +\n ' <button type=\"submit\" class=\"btn btn-primary\">Insert</button>' +\n ' </div>' +\n ' </form>' +\n ' </div>' +\n '</div>',\n init(ctx: PluginContext): void {\n if(!ctx.features.iframe) return;\n var btn = ctx.wrapper.querySelector('[data-cmd=\"insertIframe\"]') as HTMLButtonElement | null;\n if(btn){\n btn.addEventListener('click', function(){\n ctx.saveSel();\n var m = ctx.wrapper.querySelector('.te-iframe-modal') as HTMLElement | null;\n if(m) m.classList.add('is-open');\n });\n }\n var form = ctx.wrapper.querySelector('.te-iframe-form') as HTMLFormElement | null;\n if(form){\n form.addEventListener('submit', function(e: Event){\n e.preventDefault();\n ctx.restoreSel();\n var src = ((ctx.wrapper.querySelector('.te-iframe-src') as HTMLInputElement).value || '').trim();\n var w = ((ctx.wrapper.querySelector('.te-iframe-width') as HTMLInputElement).value || '').trim();\n var h = ((ctx.wrapper.querySelector('.te-iframe-height') as HTMLInputElement).value || '').trim();\n if(!src) return;\n var allowOk = ctx.utils.isAllowedIframeUrl ? ctx.utils.isAllowedIframeUrl(src) : true;\n if(!allowOk) return;\n var attrs = ' src=\"' + src.replace(/\"/g,'&quot;') + '\"';\n if(w) attrs += ' width=\"' + w.replace(/\"/g,'&quot;') + '\"';\n if(h) attrs += ' height=\"' + h.replace(/\"/g,'&quot;') + '\"';\n var sandbox = (ctx.options && ctx.options.iframeSandbox) || '';\n var allow = (ctx.options && ctx.options.iframeAllow) || '';\n if(sandbox) attrs += ' sandbox=\"' + sandbox.replace(/\"/g,'&quot;') + '\"';\n if(allow) attrs += ' allow=\"' + allow.replace(/\"/g,'&quot;') + '\"';\n var html = '<iframe' + attrs + ' style=\"max-width:100%;border:0;\"></iframe>';\n document.execCommand('insertHTML', false, html);\n (form!.closest('.te-modal') as HTMLElement).classList.remove('is-open');\n });\n }\n }\n};\n\nexport default iframe;\n","import type { Plugin, PluginContext } from '../types';\n\nvar MAX_COLS = 10;\nvar MAX_ROWS = 10;\n\nconst table: Plugin = {\n name: 'table',\n order: 54,\n css: '' +\n '.te-table-grid {' +\n ' position: absolute; z-index: 3000;' +\n ' background: #fff; border: 1px solid #dee2e6;' +\n ' border-radius: .5rem; box-shadow: 0 6px 20px rgba(0,0,0,.15);' +\n ' padding: .75rem;' +\n '}' +\n '.te-table-grid .te-tg-label {' +\n ' font-size: .8rem; color: #6c757d; text-align: center;' +\n ' margin-bottom: .5rem;' +\n '}' +\n '.te-table-grid .te-tg-cells {' +\n ' display: grid; gap: 2px;' +\n '}' +\n '.te-table-grid .te-tg-cell {' +\n ' width: 18px; height: 18px;' +\n ' background: #f0f0f0; border: 1px solid #dee2e6;' +\n ' border-radius: 2px; cursor: pointer;' +\n '}' +\n '.te-table-grid .te-tg-cell.active {' +\n ' background: #86b7fe; border-color: #0d6efd;' +\n '}' +\n '.te-tg-header {' +\n ' display: flex; justify-content: space-between; align-items: center;' +\n ' margin-bottom: .5rem;' +\n '}' +\n '.te-toolbar [data-cmd=\"insertTable\"] svg { pointer-events: none; }',\n toolbarHTML: '<button type=\"button\" class=\"btn btn-sm btn-light\" title=\"Table\" data-cmd=\"insertTable\"><i class=\"ti ti-table-plus\"></i></button>',\n modalHTML: '' +\n '<div class=\"te-table-props-modal te-modal\" aria-hidden=\"true\">' +\n ' <div class=\"te-modal-backdrop\" data-te-close></div>' +\n ' <div class=\"te-modal-dialog\">' +\n ' <div class=\"te-modal-header\">' +\n ' <h5 class=\"te-modal-title m-0\">Table Properties</h5>' +\n ' <button type=\"button\" class=\"btn-close\" data-te-close aria-label=\"Close\"></button>' +\n ' </div>' +\n ' <form class=\"te-table-props-form\">' +\n ' <div class=\"te-modal-body\">' +\n ' <div class=\"mb-3\">' +\n ' <label class=\"form-label\">Width (e.g. 100% or 800px)</label>' +\n ' <input type=\"text\" class=\"te-table-props-width form-control\" placeholder=\"100%\">' +\n ' </div>' +\n ' <div class=\"mb-3\">' +\n ' <label class=\"form-label\">Caption</label>' +\n ' <input type=\"text\" class=\"te-table-props-caption form-control\" placeholder=\"Optional caption\">' +\n ' </div>' +\n ' </div>' +\n ' <div class=\"te-modal-footer\">' +\n ' <button type=\"button\" class=\"btn btn-outline-secondary\" data-te-close>Cancel</button>' +\n ' <button type=\"submit\" class=\"btn btn-primary\">Apply</button>' +\n ' </div>' +\n ' </form>' +\n ' </div>' +\n '</div>',\n init(ctx: PluginContext): void {\n if(!ctx.features.table) return;\n\n var popup = document.createElement('div');\n popup.className = 'te-table-grid';\n popup.style.display = 'none';\n popup.innerHTML = '' +\n '<div class=\"te-tg-header\">' +\n '<span class=\"te-tg-label\">0 &times; 0</span>' +\n '<button type=\"button\" class=\"btn-close te-tg-close\" aria-label=\"Close\"></button>' +\n '</div>' +\n '<div class=\"te-tg-cells\" style=\"grid-template-columns: repeat(' + MAX_COLS + ', 18px);\"></div>';\n var cellsContainer = popup.querySelector('.te-tg-cells') as HTMLElement;\n var label = popup.querySelector('.te-tg-label') as HTMLElement;\n\n for(var r = 0; r < MAX_ROWS; r++){\n for(var c = 0; c < MAX_COLS; c++){\n var cell = document.createElement('div');\n cell.className = 'te-tg-cell';\n cell.setAttribute('data-r', r.toString());\n cell.setAttribute('data-c', c.toString());\n cellsContainer.appendChild(cell);\n }\n }\n\n function clearActive(){\n popup.querySelectorAll('.te-tg-cell.active').forEach(function(el){ el.classList.remove('active'); });\n }\n\n function highlight(r: number, c: number){\n clearActive();\n popup.querySelectorAll('.te-tg-cell').forEach(function(el){\n var er = parseInt(el.getAttribute('data-r')!, 10);\n var ec = parseInt(el.getAttribute('data-c')!, 10);\n if(er <= r && ec <= c) el.classList.add('active');\n });\n label.textContent = (c + 1) + ' × ' + (r + 1);\n }\n\n cellsContainer.addEventListener('mouseover', function(e: MouseEvent){\n var cell = (e.target as HTMLElement).closest('.te-tg-cell');\n if(!cell) return;\n var r = parseInt(cell.getAttribute('data-r')!, 10);\n var c = parseInt(cell.getAttribute('data-c')!, 10);\n highlight(r, c);\n });\n\n cellsContainer.addEventListener('mouseleave', function(){\n clearActive();\n label.textContent = '0 × 0';\n });\n\n function insertTable(cols: number, rows: number){\n ctx.restoreSel();\n var html = '<table class=\"te-table\"><tbody>';\n for(var rr = 0; rr < rows; rr++){\n html += '<tr>';\n for(var cc = 0; cc < cols; cc++){\n html += '<td><br></td>';\n }\n html += '</tr>';\n }\n html += '</tbody></table>';\n document.execCommand('insertHTML', false, html);\n }\n\n cellsContainer.addEventListener('click', function(e: MouseEvent){\n var cell = (e.target as HTMLElement).closest('.te-tg-cell');\n if(!cell) return;\n var cols = parseInt(cell.getAttribute('data-c')!, 10) + 1;\n var rows = parseInt(cell.getAttribute('data-r')!, 10) + 1;\n popup.style.display = 'none';\n insertTable(cols, rows);\n ctx.editor.focus();\n });\n\n document.body.appendChild(popup);\n\n (popup.querySelector('.te-tg-close') as HTMLElement).addEventListener('click', function(){\n popup.style.display = 'none';\n });\n\n var btn = ctx.wrapper.querySelector('[data-cmd=\"insertTable\"]') as HTMLElement | null;\n if(btn){\n btn.addEventListener('click', function(e: MouseEvent){\n e.stopPropagation();\n ctx.saveSel();\n var rect = btn!.getBoundingClientRect();\n popup.style.left = (window.scrollX + rect.left) + 'px';\n popup.style.top = (window.scrollY + rect.bottom + 4) + 'px';\n popup.style.display = popup.style.display === 'none' ? 'block' : 'none';\n });\n }\n\n document.addEventListener('click', function(e: MouseEvent){\n if(popup.style.display === 'none') return;\n if(!popup.contains(e.target as Node) && e.target !== btn){\n popup.style.display = 'none';\n }\n });\n }\n};\n\nexport default table;\n","import type { Plugin, PluginContext, TeEditorElement } from '../types';\n\nconst tableTools: Plugin = {\n name: 'tableTools',\n order: 55,\n deps: ['table'],\n css: '' +\n '.te-table-tools {' +\n ' position: absolute; display: none; z-index: 2000;' +\n ' background: #fff; border: 1px solid #dee2e6;' +\n ' border-radius: .375rem; box-shadow: 0 6px 20px rgba(0,0,0,.15);' +\n ' padding: .2rem .3rem; gap: .1rem; align-items: center;' +\n ' white-space: nowrap;' +\n '}' +\n '.te-table-tools .btn {' +\n ' padding: .15rem .35rem !important; font-size: .7rem !important; line-height: 1 !important;' +\n '}' +\n '.te-table-tools .btn svg {' +\n ' width: 12px !important; height: 12px !important;' +\n ' margin-right: 2px; vertical-align: middle;' +\n '}' +\n '.te-table-tools .te-divider-v {' +\n ' display: inline-block; width: 1px; height: 16px;' +\n ' background: #dee2e6; margin: 0 .2rem;' +\n '}' +\n '.te-table-tools .tt-label {' +\n ' font-size: .6rem; color: #6c757d; text-transform: uppercase;' +\n ' letter-spacing: .5px; margin: 0 .15rem;' +\n '}' +\n '.te-table-tools .te-bg-input {' +\n ' width: 26px !important; height: 20px !important;' +\n ' padding: 1px !important; border: 1px solid #dee2e6;' +\n ' border-radius: 3px; cursor: pointer;' +\n '}' +\n '.te-cell-selected {' +\n ' outline: 2px solid #0d6efd !important;' +\n ' outline-offset: -1px;' +\n '}',\n init(ctx: PluginContext): void {\n if(!ctx.features.table || !ctx.features.tableTools) return;\n\n var wrapper = ctx.wrapper;\n var editor = ctx.editor;\n var ed = ctx.editor as TeEditorElement;\n var tools = document.createElement('div');\n tools.className = 'te-table-tools';\n tools.style.display = 'none';\n tools.innerHTML = '' +\n '<span class=\"tt-label\">Add</span>' +\n '<button type=\"button\" class=\"btn btn-sm btn-light\" data-te-table=\"row-before\" title=\"Row above\"><i class=\"ti ti-chevron-up\"></i> Row</button>' +\n '<button type=\"button\" class=\"btn btn-sm btn-light\" data-te-table=\"row-after\" title=\"Row below\"><i class=\"ti ti-chevron-down\"></i> Row</button>' +\n '<button type=\"button\" class=\"btn btn-sm btn-light\" data-te-table=\"col-before\" title=\"Column before\"><i class=\"ti ti-chevron-left\"></i> Col</button>' +\n '<button type=\"button\" class=\"btn btn-sm btn-light\" data-te-table=\"col-after\" title=\"Column after\"><i class=\"ti ti-chevron-right\"></i> Col</button>' +\n '<span class=\"te-divider-v\"></span>' +\n '<span class=\"tt-label\">Del</span>' +\n '<button type=\"button\" class=\"btn btn-sm btn-outline-danger\" data-te-table=\"del-row\" title=\"Delete row\"><i class=\"ti ti-x\"></i> Row</button>' +\n '<button type=\"button\" class=\"btn btn-sm btn-outline-danger\" data-te-table=\"del-col\" title=\"Delete column\"><i class=\"ti ti-x\"></i> Col</button>' +\n '<button type=\"button\" class=\"btn btn-sm btn-outline-danger\" data-te-table=\"del-table\" title=\"Delete table\"><i class=\"ti ti-trash\"></i> Tbl</button>' +\n '<span class=\"te-divider-v\"></span>' +\n '<button type=\"button\" class=\"btn btn-sm btn-light\" data-te-table=\"merge\" title=\"Merge selected cells\"><i class=\"ti ti-maximize\"></i> Merge</button>' +\n '<button type=\"button\" class=\"btn btn-sm btn-light\" data-te-table=\"unmerge\" title=\"Unmerge cells\" style=\"display:none\"><i class=\"ti ti-minimize\"></i> Unmerge</button>' +\n '<span class=\"te-divider-v\"></span>' +\n '<button type=\"button\" class=\"btn btn-sm btn-outline-secondary\" data-te-table=\"toggle-header\" title=\"Toggle header\"><i class=\"ti ti-typography\"></i> Hdr</button>' +\n '<button type=\"button\" class=\"btn btn-sm btn-outline-secondary\" data-te-table=\"toggle-caption\" title=\"Toggle caption\"><i class=\"ti ti-align-left\"></i> Cap</button>' +\n '<span class=\"te-divider-v\"></span>' +\n '<span class=\"tt-label\">BG</span>' +\n '<input type=\"color\" class=\"te-bg-input form-control form-control-color\" value=\"#ffffff\" title=\"Cell background color\" />' +\n '<button type=\"button\" class=\"btn btn-sm btn-light\" data-te-table=\"bg-apply\" title=\"Apply background color\">Apply</button>' +\n '<button type=\"button\" class=\"btn btn-sm btn-light\" data-te-table=\"bg-clear\" title=\"Remove background color\">Clear</button>' +\n '<span class=\"te-divider-v\"></span>' +\n '<span class=\"tt-label\">V</span>' +\n '<button type=\"button\" class=\"btn btn-sm btn-light\" data-te-table=\"valign-top\" title=\"Align top\">Top</button>' +\n '<button type=\"button\" class=\"btn btn-sm btn-light\" data-te-table=\"valign-middle\" title=\"Align middle\">Mid</button>' +\n '<button type=\"button\" class=\"btn btn-sm btn-light\" data-te-table=\"valign-bottom\" title=\"Align bottom\">Bot</button>';\n document.body.appendChild(tools);\n\n var currentCell: HTMLElement | null = null, currentTable: HTMLElement | null = null;\n var lastCell: HTMLElement | null = null, lastTable: HTMLElement | null = null;\n var selectedCells: HTMLElement[] = [];\n\n function saveHist(){\n if(!ed._tableHist) ed._tableHist = {undo:[], redo:[]};\n ed._tableHist.undo.push(editor.innerHTML);\n ed._tableHist.redo = [];\n if(ed._tableHist.undo.length > 50) ed._tableHist.undo.shift();\n }\n\n function updateMergeBtn(){\n var btn = tools.querySelector('[data-te-table=\"merge\"]') as HTMLElement | null;\n if(!btn) return;\n btn.style.display = (selectedCells.length >= 2) ? '' : 'none';\n }\n\n function clearHighlights(){\n selectedCells.forEach(function(c){ c.classList.remove('te-cell-selected'); });\n selectedCells = [];\n updateMergeBtn();\n }\n\n function toggleHighlight(cell: HTMLElement){\n var idx = selectedCells.indexOf(cell);\n if(idx !== -1){\n selectedCells.splice(idx, 1);\n cell.classList.remove('te-cell-selected');\n } else {\n selectedCells.push(cell);\n cell.classList.add('te-cell-selected');\n }\n updateMergeBtn();\n }\n\n editor.addEventListener('click', function(e: MouseEvent){\n var cell = (e.target as HTMLElement).closest && (e.target as HTMLElement).closest('td,th') as HTMLElement | null;\n if(!cell || !editor.contains(cell)) return;\n if(e.ctrlKey || e.metaKey){\n e.preventDefault();\n toggleHighlight(cell);\n } else if(!e.shiftKey){\n clearHighlights();\n }\n });\n\n function updateUnmergeBtn(cell: HTMLElement){\n var btn = tools.querySelector('[data-te-table=\"unmerge\"]') as HTMLElement | null;\n if(!btn) return;\n var cs = parseInt(cell.getAttribute('colspan')!, 10) || 1;\n var rs = parseInt(cell.getAttribute('rowspan')!, 10) || 1;\n btn.style.display = (cs > 1 || rs > 1) ? '' : 'none';\n }\n\n function updateValignBtns(cell: HTMLElement){\n tools.querySelectorAll('[data-te-table^=\"valign-\"]').forEach(function(b){\n var align = b.getAttribute('data-te-table')!.replace('valign-', '');\n var cellAlign = ((cell as HTMLElement).style.verticalAlign || '').toLowerCase();\n b.classList.toggle('active', cellAlign === align);\n });\n }\n\n function posTools(cell: HTMLElement){\n var rect = cell.getBoundingClientRect();\n tools.style.display = 'flex';\n tools.style.visibility = 'hidden';\n var toolsW = tools.offsetWidth;\n var toolsH = tools.offsetHeight;\n var editorRect = editor.getBoundingClientRect();\n var sx = window.scrollX, sy = window.scrollY;\n\n var leftPos = rect.left + sx;\n var minLeft = editorRect.left + sx + 2;\n var maxLeft = editorRect.right + sx - toolsW - 2;\n if(leftPos < minLeft) leftPos = minLeft;\n if(leftPos > maxLeft) leftPos = maxLeft;\n tools.style.left = leftPos + 'px';\n\n var spaceBelow = editorRect.bottom - (rect.bottom + 6);\n var spaceAbove = rect.top - 6 - editorRect.top;\n var topPos;\n if(spaceBelow >= toolsH || spaceBelow >= spaceAbove){\n topPos = rect.bottom + 6 + sy;\n } else {\n topPos = rect.top - 6 - toolsH + sy;\n }\n var minTop = editorRect.top + sy + 2;\n var maxTop = editorRect.bottom + sy - toolsH - 2;\n if(topPos < minTop) topPos = minTop;\n if(topPos > maxTop) topPos = maxTop;\n tools.style.top = topPos + 'px';\n\n tools.style.visibility = '';\n updateMergeBtn();\n updateUnmergeBtn(cell);\n updateValignBtns(cell);\n var capBtn = tools.querySelector('[data-te-table=\"toggle-caption\"]') as HTMLElement | null;\n if(capBtn && currentTable) capBtn.classList.toggle('active', !!currentTable.querySelector('caption'));\n }\n function hideTools(){\n tools.style.display = 'none';\n currentCell = null;\n currentTable = null;\n }\n function updateFromSelection(){\n var sel = window.getSelection();\n if(!sel || sel.rangeCount === 0){ hideTools(); return; }\n var n: Node | null = sel.anchorNode;\n if(n && n.nodeType === 3) n = n.parentNode;\n if(!n || !wrapper.contains(n)){ hideTools(); return; }\n var cell = (n as HTMLElement).closest && (n as HTMLElement).closest('td,th') as HTMLElement | null;\n if(cell && editor.contains(cell)){\n currentCell = cell;\n currentTable = cell.closest('table') as HTMLElement | null;\n lastCell = currentCell;\n lastTable = currentTable;\n posTools(cell);\n } else {\n hideTools();\n }\n }\n\n function getSelectedCellsForTools(): HTMLElement[] | null {\n var h = tools.querySelectorAll('.te-cell-selected');\n if(h.length) return Array.prototype.slice.call(h);\n var s = window.getSelection();\n if(!s || s.rangeCount === 0) return null;\n var r = s.getRangeAt(0);\n var tbl = currentTable || lastTable;\n if(!tbl) return null;\n var cells: HTMLElement[] = [];\n tbl.querySelectorAll('td,th').forEach(function(c){\n if(r.intersectsNode(c)) cells.push(c as HTMLElement);\n });\n return cells.length ? cells : null;\n }\n\n function applyBgColor(value: string){\n var cells = getSelectedCellsForTools();\n if(!cells) return;\n for(var i = 0; i < cells.length; i++){\n cells[i].style.backgroundColor = value;\n }\n }\n\n function clearBgColor(){\n var cells = getSelectedCellsForTools();\n if(!cells) return;\n for(var i = 0; i < cells.length; i++){\n cells[i].style.backgroundColor = '';\n }\n }\n\n var bgInput = tools.querySelector('.te-bg-input') as HTMLInputElement | null;\n if(bgInput){\n bgInput.addEventListener('change', function(){\n if(currentCell || lastCell) applyBgColor(bgInput!.value);\n });\n }\n\n document.addEventListener('selectionchange', updateFromSelection);\n window.addEventListener('scroll', function(){ if(currentCell) posTools(currentCell!); });\n window.addEventListener('resize', function(){ if(currentCell) posTools(currentCell!); });\n\n function getCellIndex(cell: HTMLElement){\n var idx = 0, node: HTMLElement | null = cell;\n while(node && node.previousElementSibling){ idx++; node = node.previousElementSibling as HTMLElement; }\n return idx;\n }\n function forEachRow(table: HTMLElement, cb: (row: HTMLTableRowElement, sec: string) => void){\n ['thead','tbody'].forEach(function(sec){\n var s = table.querySelector(sec);\n if(s){\n Array.prototype.forEach.call((s as HTMLTableSectionElement).rows, function(row){ cb(row, sec); });\n }\n });\n }\n\n var refocus: ReturnType<typeof setTimeout> | null;\n\n function scheduleRefocus(){\n if(refocus) clearTimeout(refocus);\n refocus = setTimeout(function(){\n ctx.editor.focus();\n updateFromSelection();\n refocus = null;\n }, 0);\n }\n\n function mergeCells(){\n var table = currentTable || lastTable;\n if(!table) return;\n var rows = Array.prototype.slice.call(table.querySelectorAll('tr')) as HTMLTableRowElement[];\n if(!rows.length) return;\n\n var cells: HTMLElement[];\n if(selectedCells.length > 1){\n cells = selectedCells.slice();\n } else {\n var sel = window.getSelection();\n if(!sel || sel.rangeCount === 0) return;\n var range = sel.getRangeAt(0);\n cells = [];\n table.querySelectorAll('td,th').forEach(function(cell){\n if(range.intersectsNode(cell)) cells.push(cell as HTMLElement);\n });\n }\n if(cells.length < 2) return;\n saveHist();\n\n var positions = cells.map(function(cell){\n return {\n cell: cell,\n row: rows.indexOf(cell.parentElement as HTMLTableRowElement),\n col: getCellIndex(cell)\n };\n });\n\n var minRow = Math.min.apply(null, positions.map(function(p){ return p.row; }));\n var maxRow = Math.max.apply(null, positions.map(function(p){ return p.row; }));\n var minCol = Math.min.apply(null, positions.map(function(p){ return p.col; }));\n var maxCol = Math.max.apply(null, positions.map(function(p){ return p.col; }));\n\n if(minRow !== maxRow && minCol !== maxCol){\n var mergeBtn = tools.querySelector('[data-te-table=\"merge\"]') as HTMLElement | null;\n if(mergeBtn){\n mergeBtn.style.outline = '2px solid #dc3545';\n mergeBtn.style.outlineOffset = '1px';\n setTimeout(function(){ mergeBtn!.style.outline = ''; mergeBtn!.style.outlineOffset = ''; }, 600);\n }\n return;\n }\n\n var contents = cells.map(function(c){ return c.innerHTML; });\n var kept = positions.filter(function(p){ return p.row === minRow && p.col === minCol; })[0];\n if(!kept) kept = positions[0];\n\n cells.forEach(function(cell){\n if(cell !== kept.cell) cell.parentNode!.removeChild(cell);\n });\n\n kept.cell.setAttribute('colspan', String(maxCol - minCol + 1));\n kept.cell.setAttribute('rowspan', String(maxRow - minRow + 1));\n kept.cell.innerHTML = contents.join('');\n clearHighlights();\n }\n\n function unmergeCell(cell: HTMLElement){\n var colspan = parseInt(cell.getAttribute('colspan')!, 10) || 1;\n var rowspan = parseInt(cell.getAttribute('rowspan')!, 10) || 1;\n if(colspan === 1 && rowspan === 1) return;\n\n var tag = cell.tagName;\n var table = cell.closest('table') as HTMLElement;\n var rows = Array.prototype.slice.call(table.querySelectorAll('tr')) as HTMLTableRowElement[];\n var row = cell.parentElement as HTMLTableRowElement;\n var rowIdx = rows.indexOf(row);\n var colIdx = getCellIndex(cell);\n\n cell.removeAttribute('colspan');\n cell.removeAttribute('rowspan');\n cell.innerHTML = '<br>';\n\n var ref = cell.nextSibling;\n for(var c = 1; c < colspan; c++){\n var nc = document.createElement(tag);\n nc.innerHTML = '<br>';\n row.insertBefore(nc, ref);\n }\n\n for(var r = 1; r < rowspan; r++){\n var tr = rows[rowIdx + r];\n if(!tr) break;\n var insBefore = tr.cells[colIdx] || null;\n for(var c = 0; c < colspan; c++){\n var nc = document.createElement(tag);\n nc.innerHTML = '<br>';\n tr.insertBefore(nc, insBefore);\n }\n }\n }\n\n tools.addEventListener('mousedown', function(e: MouseEvent){\n var actionBtn = e.target && (e.target as HTMLElement).closest('[data-te-table]');\n var action = actionBtn && (actionBtn as HTMLElement).getAttribute('data-te-table');\n if(!action) return;\n e.preventDefault();\n var cell = currentCell || lastCell;\n var table = currentTable || lastTable;\n if(!cell || !table) return;\n saveHist();\n var row = cell.parentElement as HTMLTableRowElement;\n var colIdx = getCellIndex(cell);\n\n if(action === 'row-before' || action === 'row-after'){\n var newRow = row.cloneNode(true) as HTMLTableRowElement;\n Array.prototype.forEach.call(newRow.cells, function(td: HTMLTableCellElement){\n td.innerHTML = '<br>';\n td.removeAttribute('colspan');\n td.removeAttribute('rowspan');\n });\n if(action === 'row-before'){ row.parentNode!.insertBefore(newRow, row); }\n else { row.parentNode!.insertBefore(newRow, row.nextSibling); }\n scheduleRefocus();\n }\n else if(action === 'col-before' || action === 'col-after'){\n var after = (action === 'col-after');\n forEachRow(table, function(r, sec){\n var ref = r.cells[colIdx];\n var newCell = document.createElement((sec === 'thead') ? 'th' : 'td');\n newCell.innerHTML = '<br>';\n if(after && ref && ref.nextSibling){ r.insertBefore(newCell, ref.nextSibling); }\n else if(ref){ r.insertBefore(newCell, ref); }\n else { r.appendChild(newCell); }\n });\n scheduleRefocus();\n }\n else if(action === 'del-row'){\n row.parentNode!.removeChild(row);\n if(!table.querySelector('tr')){ table.parentNode!.removeChild(table); hideTools(); }\n else { scheduleRefocus(); }\n }\n else if(action === 'del-col'){\n forEachRow(table, function(r){ if(r.cells[colIdx]) r.deleteCell(colIdx); });\n var any = table.querySelector('tr') as HTMLTableRowElement | null;\n if(any && any.cells.length === 0){ table.parentNode!.removeChild(table); hideTools(); }\n else { scheduleRefocus(); }\n }\n else if(action === 'del-table'){ table.parentNode!.removeChild(table); hideTools(); }\n else if(action === 'bg-apply'){ applyBgColor(bgInput ? bgInput.value : '#ffffff'); scheduleRefocus(); }\n else if(action === 'bg-clear'){ clearBgColor(); scheduleRefocus(); }\n else if(action === 'valign-top' || action === 'valign-middle' || action === 'valign-bottom'){\n var cells = getSelectedCellsForTools();\n if(!cells || !cells.length) cells = [cell];\n var vAlign = action.replace('valign-', '');\n for(var vi = 0; vi < cells.length; vi++){ cells[vi].style.verticalAlign = vAlign; }\n scheduleRefocus();\n }\n else if(action === 'merge'){ mergeCells(); scheduleRefocus(); }\n else if(action === 'unmerge'){ unmergeCell(cell); scheduleRefocus(); }\n else if(action === 'toggle-header'){\n var thead = table.querySelector('thead') as HTMLTableSectionElement | null;\n if(thead){\n var tbody = table.querySelector('tbody') as HTMLTableSectionElement | null || (function(){\n var tb = document.createElement('tbody');\n table.appendChild(tb);\n return tb;\n })();\n Array.prototype.slice.call(thead.rows).forEach(function(hr: HTMLTableRowElement){\n var tr = document.createElement('tr');\n Array.prototype.forEach.call(hr.cells, function(hc: HTMLTableCellElement){\n var td = document.createElement('td');\n td.innerHTML = hc.innerHTML || '<br>';\n tr.appendChild(td);\n });\n tbody.insertBefore(tr, tbody.firstChild);\n });\n thead.parentNode!.removeChild(thead);\n } else {\n var tb = table.querySelector('tbody') as HTMLTableSectionElement | null;\n if(tb && tb.rows.length){\n var first = tb.rows[0];\n var newHead = document.createElement('thead');\n var trh = document.createElement('tr');\n Array.prototype.forEach.call(first.cells, function(td: HTMLTableCellElement){\n var th = document.createElement('th');\n th.innerHTML = td.innerHTML || '<br>';\n trh.appendChild(th);\n });\n newHead.appendChild(trh);\n table.insertBefore(newHead, tb);\n tb.removeChild(first);\n }\n }\n scheduleRefocus();\n }\n else if(action === 'toggle-caption'){\n var cap = table.querySelector('caption');\n if(cap){\n cap.parentNode!.removeChild(cap);\n } else {\n var caption = document.createElement('caption');\n caption.innerHTML = '<br>';\n caption.contentEditable = 'true';\n caption.style.captionSide = 'bottom';\n caption.style.textAlign = 'left';\n caption.style.padding = '4px 6px';\n caption.style.fontStyle = 'italic';\n caption.style.color = '#6c757d';\n table.insertBefore(caption, table.firstChild);\n setTimeout(function(){ caption.focus(); }, 0);\n }\n scheduleRefocus();\n }\n });\n },\n};\n\nexport default tableTools;\n","import type { Plugin, PluginContext } from '../types';\n\nconst hr: Plugin = {\n name: 'hr',\n order: 55,\n toolbarHTML: '<button type=\"button\" class=\"btn btn-sm btn-light\" title=\"Horizontal rule\" data-cmd=\"insertHR\"><i class=\"ti ti-minus\"></i></button>',\n css: '' +\n '.te-hr-popup {' +\n ' position: fixed; display: none; z-index: 3000;' +\n ' background: #fff; border: 1px solid #dee2e6;' +\n ' border-radius: .375rem; box-shadow: 0 6px 20px rgba(0,0,0,.15);' +\n ' padding: .5rem; white-space: nowrap;' +\n '}' +\n '.te-hr-popup .btn {' +\n ' padding: .15rem .4rem !important; font-size: 1rem !important; line-height: 1 !important;' +\n ' margin-right: 2px;' +\n '}' +\n '.te-hr-popup .btn.active { background: #e7f1ff; border-color: #b6d4fe; }' +\n '.te-hr-popup input[type=\"color\"] {' +\n ' width: 26px; height: 22px; padding: 1px; border: 1px solid #dee2e6;' +\n ' border-radius: 3px; cursor: pointer; vertical-align: middle;' +\n '}',\n init(ctx: PluginContext): void {\n if(!ctx.features.hr) return;\n var btn = ctx.wrapper.querySelector('[data-cmd=\"insertHR\"]');\n if(!btn) return;\n\n var popup = document.createElement('div');\n popup.className = 'te-hr-popup';\n popup.innerHTML = '' +\n '<button type=\"button\" class=\"btn btn-sm btn-light active\" data-te-hr=\"solid\" title=\"Solid\">━</button>' +\n '<button type=\"button\" class=\"btn btn-sm btn-light\" data-te-hr=\"dashed\" title=\"Dashed\">┅</button>' +\n '<button type=\"button\" class=\"btn btn-sm btn-light\" data-te-hr=\"dotted\" title=\"Dotted\">┈</button>' +\n '<input type=\"color\" class=\"te-hr-color\" value=\"#cccccc\" title=\"HR color\" />';\n document.body.appendChild(popup);\n\n var currentStyle = 'solid';\n var currentColor = '#cccccc';\n var savedRange: Range | null = null;\n\n function saveEditorRange(): void{\n var sel = window.getSelection();\n if(sel && sel.rangeCount > 0) savedRange = sel.getRangeAt(0).cloneRange();\n else savedRange = null;\n }\n\n function restoreEditorRange(): void{\n if(!savedRange) return;\n var sel = window.getSelection();\n sel!.removeAllRanges();\n sel!.addRange(savedRange);\n }\n\n function posPopup(): void{\n var br = (btn as HTMLElement).getBoundingClientRect();\n var pw = popup.offsetWidth || 200;\n var left = br.left + (br.width / 2) - (pw / 2);\n if(left < 4) left = 4;\n if(left + pw > window.innerWidth - 4) left = window.innerWidth - pw - 4;\n popup.style.left = left + 'px';\n popup.style.top = (br.bottom + 4) + 'px';\n }\n\n function insertHR(): void{\n ctx.editor.focus();\n restoreEditorRange();\n var style = 'border: none; border-top: 2px ' + currentStyle + ' ' + currentColor + '; margin: 1em 0;';\n document.execCommand('insertHTML', false, '<hr style=\"' + style + '\">');\n hidePopup();\n }\n\n function hidePopup(): void{ popup.style.display = 'none'; }\n function showPopup(): void{\n saveEditorRange();\n popup.style.display = 'block';\n posPopup();\n }\n\n btn.addEventListener('click', function(e: Event){\n (e as MouseEvent).preventDefault();\n (e as MouseEvent).stopPropagation();\n if(popup.style.display === 'block'){ hidePopup(); return; }\n showPopup();\n });\n\n popup.addEventListener('mousedown', function(e: MouseEvent){\n var opt = (e.target as HTMLElement).closest('[data-te-hr]');\n if(opt){\n e.preventDefault();\n currentStyle = opt.getAttribute('data-te-hr')!;\n popup.querySelectorAll('[data-te-hr]').forEach(function(b){ b.classList.remove('active'); });\n opt.classList.add('active');\n insertHR();\n return;\n }\n });\n\n popup.addEventListener('change', function(e: Event){\n var inp = (e.target as HTMLElement).closest('.te-hr-color');\n if(inp){\n currentColor = (inp as HTMLInputElement).value;\n insertHR();\n }\n });\n\n document.addEventListener('click', function(e: MouseEvent){\n if(popup.style.display !== 'block') return;\n if(!popup.contains(e.target as Node) && e.target !== btn && !(btn as HTMLElement).contains(e.target as Node)){\n hidePopup();\n }\n });\n\n window.addEventListener('scroll', function(){ if(popup.style.display === 'block') posPopup(); });\n window.addEventListener('resize', function(){ if(popup.style.display === 'block') posPopup(); });\n }\n};\n\nexport default hr;\n","import type { Plugin, PluginContext } from '../types';\n\nconst unlink: Plugin = {\n name: 'unlink',\n order: 58,\n toolbarHTML: '<button type=\"button\" class=\"btn btn-sm btn-light\" title=\"Remove link\" data-cmd=\"unlink\"><i class=\"ti ti-x\"></i></button>',\n init(ctx: PluginContext): void {\n if(!ctx.features.unlink) return;\n var btn = ctx.wrapper.querySelector('[data-cmd=\"unlink\"]');\n if(!btn) return;\n btn.addEventListener('click', function(){\n var sel = window.getSelection();\n if(!sel || sel.rangeCount === 0) return;\n var node: Node | null = sel.anchorNode;\n if(node && node.nodeType === 3) node = node.parentNode;\n var link = node && (node as HTMLElement).closest && (node as HTMLElement).closest('a') as HTMLAnchorElement | null;\n if(link){\n var parent = link.parentNode!;\n while(link.firstChild){ parent.insertBefore(link.firstChild, link); }\n parent.removeChild(link);\n } else {\n document.execCommand('unlink', false, undefined);\n }\n ctx.editor.focus();\n });\n }\n};\n\nexport default unlink;\n","import type { Plugin, PluginContext } from '../types';\n\nvar EMOJIS = '😀😃😄😁😆😅🤣😂🙂🙃😉😊😇🥰😍🤩😘😗😚😋😛😜🤪😝🤑🤗🤭🤫🤔🤐🤨😐😑😶😏😒🙄😬🤥😌😔😪🤤😴😷🤒🤕🤢🤮🤧🥵🥶🥴😵🤯🤠🥳🥸😎🤓🧐😕😟🙁😮😯😲😳🥺😦😧😨😰😥😢😭😱😖😣😞😓😩😫🥱😤😡😠🤬😈👿💀☠💩🤡👹👺👻👽👾🤖💋👋✋👌🤏🤞🤟🤘🤙👈👉👆🖕👍👎✊👊🤛🤜👏🙌👐🤲🤝🙏✍💅👂👃👣👀👅👄'.match(/.{1,2}/g) || [];\n\nvar EMOJI_NAMES: Record<string, string> = {\n '😀':'grinning laugh happy','😃':'grinning smile happy','😄':'grinning smile happy','😁':'beaming grin happy',\n '😆':'laughing grinning','🤣':'rolling floor laughing','😂':'tears joy laughing cry',\n '🙂':'slight smile','🙃':'upside down','😉':'winking wink',\n '😊':'blush smile happy','😇':'innocent halo angel',\n '🥰':'love heart smile','😍':'heart eyes love','🤩':'star struck',\n '😘':'kiss blowing heart','😗':'kissing kiss','😚':'kiss closed eyes',\n '😋':'savor tongue yum','😛':'tongue playful','😜':'wink tongue silly','🤪':'crazy wild','😝':'squint tongue',\n '🤑':'money tongue rich',\n '🤗':'hug open hands','🤭':'hand over mouth secret','🤫':'shush quiet silent',\n '🤔':'thinking think','🤐':'zipper mouth secret','🤨':'raised eyebrow suspicious',\n '😐':'neutral straight face','😑':'expressionless blank','😶':'no mouth silent',\n '😏':'smirk smug','😒':'unamified roll','🙄':'eye roll',\n '😬':'grimace awkward','🤥':'lying liar nose',\n '😌':'relieved relief','😔':'pensive sad','😪':'sleepy tired','🤤':'drooling drool','😴':'sleeping sleep zzz',\n '😷':'medical mask sick','🤒':'thermometer sick fever','🤕':'head bandage hurt',\n '🤢':'nauseous sick vomit','🤮':'vomiting sick','🤧':'sneeze sick',\n '🥵':'hot fever sweat','🥶':'cold freeze ice','🥴':'dizzy tipsy',\n '😵':'dizzy confused','🤯':'exploding head mind blown',\n '🤠':'cowboy hat','🥳':'party celebration','🥸':'disguise mask',\n '😎':'sunglasses cool','🤓':'nerd geek glasses','🧐':'monocle detective',\n '😕':'confused unsure','😟':'worried concern','🙁':'slight frown sad',\n '😮':'surprised shock','😯':'hushed surprise','😲':'astonished amazed','😳':'flushed embarrassed',\n '🥺':'pleading puppy eyes',\n '😦':'frown sad','😧':'anguish distressed','😨':'fearful afraid','😰':'anxious sweat worry',\n '😥':'disappointed sad','😢':'cry sad tear','😭':'sobbing cry tears',\n '😱':'scream fear horror','😖':'confounded frustrated','😣':'persevere struggle',\n '😞':'disappointed sad','😓':'downcast sweat','😩':'weary tired','😫':'tired exhausted','🥱':'yawn sleepy',\n '😤':'triumph frustrated steam','😡':'angry rage','😠':'angry mad','🤬':'cursing swear',\n '😈':'devil evil grin','👿':'devil evil angry','💀':'skull death','☠':'skull crossbones danger',\n '💩':'poop poo','🤡':'clown circus','👹':'ogre monster','👺':'goblin monster',\n '👻':'ghost halloween','👽':'alien ufo','👾':'alien monster space','🤖':'robot ai',\n '💋':'kiss lips',\n '👋':'wave hand hello bye','✋':'raised hand stop high five','👌':'ok perfect',\n '🤏':'pinching small little','🤞':'crossed fingers luck','🤟':'love gesture',\n '🤘':'horns rock metal','🤙':'call me phone',\n '👈':'point left','👉':'point right','👆':'point up','🖕':'middle finger fuck',\n '👍':'thumbs up like','👎':'thumbs down dislike',\n '✊':'fist raised power','👊':'fist punch','🤛':'fist left','🤜':'fist right',\n '👏':'clap applause','🙌':'raised hands celebration','👐':'open hands',\n '🤲':'palms together pray','🤝':'handshake deal agree','🙏':'folded hands pray please thank',\n '✍':'writing hand','💅':'nail polish care',\n '👂':'ear listen','👃':'nose smell','👣':'footsteps feet','👀':'eyes look','👅':'tongue taste','👄':'mouth lips'\n};\n\nconst emoji: Plugin = {\n name: 'emoji',\n order: 60,\n css: '' +\n '.te-emoji-popup {' +\n ' position: absolute; z-index: 3000;' +\n ' background: #fff; border: 1px solid #dee2e6;' +\n ' border-radius: .5rem; box-shadow: 0 6px 20px rgba(0,0,0,.15);' +\n ' padding: .4rem; max-width: 290px;' +\n '}' +\n '.te-emoji-popup .te-emoji-search {' +\n ' width: 100%; box-sizing: border-box;' +\n ' padding: .3rem .5rem; margin-bottom: .4rem;' +\n ' border: 1px solid #dee2e6; border-radius: .375rem;' +\n ' font-size: .8rem; outline: none;' +\n '}' +\n '.te-emoji-popup .te-emoji-search:focus {' +\n ' border-color: #86b7fe; box-shadow: 0 0 0 2px rgba(13,110,253,.15);' +\n '}' +\n '.te-emoji-popup .te-emoji-no-result {' +\n ' padding: 1rem; text-align: center; color: #6c757d; font-size: .8rem;' +\n '}' +\n '.te-emoji-popup .te-emoji-grid {' +\n ' display: grid; grid-template-columns: repeat(8, 1fr); gap: 2px;' +\n ' max-height: 220px; overflow-y: auto;' +\n '}' +\n '.te-emoji-popup .te-emoji-grid button {' +\n ' background: none; border: none; font-size: 1.3rem;' +\n ' padding: .25rem; cursor: pointer; border-radius: .25rem; text-align: center;' +\n '}' +\n '.te-emoji-popup .te-emoji-grid button:hover { background: #f0f0f0; }' +\n '.te-emoji-popup .te-emoji-grid button.hidden { display: none; }',\n toolbarHTML: '<button type=\"button\" class=\"btn btn-sm btn-light\" title=\"Emoji\" data-cmd=\"emoji\"><i class=\"ti ti-mood-smile\"></i></button>',\n init(ctx: PluginContext): void {\n if(!ctx.features.emoji) return;\n\n var popup = document.createElement('div');\n popup.className = 'te-emoji-popup';\n popup.style.display = 'none';\n popup.innerHTML = '<input type=\"text\" class=\"te-emoji-search\" placeholder=\"Search emoji...\" /><div class=\"te-emoji-grid\"></div><div class=\"te-emoji-no-result\" style=\"display:none\">No emoji found</div>';\n var grid = popup.querySelector('.te-emoji-grid') as HTMLElement;\n var search = popup.querySelector('.te-emoji-search') as HTMLInputElement;\n var noResult = popup.querySelector('.te-emoji-no-result') as HTMLElement;\n\n EMOJIS.forEach(function(emoji){\n var btn = document.createElement('button');\n btn.type = 'button';\n btn.textContent = emoji;\n btn.setAttribute('data-emoji', emoji);\n btn.title = EMOJI_NAMES[emoji] || '';\n grid.appendChild(btn);\n });\n document.body.appendChild(popup);\n\n var toolbarBtn = ctx.wrapper.querySelector('[data-cmd=\"emoji\"]') as HTMLElement | null;\n var savedRange: Range | null = null;\n\n function saveEditorRange(){\n var sel = window.getSelection();\n if(sel && sel.rangeCount > 0) savedRange = sel.getRangeAt(0).cloneRange();\n else savedRange = null;\n }\n\n function restoreEditorRange(){\n if(!savedRange) return;\n var sel = window.getSelection();\n sel!.removeAllRanges();\n sel!.addRange(savedRange);\n }\n\n function showPopup(){\n saveEditorRange();\n var rect = toolbarBtn!.getBoundingClientRect();\n popup.style.display = 'block';\n popup.style.visibility = 'hidden';\n var pw = popup.offsetWidth, ph = popup.offsetHeight;\n var sx = window.scrollX, sy = window.scrollY;\n var vw = window.innerWidth, vh = window.innerHeight;\n\n var left = rect.left + sx;\n if(left + pw > sx + vw - 8) left = sx + vw - pw - 8;\n if(left < sx + 4) left = sx + 4;\n popup.style.left = left + 'px';\n\n var top = rect.bottom + 4 + sy;\n if(top + ph > sy + vh - 8) top = rect.top - ph - 4 + sy;\n if(top < sy + 4) top = sy + 4;\n popup.style.top = top + 'px';\n\n popup.style.visibility = '';\n search.value = '';\n grid.querySelectorAll('button').forEach(function(b){ b.classList.remove('hidden'); });\n noResult.style.display = 'none';\n search.focus();\n }\n\n if(toolbarBtn){\n toolbarBtn.addEventListener('click', function(e: MouseEvent){\n if(popup.style.display !== 'none'){ popup.style.display = 'none'; return; }\n showPopup();\n });\n }\n\n search.addEventListener('input', function(){\n var q = search.value.trim().toLowerCase();\n var visible = 0;\n grid.querySelectorAll('button').forEach(function(b){\n var name = (EMOJI_NAMES[(b as HTMLButtonElement).textContent!] || '').toLowerCase();\n var match = !q || name.indexOf(q) !== -1;\n b.classList.toggle('hidden', !match);\n if(match) visible++;\n });\n noResult.style.display = visible ? 'none' : 'block';\n });\n\n search.addEventListener('keydown', function(e: KeyboardEvent){\n if(e.key === 'Escape'){ popup.style.display = 'none'; ctx.editor.focus(); }\n });\n\n popup.addEventListener('mousedown', function(e: MouseEvent){\n var btn = (e.target as HTMLElement).closest && (e.target as HTMLElement).closest('[data-emoji]');\n if(!btn) return;\n e.preventDefault();\n ctx.editor.focus();\n restoreEditorRange();\n document.execCommand('insertHTML', false, (btn as HTMLElement).textContent!);\n popup.style.display = 'none';\n });\n\n document.addEventListener('click', function(e: MouseEvent){\n if(popup.style.display === 'none') return;\n if(!popup.contains(e.target as Node) && e.target !== toolbarBtn){\n popup.style.display = 'none';\n }\n });\n }\n};\n\nexport default emoji;\n","import type { Plugin, PluginContext } from '../types';\n\nconst direction: Plugin = {\n name: 'direction',\n order: 61,\n toolbarHTML: '' +\n '<button type=\"button\" class=\"btn btn-sm btn-light\" title=\"Left to Right\" data-cmd=\"ltr\"><i class=\"ti ti-arrow-left\"></i> LTR</button>' +\n '<button type=\"button\" class=\"btn btn-sm btn-light\" title=\"Right to Left\" data-cmd=\"rtl\">RTL <i class=\"ti ti-arrow-right\"></i></button>',\n init(ctx: PluginContext): void {\n if (!ctx.features.direction) return;\n ctx.wrapper.querySelectorAll('[data-cmd=\"ltr\"],[data-cmd=\"rtl\"]').forEach(function (btn) {\n btn.addEventListener('click', function () {\n var dir = btn.getAttribute('data-cmd');\n document.execCommand('formatBlock', false, 'p');\n var sel = window.getSelection();\n if (sel && sel.rangeCount > 0) {\n var node: Node | null = sel.anchorNode;\n if (node && node.nodeType === 3) node = node.parentNode;\n var block = node && (node as Element).closest && (node as Element).closest('p,h1,h2,h3,h4,h5,h6,div');\n if (block && ctx.wrapper.contains(block)) {\n block.setAttribute('dir', dir!);\n }\n }\n ctx.editor.focus();\n });\n });\n }\n};\n\nexport default direction;\n","import type { Plugin, PluginContext } from '../types';\n\nconst source: Plugin = {\n name: 'source',\n order: 65,\n css: '' +\n '.te-source-toggle.active { background: #e7f1ff; border-color: #b6d4fe; }' +\n '.te-editor.te-source-mode { display: none; }' +\n '.te-source-textarea {' +\n ' width: 100%; min-height: 200px; border: 1px solid #dee2e6;' +\n ' border-radius: .375rem; padding: .75rem; resize: vertical;' +\n ' font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;' +\n ' font-size: .85rem; line-height: 1.6; display: none;' +\n '}',\n toolbarHTML: '<button type=\"button\" class=\"btn btn-sm btn-outline-secondary\" title=\"Toggle source\" data-cmd=\"editSource\"><i class=\"ti ti-source-code\"></i></button>',\n init(ctx: PluginContext): void {\n if(!ctx.features.source) return;\n\n var btn = ctx.wrapper.querySelector('[data-cmd=\"editSource\"]') as HTMLButtonElement | null;\n if(!btn) return;\n\n var ta = document.createElement('textarea');\n ta.className = 'te-source-textarea';\n ta.spellcheck = false;\n ctx.editor.parentNode!.insertBefore(ta, ctx.editor);\n\n var sourceMode = false;\n\n function formatSource(html: string): string {\n if(!html) return '';\n var out = String(html);\n var blockTags = ['p','h1','h2','h3','h4','h5','h6','blockquote','pre','li','tr','thead','tbody','tfoot','table','ul','ol'];\n blockTags.forEach(function(tag){\n var openRe = new RegExp('<' + tag + '(\\\\s[^>]*)?>', 'gi');\n var closeRe = new RegExp('</' + tag + '>', 'gi');\n out = out.replace(openRe, function(m){ return '\\n' + m; });\n out = out.replace(closeRe, function(m){ return m + '\\n'; });\n });\n out = out.replace(/\\n{2,}/g, '\\n');\n return out.trim();\n }\n\n function toggleSource(){\n sourceMode = !sourceMode;\n if(sourceMode){\n ta.value = formatSource(ctx.editor.innerHTML);\n ctx.editor.classList.add('te-source-mode');\n ta.style.display = 'block';\n ta.focus();\n } else {\n var safe = ctx.utils.sanitizeHTML ? ctx.utils.sanitizeHTML(ta.value, ctx.options.sanitize || {}) : ta.value;\n ctx.editor.innerHTML = safe;\n ctx.editor.classList.remove('te-source-mode');\n ta.style.display = 'none';\n ctx.editor.focus();\n }\n btn!.classList.toggle('active', sourceMode);\n var allControls = ctx.toolbar.querySelectorAll('[data-cmd], select, input');\n for(var i = 0; i < allControls.length; i++){\n if(allControls[i] === btn) continue;\n if(sourceMode){\n (allControls[i] as HTMLElement).setAttribute('disabled', 'disabled');\n (allControls[i] as HTMLElement).style.opacity = '.4';\n (allControls[i] as HTMLElement).style.pointerEvents = 'none';\n } else {\n (allControls[i] as HTMLElement).removeAttribute('disabled');\n (allControls[i] as HTMLElement).style.opacity = '';\n (allControls[i] as HTMLElement).style.pointerEvents = '';\n }\n }\n }\n\n btn.addEventListener('click', toggleSource);\n }\n};\n\nexport default source;\n","import type { Plugin, PluginContext } from '../types';\n\nconst history: Plugin = {\n name: 'history',\n order: 70,\n toolbarHTML: '' +\n '<button type=\"button\" class=\"btn btn-sm btn-light\" title=\"Undo\" data-cmd=\"undo\"><i class=\"ti ti-arrow-back-up\"></i></button>' +\n '<button type=\"button\" class=\"btn btn-sm btn-light\" title=\"Redo\" data-cmd=\"redo\"><i class=\"ti ti-arrow-forward-up\"></i></button>' +\n '<button type=\"button\" class=\"btn btn-sm btn-light\" title=\"Clear formatting\" data-cmd=\"removeFormat\"><i class=\"ti ti-trash\"></i></button>',\n init(ctx: PluginContext): void {\n },\n};\n\nexport default history;\n","import type { Plugin, PluginContext } from '../types';\n\nconst fullscreen: Plugin = {\n name: 'fullscreen',\n order: 75,\n css: '' +\n '.te-fullscreen {' +\n ' position: fixed; inset: 0; z-index: 9999;' +\n '}' +\n '.te-fullscreen .te-container {' +\n ' max-width: none; display: flex; flex-direction: column; height: 100%;' +\n '}' +\n '.te-fullscreen .te-container .te-editor {' +\n ' flex: 1; height: auto !important; min-height: 300px;' +\n '}' +\n '.te-fullscreen .te-container .te-toolbar {' +\n ' border-radius: 0;' +\n '}' +\n '.te-fullscreen .te-btn-fullscreen {' +\n ' background: #e7f1ff; border-color: #b6d4fe;' +\n '}',\n toolbarHTML: '<button type=\"button\" class=\"btn btn-sm btn-light te-btn-fullscreen\" title=\"Fullscreen\" data-cmd=\"fullscreen\"><i class=\"ti ti-maximize\"></i></button>',\n init(ctx: PluginContext): void {\n if (!ctx.features.fullscreen) return;\n var btn = ctx.wrapper.querySelector('[data-cmd=\"fullscreen\"]') as HTMLElement | null;\n if (!btn) return;\n btn.addEventListener('click', function () {\n var isFull = ctx.wrapper.classList.toggle('te-fullscreen');\n btn!.innerHTML = isFull ? '<i class=\"ti ti-minimize\"></i>' : '<i class=\"ti ti-maximize\"></i>';\n\n ctx.editor.focus();\n });\n }\n};\n\nexport default fullscreen;\n","import type { Plugin, PluginContext } from '../types';\n\nconst toolbarCollapse: Plugin = {\n name: 'toolbarCollapse',\n order: 1000,\n css: '' +\n '.te-toolbar .btn svg, .te-toolbar .btn i {' +\n ' width: 14px !important; height: 14px !important;' +\n ' vertical-align: middle;' +\n '}',\n init(ctx: PluginContext): void {}\n};\n\nexport default toolbarCollapse;\n","import type { Plugin, PluginContext } from '../types';\n\nvar STORAGE_PREFIX = 'te-autosave-';\n\nfunction getStorageKey(textarea: HTMLTextAreaElement): string {\n var id = textarea.id || textarea.name || textarea.className || '';\n return STORAGE_PREFIX + (id || Math.random().toString(36).slice(2, 8));\n}\n\nconst autosave: Plugin = {\n name: 'autosave',\n order: 210,\n css: '' +\n '.te-autosave-badge {' +\n ' font-size: .7rem; padding: 1px 6px; border-radius: 8px;' +\n ' line-height: 1.4; opacity: .6; margin-left: auto;' +\n '}' +\n '.te-autosave-badge.saved { background: #d1e7dd; color: #0f5132; }' +\n '.te-autosave-badge.unsaved { background: #fff3cd; color: #664d03; }',\n init(ctx: PluginContext): void {\n if(!ctx.features.autosave) return;\n\n var key = getStorageKey(ctx.textarea);\n\n try {\n var saved = localStorage.getItem(key);\n if(saved && saved !== ctx.editor.innerHTML){\n ctx.editor.innerHTML = saved;\n }\n } catch(_){}\n\n var badge = document.createElement('span');\n badge.className = 'te-autosave-badge saved';\n badge.textContent = 'Saved';\n var rightEl = ctx.wrapper.querySelector('.te-status-right') as HTMLElement | null;\n if(rightEl){\n rightEl.style.display = 'inline-flex';\n rightEl.style.alignItems = 'center';\n rightEl.style.gap = '8px';\n rightEl.appendChild(badge);\n }\n\n function setStatus(saved: boolean): void {\n badge.textContent = saved ? 'Saved' : 'Unsaved';\n badge.className = 'te-autosave-badge ' + (saved ? 'saved' : 'unsaved');\n }\n\n var saveTimer: ReturnType<typeof setTimeout> | null = null;\n function save(): void {\n setStatus(false);\n if(saveTimer) clearTimeout(saveTimer);\n saveTimer = setTimeout(function(){\n try {\n localStorage.setItem(key, ctx.editor.innerHTML);\n setStatus(true);\n } catch(_){}\n }, 500);\n }\n\n ctx.editor.addEventListener('input', save);\n ctx.editor.addEventListener('paste', save);\n\n ctx.editor.addEventListener('blur', function(){\n try { localStorage.removeItem(key); } catch(_){}\n });\n }\n};\n\nexport default autosave;\n","import type { Plugin, PluginContext } from '../types';\n\nvar URL_RE = /(?:https?:\\/\\/|www\\.)[^\\s<>\"'()]+(?:\\.[^\\s<>\"'()]+)*/gi;\n\nconst autoLinkify: Plugin = {\n name: 'autoLinkify',\n order: 1,\n init(ctx: PluginContext): void {\n if (ctx.features.autoLinkify === false) return;\n var editor = ctx.editor;\n\n editor.addEventListener('paste', function (e: ClipboardEvent) {\n var text = (e.clipboardData && e.clipboardData.getData('text/plain')) || '';\n if (!text) return;\n\n text = text.trim();\n\n if (URL_RE.test(text)) {\n URL_RE.lastIndex = 0;\n var url = text.match(URL_RE)![0];\n var fullUrl = url.indexOf('://') === -1 ? 'https://' + url : url;\n var isOk = ctx.utils.isSafeUrl ? ctx.utils.isSafeUrl(fullUrl, ctx.options.urlSchemes || ['http', 'https', 'mailto', 'tel']) : true;\n if (isOk) {\n e.preventDefault();\n e.stopImmediatePropagation();\n var html = '<p><a href=\"' + fullUrl.replace(/\"/g, '&quot;') + '\" target=\"_blank\" rel=\"noopener noreferrer\">' + url.replace(/</g, '&lt;').replace(/>/g, '&gt;') + '</a></p>';\n document.execCommand('insertHTML', false, html);\n }\n }\n }, true);\n }\n};\n\nexport default autoLinkify;\n","import type { Plugin, PluginContext } from '../types';\n\nconst caseTransform: Plugin = {\n name: 'caseTransform',\n order: 31,\n toolbarHTML: '' +\n '<select class=\"te-case form-select form-select-sm\" title=\"Change case\">' +\n ' <option value=\"\">Case</option>' +\n ' <option value=\"upper\">UPPERCASE</option>' +\n ' <option value=\"lower\">lowercase</option>' +\n ' <option value=\"title\">Title Case</option>' +\n ' <option value=\"sentence\">Sentence case</option>' +\n '</select>',\n init(ctx: PluginContext): void {\n if(ctx.features.caseTransform === false) return;\n var sel = ctx.wrapper.querySelector('.te-case') as HTMLSelectElement | null;\n if(!sel) return;\n\n sel.addEventListener('mousedown', function(){\n ctx.saveSel();\n });\n\n sel.addEventListener('change', function(){\n var v = sel!.value;\n sel!.value = '';\n if(!v) return;\n\n ctx.restoreSel();\n\n var s = window.getSelection();\n if(!s || s.isCollapsed || !s.rangeCount) return;\n var text = s.toString();\n if(!text) return;\n\n var transformed: string;\n switch(v){\n case 'upper': transformed = text.toUpperCase(); break;\n case 'lower': transformed = text.toLowerCase(); break;\n case 'title':\n transformed = text.toLowerCase().replace(/\\b\\w/g, function(m){ return m.toUpperCase(); });\n break;\n case 'sentence':\n transformed = text.charAt(0).toUpperCase() + text.slice(1).toLowerCase().replace(/([.!?]\\s+)(\\w)/g, function(m){ return m.toUpperCase(); });\n break;\n default: return;\n }\n\n document.execCommand('insertText', false, transformed);\n ctx.editor.focus();\n });\n }\n};\n\nexport default caseTransform;\n","import type { Plugin, PluginContext } from '../types';\n\nconst shortcutsHelp: Plugin = {\n name: 'shortcutsHelp',\n order: 90,\n css: '' +\n '.te-shortcuts-table { width: 100%; border-collapse: collapse; font-size: .875rem; }' +\n '.te-shortcuts-table th, .te-shortcuts-table td { padding: .4rem .75rem; border-bottom: 1px solid #e9ecef; text-align: left; color: #000; }' +\n '.te-shortcuts-table th { background: #f8f9fa; font-weight: 600; }' +\n '.te-shortcuts-table kbd { display: inline-block; padding: 2px 6px; font-size: .75rem; font-family: monospace; background: #f0f0f0; border: 1px solid #d0d0d0; border-radius: 3px; color: #000; }',\n toolbarHTML: '<button type=\"button\" class=\"btn btn-sm btn-light\" title=\"Keyboard shortcuts\" data-cmd=\"shortcutsHelp\"><i class=\"ti ti-help-circle\"></i></button>',\n modalHTML: '' +\n '<div class=\"te-shortcuts-modal te-modal\" aria-hidden=\"true\">' +\n ' <div class=\"te-modal-backdrop\" data-te-close></div>' +\n ' <div class=\"te-modal-dialog\">' +\n ' <div class=\"te-modal-header\">' +\n ' <h5 class=\"te-modal-title m-0\">Keyboard Shortcuts</h5>' +\n ' <button type=\"button\" class=\"btn-close\" data-te-close aria-label=\"Close\"></button>' +\n ' </div>' +\n ' <div class=\"te-modal-body\">' +\n ' <table class=\"te-shortcuts-table\">' +\n ' <thead><tr><th>Shortcut</th><th>Action</th></tr></thead>' +\n ' <tbody>' +\n ' <tr><td><kbd>Ctrl</kbd> + <kbd>B</kbd></td><td>Bold</td></tr>' +\n ' <tr><td><kbd>Ctrl</kbd> + <kbd>I</kbd></td><td>Italic</td></tr>' +\n ' <tr><td><kbd>Ctrl</kbd> + <kbd>U</kbd></td><td>Underline</td></tr>' +\n ' <tr><td><kbd>Ctrl</kbd> + <kbd>S</kbd></td><td>Strikethrough</td></tr>' +\n ' <tr><td><kbd>Ctrl</kbd> + <kbd>Z</kbd></td><td>Undo</td></tr>' +\n ' <tr><td><kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>Z</kbd></td><td>Redo</td></tr>' +\n ' <tr><td><kbd>Ctrl</kbd> + <kbd>Y</kbd></td><td>Redo</td></tr>' +\n ' <tr><td><kbd>Ctrl</kbd> + <kbd>K</kbd></td><td>Insert link</td></tr>' +\n ' <tr><td><kbd>Tab</kbd></td><td>Indent list item</td></tr>' +\n ' <tr><td><kbd>Shift</kbd> + <kbd>Tab</kbd></td><td>Outdent list item</td></tr>' +\n ' </tbody>' +\n ' </table>' +\n ' </div>' +\n ' </div>' +\n '</div>',\n init(ctx: PluginContext): void {\n if(ctx.features.shortcutsHelp === false) return;\n var btn = ctx.wrapper.querySelector('[data-cmd=\"shortcutsHelp\"]');\n if(btn){\n btn.addEventListener('click', function(){\n var m = ctx.wrapper.querySelector('.te-shortcuts-modal');\n if(m) m.classList.add('is-open');\n });\n }\n }\n};\n\nexport default shortcutsHelp;\n","import type { Plugin, PluginContext } from '../types';\n\nconst floatingToolbar: Plugin = {\n name: 'floatingToolbar',\n order: 58,\n css: '' +\n '.te-float-toolbar {' +\n ' position: fixed; display: none; z-index: 3100;' +\n ' background: #fff; border: 1px solid #dee2e6;' +\n ' border-radius: .375rem; box-shadow: 0 6px 20px rgba(0,0,0,.15);' +\n ' padding: .2rem; gap: 2px; align-items: center;' +\n ' white-space: nowrap;' +\n '}' +\n '.te-float-toolbar .btn {' +\n ' padding: .2rem .4rem !important; font-size: .75rem !important; line-height: 1 !important;' +\n '}' +\n '.te-float-toolbar .btn i,' +\n '.te-float-toolbar .btn svg {' +\n ' width: 13px !important; height: 13px !important;' +\n ' pointer-events: none;' +\n '}' +\n '.te-float-link-input {' +\n ' position: fixed; display: none; z-index: 3101;' +\n ' background: #fff; border: 1px solid #dee2e6;' +\n ' border-radius: .375rem; box-shadow: 0 6px 20px rgba(0,0,0,.15);' +\n ' padding: .35rem; gap: .25rem; align-items: center;' +\n ' white-space: nowrap;' +\n '}' +\n '.te-float-link-input input {' +\n ' width: 220px; padding: .2rem .4rem; font-size: .8rem;' +\n ' border: 1px solid #dee2e6; border-radius: .25rem; outline: none;' +\n '}' +\n '.te-float-link-input input:focus {' +\n ' border-color: #86b7fe; box-shadow: 0 0 0 2px rgba(13,110,253,.15);' +\n '}' +\n '.te-float-link-input .btn {' +\n ' padding: .2rem .5rem !important; font-size: .75rem !important; line-height: 1 !important;' +\n '}',\n init(ctx: PluginContext): void {\n if(!ctx.features.floatingToolbar) return;\n\n var editor = ctx.editor;\n var tools = document.createElement('div');\n tools.className = 'te-float-toolbar';\n tools.innerHTML = '' +\n '<button type=\"button\" class=\"btn btn-sm btn-light\" data-te-float=\"bold\" title=\"Bold\"><i class=\"ti ti-bold\"></i></button>' +\n '<button type=\"button\" class=\"btn btn-sm btn-light\" data-te-float=\"italic\" title=\"Italic\"><i class=\"ti ti-italic\"></i></button>' +\n '<button type=\"button\" class=\"btn btn-sm btn-light\" data-te-float=\"underline\" title=\"Underline\"><i class=\"ti ti-underline\"></i></button>' +\n '<span class=\"te-divider-v\" style=\"display:inline-block;width:1px;height:14px;background:#dee2e6;margin:0 2px;vertical-align:middle\"></span>' +\n '<button type=\"button\" class=\"btn btn-sm btn-light te-float-fore\" title=\"Text color\" style=\"position:relative;padding:.15rem .35rem!important;min-width:22px;text-align:center\"><span class=\"te-float-cp\" style=\"display:block;font-size:.8rem;line-height:1\">A<span style=\"display:block;height:2px;border-radius:1px;margin-top:1px;background:#000\"></span></span><input type=\"color\" class=\"te-float-fore-input\" value=\"#000000\" style=\"position:absolute;top:0;left:0;width:100%;height:100%;opacity:0;cursor:pointer;border:none;padding:0\"></button>' +\n '<button type=\"button\" class=\"btn btn-sm btn-light te-float-back\" title=\"Background color\" style=\"position:relative;padding:.15rem .35rem!important;min-width:22px;text-align:center\"><span class=\"te-float-cp\" style=\"display:block;font-size:.8rem;line-height:1\">A<span style=\"display:block;height:2px;border-radius:1px;margin-top:1px;background:#ffff00\"></span></span><input type=\"color\" class=\"te-float-back-input\" value=\"#ffff00\" style=\"position:absolute;top:0;left:0;width:100%;height:100%;opacity:0;cursor:pointer;border:none;padding:0\"></button>' +\n '<span class=\"te-divider-v\" style=\"display:inline-block;width:1px;height:14px;background:#dee2e6;margin:0 2px;vertical-align:middle\"></span>' +\n '<button type=\"button\" class=\"btn btn-sm btn-light\" data-te-float=\"link\" title=\"Insert link\"><i class=\"ti ti-link\"></i></button>' +\n '<span class=\"te-divider-v\" style=\"display:inline-block;width:1px;height:14px;background:#dee2e6;margin:0 2px;vertical-align:middle\"></span>' +\n '<button type=\"button\" class=\"btn btn-sm btn-light\" data-te-float=\"removeFormat\" title=\"Clear formatting\"><i class=\"ti ti-clear-formatting\"></i></button>';\n document.body.appendChild(tools);\n\n var linkInput = document.createElement('div');\n linkInput.className = 'te-float-link-input';\n linkInput.innerHTML = '' +\n '<input type=\"url\" class=\"te-float-link-url\" placeholder=\"https://example.com\" />' +\n '<button type=\"button\" class=\"btn btn-sm btn-primary\" data-te-float-link=\"apply\">Apply</button>' +\n '<button type=\"button\" class=\"btn btn-sm btn-light\" data-te-float-link=\"cancel\">Cancel</button>';\n document.body.appendChild(linkInput);\n\n var foreInput = tools.querySelector('.te-float-fore-input') as HTMLInputElement | null;\n var backInput = tools.querySelector('.te-float-back-input') as HTMLInputElement | null;\n\n if(foreInput){\n foreInput.addEventListener('change', function(){\n editor.focus();\n restoreRange();\n document.execCommand('foreColor', false, (foreInput as HTMLInputElement).value);\n var preview = tools.querySelector('.te-float-fore .te-float-cp') as HTMLElement | null;\n if(preview) preview.style.color = (foreInput as HTMLInputElement).value;\n hideTools();\n });\n }\n\n if(backInput){\n backInput.addEventListener('change', function(){\n editor.focus();\n restoreRange();\n try{ document.execCommand('hiliteColor', false, (backInput as HTMLInputElement).value); }\n catch(e){ document.execCommand('backColor', false, (backInput as HTMLInputElement).value); }\n var bar = tools.querySelector('.te-float-back .te-float-cp span:last-child') as HTMLElement | null;\n if(bar) bar.style.background = (backInput as HTMLInputElement).value;\n hideTools();\n });\n }\n\n var hideTimer: ReturnType<typeof setTimeout> | null = null;\n var isVisible = false;\n var savedRange: Range | null = null;\n\n function saveRange(){\n var sel = window.getSelection();\n if(sel && sel.rangeCount > 0) savedRange = sel.getRangeAt(0).cloneRange();\n else savedRange = null;\n }\n\n function restoreRange(){\n if(!savedRange) return;\n var sel = window.getSelection()!;\n sel.removeAllRanges();\n sel.addRange(savedRange);\n }\n\n function posTools(x: number, y: number, rect: DOMRect | null){\n var tw = tools.offsetWidth || 100;\n var th = tools.offsetHeight || 30;\n var er = editor.getBoundingClientRect();\n var left = x - tw / 2;\n if(left < er.left) left = er.left;\n if(left + tw > er.right) left = er.right - tw;\n var spaceAbove = rect ? rect.top - er.top : y - er.top;\n var spaceBelow = rect ? er.bottom - rect.bottom : er.bottom - y;\n var top;\n if(spaceAbove >= th + 8){\n top = (rect ? rect.top : y) - th - 8;\n } else if(spaceBelow >= th + 8){\n top = (rect ? rect.bottom : y) + 8;\n } else {\n top = spaceAbove > spaceBelow ? er.top + 2 : er.bottom - th - 2;\n }\n tools.style.left = left + 'px';\n tools.style.top = top + 'px';\n }\n\n function hideTools(){\n isVisible = false;\n linkInput.style.display = 'none';\n tools.style.display = 'none';\n }\n\n function showTools(x: number, y: number, rect: DOMRect | null){\n isVisible = true;\n tools.style.display = 'flex';\n posTools(x, y, rect);\n saveRange();\n }\n\n function showLinkInput(){\n saveRange();\n var er = editor.getBoundingClientRect();\n var toolsRect = tools.getBoundingClientRect();\n linkInput.style.display = 'flex';\n linkInput.style.visibility = 'hidden';\n var liw = linkInput.offsetWidth || 320;\n var lih = linkInput.offsetHeight || 32;\n var left = toolsRect.left + toolsRect.width / 2 - liw / 2;\n if(left < er.left) left = er.left;\n if(left + liw > er.right) left = er.right - liw;\n linkInput.style.left = left + 'px';\n var spaceBelow = window.innerHeight - toolsRect.bottom;\n linkInput.style.top = ((spaceBelow >= lih + 4) ? (toolsRect.bottom + 4) : (toolsRect.top - lih - 4)) + 'px';\n linkInput.style.visibility = '';\n (linkInput.querySelector('.te-float-link-url') as HTMLInputElement).value = '';\n (linkInput.querySelector('.te-float-link-url') as HTMLInputElement).focus();\n }\n\n editor.addEventListener('mouseup', function(e: MouseEvent){\n if(editor.contentEditable !== 'true') return;\n if(hideTimer) clearTimeout(hideTimer);\n var sel = window.getSelection();\n if(!sel || sel.isCollapsed || !sel.toString().trim()){\n hideTools();\n return;\n }\n if(!editor.contains(sel.anchorNode) || !editor.contains(sel.focusNode)){\n hideTools();\n return;\n }\n var range = sel.getRangeAt(0);\n var rect = range.getBoundingClientRect();\n var x = rect.left + rect.width / 2;\n showTools(x, 0, rect);\n });\n\n editor.addEventListener('mousedown', function(){\n if(hideTimer) clearTimeout(hideTimer);\n hideTimer = setTimeout(function(){ hideTools(); }, 200);\n });\n\n editor.addEventListener('keydown', function(){\n hideTools();\n });\n\n editor.addEventListener('scroll', function(){\n if(isVisible) hideTools();\n });\n\n tools.addEventListener('mousedown', function(e: MouseEvent){\n e.preventDefault();\n var actionBtn = (e.target as HTMLElement).closest('[data-te-float]');\n if(!actionBtn) return;\n var action = actionBtn.getAttribute('data-te-float');\n if(!action) return;\n\n if(action === 'link'){\n showLinkInput();\n return;\n }\n\n editor.focus();\n var sel = window.getSelection();\n if(!sel || sel.rangeCount === 0) return;\n document.execCommand(action, false, undefined);\n hideTools();\n });\n\n linkInput.addEventListener('mousedown', function(e: MouseEvent){\n e.preventDefault();\n var actionBtn = (e.target as HTMLElement).closest('[data-te-float-link]');\n if(!actionBtn) return;\n var action = actionBtn.getAttribute('data-te-float-link');\n\n if(action === 'cancel'){\n hideTools();\n return;\n }\n\n if(action === 'apply'){\n var url = (linkInput.querySelector('.te-float-link-url') as HTMLInputElement).value.trim();\n if(!url) return;\n editor.focus();\n restoreRange();\n if (!/^https?:\\/\\//i.test(url) && !/^mailto:/i.test(url) && !/^tel:/i.test(url)) url = 'https://' + url;\n document.execCommand('createLink', false, url);\n hideTools();\n }\n });\n\n linkInput.addEventListener('keydown', function(e: KeyboardEvent){\n if(e.key === 'Enter'){\n e.preventDefault();\n var url = (linkInput.querySelector('.te-float-link-url') as HTMLInputElement).value.trim();\n if(!url) return;\n editor.focus();\n restoreRange();\n if (!/^https?:\\/\\//i.test(url) && !/^mailto:/i.test(url) && !/^tel:/i.test(url)) url = 'https://' + url;\n document.execCommand('createLink', false, url);\n hideTools();\n }\n if(e.key === 'Escape'){\n hideTools();\n }\n });\n\n document.addEventListener('mousedown', function(e: MouseEvent){\n if(isVisible && !tools.contains(e.target as Node) && !linkInput.contains(e.target as Node) && e.target !== editor && !editor.contains(e.target as Node)){\n hideTools();\n }\n });\n }\n};\n\nexport default floatingToolbar;\n","import type { Plugin, PluginContext } from '../types';\n\nconst darkMode: Plugin = {\n name: 'darkMode',\n order: 59,\n toolbarHTML: '<button type=\"button\" class=\"btn btn-sm btn-light\" title=\"Toggle dark mode\" data-cmd=\"toggleDark\"><i class=\"ti ti-moon\"></i></button>',\n css: '' +\n '.te-container.te-dark {' +\n ' color-scheme: dark;' +\n '}' +\n '.te-container.te-dark .te-toolbar {' +\n ' background: #1e1e1e; border-color: #444;' +\n '}' +\n '.te-container.te-dark .te-toolbar .btn {' +\n ' color: #ccc; border-color: #555; background: #2a2a2a;' +\n '}' +\n '.te-container.te-dark .te-toolbar .btn:hover {' +\n ' background: #333; color: #fff;' +\n '}' +\n '.te-container.te-dark .te-toolbar .btn.active {' +\n ' background: #0d6efd; color: #fff; border-color: #0d6efd;' +\n '}' +\n '.te-container.te-dark .te-editor {' +\n ' background: #121212; border-color: #444; color: #e0e0e0;' +\n '}' +\n '.te-container.te-dark .te-editor:focus {' +\n ' box-shadow: inset 0 0 0 2px rgba(13,110,253,.5);' +\n '}' +\n '.te-container.te-dark .te-editor[placeholder]:empty:before {' +\n ' color: #666;' +\n '}' +\n '.te-container.te-dark .te-divider {' +\n ' background: #444;' +\n '}' +\n '.te-container.te-dark .te-status {' +\n ' color: #999;' +\n '}' +\n '.te-container.te-dark .te-modal-dialog {' +\n ' background: #1e1e1e; color: #e0e0e0; box-shadow: 0 20px 60px rgba(0,0,0,.5);' +\n '}' +\n '.te-container.te-dark .te-modal-header,' +\n '.te-container.te-dark .te-modal-footer {' +\n ' background: #2a2a2a; border-color: #444;' +\n '}' +\n '.te-container.te-dark .te-modal-header .te-modal-title {' +\n ' color: #e0e0e0;' +\n '}' +\n '.te-container.te-dark .te-modal-body {' +\n ' color: #e0e0e0;' +\n '}' +\n '.te-container.te-dark .btn-close {' +\n ' filter: invert(1);' +\n '}' +\n '.te-container.te-dark .te-modal .btn-primary {' +\n ' background: #555; border-color: #555; color: #fff;' +\n '}' +\n '.te-container.te-dark .te-modal .btn-primary:hover {' +\n ' background: #777; border-color: #777;' +\n '}' +\n '.te-container.te-dark .te-modal .btn-outline-secondary {' +\n ' color: #ccc; border-color: #555;' +\n '}' +\n '.te-container.te-dark .te-modal .btn-outline-secondary:hover {' +\n ' background: #333; border-color: #777;' +\n '}' +\n '.te-container.te-dark .te-modal .btn-outline-danger {' +\n ' color: #e57373; border-color: #e57373;' +\n '}' +\n '.te-container.te-dark .te-modal .btn-outline-danger:hover {' +\n ' background: #C1272D; border-color: #C1272D; color: #fff;' +\n '}' +\n '.te-container.te-dark .form-control {' +\n ' background: #2a2a2a; border-color: #555; color: #e0e0e0;' +\n '}' +\n '.te-container.te-dark .form-select {' +\n ' background: #2a2a2a; border-color: #555; color: #e0e0e0;' +\n '}' +\n '.te-container.te-dark .te-table-tools {' +\n ' background: #1e1e1e; border-color: #444;' +\n '}' +\n '.te-container.te-dark .te-table-tools .btn {' +\n ' color: #ccc; border-color: #555; background: #2a2a2a;' +\n '}' +\n '.te-container.te-dark .te-table-tools .tt-label {' +\n ' color: #999;' +\n '}' +\n '.te-container.te-dark .te-image-tools {' +\n ' background: #1e1e1e; border-color: #444;' +\n '}' +\n '.te-container.te-dark .te-image-tools .btn {' +\n ' color: #ccc; border-color: #555; background: #2a2a2a;' +\n '}' +\n '.te-container.te-dark .te-float-toolbar {' +\n ' background: #1e1e1e; border-color: #444;' +\n '}' +\n '.te-container.te-dark .te-float-toolbar .btn {' +\n ' color: #ccc; border-color: #555; background: #2a2a2a;' +\n '}' +\n '.te-container.te-dark .te-hr-popup {' +\n ' background: #1e1e1e; border-color: #444;' +\n '}' +\n '.te-container.te-dark .te-hr-popup .btn {' +\n ' color: #ccc; border-color: #555; background: #2a2a2a;' +\n '}',\n init(ctx: PluginContext): void {\n if(!ctx.features.darkMode) return;\n var btn = ctx.wrapper.querySelector('[data-cmd=\"toggleDark\"]');\n if(!btn) return;\n\n btn.addEventListener('click', function(){\n var container = ctx.wrapper.querySelector('.te-container');\n if(!container) return;\n var isDark = container.classList.toggle('te-dark');\n var icon = btn!.querySelector('.ti');\n if(icon){\n icon.className = 'ti ' + (isDark ? 'ti-sun' : 'ti-moon');\n }\n (btn as HTMLElement).classList.toggle('active', isDark);\n });\n }\n};\n\nexport default darkMode;\n","import type { Plugin, PluginContext } from '../types';\n\nvar STORAGE_KEY = 'te-shortcut-map';\n\nvar DEFAULT_MAP: Record<string, {key: string; ctrl: boolean; shift: boolean}> = {\n 'Bold': {key:'b', ctrl:true, shift:false},\n 'Italic': {key:'i', ctrl:true, shift:false},\n 'Underline': {key:'u', ctrl:true, shift:false},\n 'Strike': {key:'s', ctrl:true, shift:false},\n 'Undo': {key:'z', ctrl:true, shift:false},\n 'Redo': {key:'z', ctrl:true, shift:true},\n 'RedoAlt': {key:'y', ctrl:true, shift:false},\n 'Link': {key:'k', ctrl:true, shift:false}\n};\n\nfunction loadMap(): Record<string, {key: string; ctrl: boolean; shift: boolean}>{\n try {\n var raw = localStorage.getItem(STORAGE_KEY);\n if(raw) return JSON.parse(raw);\n } catch(_){}\n return JSON.parse(JSON.stringify(DEFAULT_MAP));\n}\n\nfunction saveMap(map: Record<string, {key: string; ctrl: boolean; shift: boolean}>): void{\n try { localStorage.setItem(STORAGE_KEY, JSON.stringify(map)); } catch(_){}\n}\n\nfunction esc(s: string): string{ return String(s).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/\"/g,'&quot;'); }\n\nconst shortcutCustomizer: Plugin = {\n name: 'shortcutCustomizer',\n order: 6,\n toolbarHTML: '<button type=\"button\" class=\"btn btn-sm btn-light\" title=\"Customize shortcuts\" data-cmd=\"customizeShortcuts\"><i class=\"ti ti-edit\"></i></button>',\n modalHTML: '' +\n '<div class=\"te-modal\" data-te-modal=\"shortcutCustomizer\">' +\n ' <div class=\"te-modal-backdrop\" data-te-close></div>' +\n ' <div class=\"te-modal-dialog\" style=\"width:420px\">' +\n ' <div class=\"te-modal-header\"><strong>Customize Shortcuts</strong><button type=\"button\" class=\"btn-close\" data-te-close></button></div>' +\n ' <div class=\"te-modal-body te-shortcut-body\"></div>' +\n ' <div class=\"te-modal-footer\">' +\n ' <button type=\"button\" class=\"btn btn-sm btn-secondary\" data-te-sc-reset>Reset</button>' +\n ' <button type=\"button\" class=\"btn btn-sm btn-secondary\" data-te-close>Close</button>' +\n ' <button type=\"button\" class=\"btn btn-sm btn-primary\" data-te-shortcut-save>Save</button>' +\n ' </div>' +\n ' </div>' +\n '</div>',\n css: '' +\n '.te-shortcut-body table { width: 100%; border-collapse: collapse; }' +\n '.te-shortcut-body td, .te-shortcut-body th { padding: 4px 8px; border-bottom: 1px solid #dee2e6; text-align: left; font-size: .85rem; }' +\n '.te-shortcut-body th { font-weight: 600; color: #495057; }' +\n '.te-shortcut-body input[type=\"text\"] { width: 40px; padding: 2px 6px; border: 1px solid #dee2e6; border-radius: 3px; font-size: .85rem; }' +\n '.te-shortcut-body input[type=\"text\"]:focus { outline: none; border-color: #86b7fe; box-shadow: 0 0 0 2px rgba(13,110,253,.25); }' +\n '.te-shortcut-body label { font-size: .8rem; margin-left: 4px; }',\n init(ctx: PluginContext): void {\n if(!ctx.features.shortcutCustomizer) return;\n var btn = ctx.wrapper.querySelector('[data-cmd=\"customizeShortcuts\"]');\n if(!btn) return;\n\n btn.addEventListener('click', function(){\n var modal = ctx.wrapper.querySelector('[data-te-modal=\"shortcutCustomizer\"]');\n if(!modal) return;\n var body = modal.querySelector('.te-shortcut-body');\n if(!body) return;\n\n var map = loadMap();\n var names = ['Bold','Italic','Underline','Strike','Undo','Redo','RedoAlt','Link'];\n var html = '<table><tr><th>Action</th><th>Shortcut</th></tr>';\n for(var i = 0; i < names.length; i++){\n var n = names[i];\n var s = map[n] || {key:'', ctrl:true, shift:false};\n var label = n === 'RedoAlt' ? 'Redo (alt)' : n;\n html += '<tr><td>' + label + '</td><td>' +\n 'Ctrl <input type=\"checkbox\" data-ctrl=\"' + n + '\" ' + (s.ctrl ? 'checked' : '') + ' />' +\n ' Shift <input type=\"checkbox\" data-shift=\"' + n + '\" ' + (s.shift ? 'checked' : '') + ' />' +\n ' <input type=\"text\" class=\"te-sc-input\" data-action=\"' + n + '\" value=\"' + esc(s.key) + '\" placeholder=\"key\" maxlength=\"1\" />' +\n '</td></tr>';\n }\n html += '</table>';\n body.innerHTML = html;\n modal.classList.add('is-open');\n });\n\n ctx.wrapper.addEventListener('click', function(e: MouseEvent){\n var saveBtn = (e.target as HTMLElement).closest('[data-te-shortcut-save]');\n if(!saveBtn) return;\n var modal = ctx.wrapper.querySelector('[data-te-modal=\"shortcutCustomizer\"]');\n if(!modal) return;\n var map: Record<string, {key: string; ctrl: boolean; shift: boolean}> = {};\n modal.querySelectorAll('.te-sc-input').forEach(function(inp){\n var action = inp.getAttribute('data-action');\n var key = (inp as HTMLInputElement).value.trim().toLowerCase();\n var ctrl = (modal!.querySelector('[data-ctrl=\"' + action + '\"]') as HTMLInputElement).checked;\n var shift = (modal!.querySelector('[data-shift=\"' + action + '\"]') as HTMLInputElement).checked;\n if(key) map[action!] = {key:key, ctrl:ctrl, shift:shift};\n });\n saveMap(map);\n modal.classList.remove('is-open');\n });\n\n ctx.wrapper.addEventListener('click', function(e: MouseEvent){\n var resetBtn = (e.target as HTMLElement).closest('[data-te-sc-reset]');\n if(!resetBtn) return;\n var modal = ctx.wrapper.querySelector('[data-te-modal=\"shortcutCustomizer\"]');\n if(!modal) return;\n saveMap(JSON.parse(JSON.stringify(DEFAULT_MAP)));\n var body = modal.querySelector('.te-shortcut-body');\n var names = ['Bold','Italic','Underline','Strike','Undo','Redo','RedoAlt','Link'];\n var html = '<table><tr><th>Action</th><th>Shortcut</th></tr>';\n for(var i = 0; i < names.length; i++){\n var n = names[i];\n var s = DEFAULT_MAP[n];\n var label = n === 'RedoAlt' ? 'Redo (alt)' : n;\n html += '<tr><td>' + label + '</td><td>' +\n 'Ctrl <input type=\"checkbox\" data-ctrl=\"' + n + '\" ' + (s.ctrl ? 'checked' : '') + ' />' +\n ' Shift <input type=\"checkbox\" data-shift=\"' + n + '\" ' + (s.shift ? 'checked' : '') + ' />' +\n ' <input type=\"text\" class=\"te-sc-input\" data-action=\"' + n + '\" value=\"' + esc(s.key) + '\" placeholder=\"key\" maxlength=\"1\" />' +\n '</td></tr>';\n }\n html += '</table>';\n if(body) body.innerHTML = html;\n });\n }\n};\n\nexport default shortcutCustomizer;\n","import type { PluginManagerInstance } from '../types';\n\nimport block from './block';\nimport inline from './inline';\nimport pre from './pre';\nimport inlineCode from './inlineCode';\nimport subSuper from './subSuper';\nimport keyboardShortcuts from './keyboardShortcuts';\n\nimport readOnly from './readOnly';\nimport linkTooltip from './linkTooltip';\nimport emojiAutocomplete from './emojiAutocomplete';\nimport statusBar from './statusBar';\nimport codeBlock from './codeBlock';\nimport mediaEmbed from './mediaEmbed';\nimport dragDrop from './dragDrop';\nimport pastePlain from './pastePlain';\nimport findReplace from './findReplace';\nimport indent from './indent';\nimport list from './list';\nimport lineHeight from './lineHeight';\nimport fontSize from './fontSize';\nimport fontFamily from './fontFamily';\nimport specialChars from './specialChars';\nimport colors from './colors';\nimport tableBg from './tableBg';\nimport align from './align';\nimport markdown from './markdown';\nimport link from './link';\nimport image from './image';\nimport imageProps from './imageProps';\nimport imageTools from './imageTools';\nimport iframe from './iframe';\nimport table from './table';\nimport tableTools from './tableTools';\nimport hr from './hr';\nimport unlink from './unlink';\nimport emoji from './emoji';\nimport direction from './direction';\nimport source from './source';\nimport history from './history';\nimport fullscreen from './fullscreen';\nimport toolbarCollapse from './toolbarCollapse';\nimport autosave from './autosave';\nimport autoLinkify from './autoLinkify';\nimport caseTransform from './caseTransform';\nimport shortcutsHelp from './shortcutsHelp';\nimport floatingToolbar from './floatingToolbar';\nimport darkMode from './darkMode';\nimport shortcutCustomizer from './shortcutCustomizer';\n\nexport default function registerDefaultPlugins(pm: PluginManagerInstance): void {\n pm.register('block', block);\n pm.register('inline', inline);\n pm.register('pre', pre);\n pm.register('inlineCode', inlineCode);\n pm.register('subSuper', subSuper);\n pm.register('keyboardShortcuts', keyboardShortcuts);\n\n pm.register('readOnly', readOnly);\n pm.register('linkTooltip', linkTooltip);\n pm.register('emojiAutocomplete', emojiAutocomplete);\n pm.register('statusBar', statusBar);\n pm.register('codeBlock', codeBlock);\n pm.register('mediaEmbed', mediaEmbed);\n pm.register('dragDrop', dragDrop);\n pm.register('pastePlain', pastePlain);\n pm.register('findReplace', findReplace);\n pm.register('indent', indent);\n pm.register('list', list);\n pm.register('lineHeight', lineHeight);\n pm.register('fontSize', fontSize);\n pm.register('fontFamily', fontFamily);\n pm.register('specialChars', specialChars);\n pm.register('colors', colors);\n pm.register('tableBg', tableBg);\n pm.register('align', align);\n pm.register('markdown', markdown);\n pm.register('link', link);\n pm.register('image', image);\n pm.register('imageProps', imageProps);\n pm.register('imageTools', imageTools);\n pm.register('iframe', iframe);\n pm.register('table', table);\n pm.register('tableTools', tableTools);\n pm.register('hr', hr);\n pm.register('unlink', unlink);\n pm.register('emoji', emoji);\n pm.register('direction', direction);\n pm.register('source', source);\n pm.register('history', history);\n pm.register('fullscreen', fullscreen);\n pm.register('toolbarCollapse', toolbarCollapse);\n pm.register('autosave', autosave);\n pm.register('autoLinkify', autoLinkify);\n pm.register('caseTransform', caseTransform);\n pm.register('shortcutsHelp', shortcutsHelp);\n pm.register('floatingToolbar', floatingToolbar);\n pm.register('darkMode', darkMode);\n pm.register('shortcutCustomizer', shortcutCustomizer);\n}\n","import './styles/index.css';\n\nimport PluginManager from './core/PluginManager';\nimport Editor from './core/Editor';\nimport registerDefaultPlugins from './plugins/index';\nimport type {\n EditorOptions,\n EditorInstance,\n BrowseImageHandler,\n TulihEditorStatic,\n} from './types';\n\nconst pm = new PluginManager();\nregisterDefaultPlugins(pm);\npm.injectAllCSS();\n\n// Auto-load the Tabler Icons webfont (used by toolbar buttons) unless it is\n// already present on the page. Tabler Icons is MIT licensed\n// (https://github.com/tabler/tabler-icons). Pinned to the v3 line to avoid\n// unexpected breaking changes from a future major release.\n(function loadTablerIcons(): void {\n if (typeof document === 'undefined') return;\n if (document.querySelector('link[href*=\"tabler-icons\"]')) return;\n const l = document.createElement('link');\n l.rel = 'stylesheet';\n l.href = 'https://cdn.jsdelivr.net/npm/@tabler/icons-webfont@3/dist/tabler-icons.min.css';\n document.head.appendChild(l);\n})();\n\nconst TulihEditor: TulihEditorStatic = {\n pluginManager: pm,\n instances: [],\n onBrowseImage: null,\n onUploadImage: null,\n\n setBrowseImage(handler: BrowseImageHandler): void {\n this.onBrowseImage = handler;\n },\n\n attach(target: string | Element, options?: EditorOptions): EditorInstance | undefined {\n const el = (typeof target === 'string' ? document.querySelector(target) : target) as HTMLElement | null;\n if (!el) return;\n if (String(el.tagName).toUpperCase() !== 'TEXTAREA' && !(el.matches && el.matches('textarea[data-tulih-editor]'))) return;\n const sibling = el.nextElementSibling;\n if (sibling && sibling.querySelector && sibling.querySelector('.te-editor')) return;\n\n return new Editor(el, options, TulihEditor);\n },\n\n create(target: string | Element, options?: EditorOptions): EditorInstance | undefined {\n return this.attach(target, options);\n },\n};\n\nif (typeof document !== 'undefined') {\n document.addEventListener('DOMContentLoaded', () => {\n const allTA = document.querySelectorAll('textarea[data-tulih-editor]');\n allTA.forEach((ta) => { TulihEditor.attach(ta); });\n });\n}\n\n// Expose the classes on the default object for advanced/UMD consumers without\n// adding runtime *named* exports (those would turn the UMD global into\n// `TulihEditor.default`, breaking the documented `<script>` usage).\n(TulihEditor as TulihEditorStatic & { Editor: typeof Editor; PluginManager: typeof PluginManager }).Editor = Editor;\n(TulihEditor as TulihEditorStatic & { Editor: typeof Editor; PluginManager: typeof PluginManager }).PluginManager = PluginManager;\n\nexport default TulihEditor;\nexport type {\n Plugin,\n PluginContext,\n EditorOptions,\n EditorInstance,\n Features,\n SanitizeOptions,\n ResolvedOptions,\n EditorUtils,\n UploadImageHandler,\n BrowseImageHandler,\n TulihEditorStatic,\n PluginManagerInstance,\n HTMLProvider,\n CSSProvider,\n TeHistory,\n TeEditorElement,\n TeWrapperElement,\n} from './types';\n"],"names":["PluginManager","name","plugin","idx","sorted","visited","visiting","map","visit","p","dep","a","b","ctx","features","toolbar","parts","group","i","html","plugins","lastGroup","cssText","style","blockSelector","inlineTags","hasBlockDescendant","el","isInlineElement","tag","wrapNodeInP","node","wrapIframe","wrapper","normalizeParagraphs","root","child","next","ensureInitialParagraph","p0","escapeHtml","str","buildEditorHTML","toolbarHTML","modalHTML","DEFAULT_FEATURES","DEFAULT_SANITIZE","DEFAULT_URL_SCHEMES","DEFAULT_IMAGE_SCHEMES","DEFAULT_IFRAME_ALLOWLIST","DEFAULT_IFRAME_SANDBOX","DEFAULT_IFRAME_ALLOW","Editor","target","options","TulihEditor","isTextarea","hasAttr","sibling","opts","textarea","isMinimal","allOn","k","self","sanitizeHTML","sanOpts","allowedTags","allowedAttrs","container","walker","toUnwrap","comments","attr","aname","isSafeUrl","src","isAllowedIframeUrl","c","url","schemes","u","host","allowed","editorEl","toolbarEl","raw","safeInit","H.normalizeParagraphs","H.ensureInitialParagraph","updateActiveStates","cmd","btn","undoBtn","redoBtn","h","canUndo","canRedo","sel","elNode","inOL","inUL","olBtn","ulBtn","val","clearFrHighlights","m","parent","x","modal","saveSel","s","restoreSel","r","insertImageFile","file","f","cb","cleanWordHtml","out","e","files","pasted","fi","items","ii","imgFile","clipItems","ci","ciTypes","ct","blob","rawHtml","text","toInsert","safe","ro","isRo","instances","myIdx","block","v","inline","pre","inlineCode","txt","H.escapeHtml","subSuper","STORAGE_KEY","DEFAULT_MAP","loadMap","keyboardShortcuts","editor","linkBtn","applyReadOnly","readOnly","linkTooltip","tooltip","hideTimer","hide","href","position","y","EMOJIS","EMOJI_NAMES","emojiAutocomplete","popup","query","activeIdx","buildItems","filter","div","rect","pr","insertEmoji","emoji","range","len","move","dir","active","offset","before","colon","item","statusBar","bar","getActiveTag","n","t","update","hasSel","words","chars","tagEl","rightEl","wEl","cEl","selText","selWords","LANGUAGES","codeBlock","l","lang","cls","EMBED_PROVIDERS","id","mediaEmbed","dragDrop","isImageFile","readFile","reader","handler","pastePlain","findReplace","findInp","replaceInp","countEl","escapeRe","clearHighlights","selectMatch","highlights","currentIdx","doFind","nodes","nodeText","re2","matches","match","span","mid","goNext","goPrev","doFindAndSelect","closePopup","saveUndoState","updateUndoRedoBtns","rbtn","findText","replaceText","re","count","indent","indentBtn","outdentBtn","CLS_RE","OL_STYLES","UL_STYLES","setListStyle","list","findAncestorList","buildOptions","styles","handleSelect","select","execCmd","matched","afterNode","newList","olSel","ulSel","lineHeight","FONT_SIZES","fontSize","FONTS","fontFamily","CHARS","specialChars","ch","colors","foreInput","foreBtn","preview","backInput","backBtn","tableBg","ALIGN_CMDS","getBlockAlignment","cs","ta","align","names","updateActive","RULES","markdown","rule","link","editingLink","linkTools","linkEditPopup","posLinkTools","er","tw","th","left","spaceBelow","top","hideLinkTools","_editPopupTime","hideEditPopup","_from","showEditPopup","pw","ph","openLinkModal","closeLinkModal","fillModal","sub","getSelectedText","actionBtn","action","updateLink","fromTools","form","blank","rel","isOk","relFinal","displayText","closeBtns","image","inputUrl","browseBtn","alt","ok","img","imageProps","altInp","wInp","hInp","clsInp","idInp","styleInp","currentImg","w","idv","safeCss","decl","prop","SAFE","imageTools","currentImage","tools","resizeHandle","getAlign","st","setAlign","clearImageFocus","prev","showResizeHandle","updateAlignBtns","posTools","toolsH","editorRect","below","above","capBtn","brdrBtn","rndBtn","hideTools","dblClick","curBorder","curRadius","fig","figure","caption","resizeData","parentW","currentPct","onResize","onResizeEnd","dx","pctDelta","newPct","iframe","allowOk","attrs","sandbox","allow","MAX_COLS","MAX_ROWS","table","cellsContainer","label","cell","clearActive","highlight","ec","insertTable","cols","rows","rr","cc","tableTools","ed","currentCell","currentTable","lastCell","lastTable","selectedCells","saveHist","updateMergeBtn","toggleHighlight","updateUnmergeBtn","rs","updateValignBtns","cellAlign","toolsW","sx","sy","leftPos","minLeft","maxLeft","spaceAbove","topPos","minTop","maxTop","updateFromSelection","getSelectedCellsForTools","tbl","cells","applyBgColor","value","clearBgColor","bgInput","getCellIndex","forEachRow","sec","row","refocus","scheduleRefocus","mergeCells","positions","minRow","maxRow","minCol","maxCol","mergeBtn","contents","kept","unmergeCell","colspan","rowspan","rowIdx","colIdx","ref","nc","tr","insBefore","newRow","td","after","newCell","any","vAlign","vi","thead","tbody","tb","hr","hc","first","newHead","trh","cap","currentStyle","currentColor","savedRange","saveEditorRange","restoreEditorRange","posPopup","br","insertHR","hidePopup","showPopup","opt","inp","unlink","grid","search","noResult","toolbarBtn","vw","vh","q","visible","direction","source","sourceMode","formatSource","blockTags","openRe","closeRe","toggleSource","allControls","history","fullscreen","isFull","toolbarCollapse","STORAGE_PREFIX","getStorageKey","autosave","key","saved","badge","setStatus","saveTimer","save","URL_RE","autoLinkify","fullUrl","caseTransform","transformed","shortcutsHelp","floatingToolbar","linkInput","restoreRange","isVisible","saveRange","showTools","showLinkInput","toolsRect","liw","lih","darkMode","isDark","icon","saveMap","esc","shortcutCustomizer","body","saveBtn","ctrl","shift","resetBtn","registerDefaultPlugins","pm"],"mappings":"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"}