autumnnote 1.0.3 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/autumnnote.es.js +923 -869
- package/dist/autumnnote.es.js.map +1 -1
- package/dist/autumnnote.umd.js +11 -11
- package/dist/autumnnote.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/js/index.umd.js +12 -12
- package/src/js/module/ImageResizer.js +41 -26
- package/src/js/module/ImageTooltip.js +40 -6
- package/src/js/module/TableTooltip.js +93 -68
- package/src/js/module/VideoResizer.js +45 -33
- package/src/js/module/VideoTooltip.js +9 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"autumnnote.es.js","sources":["../src/js/core/func.js","../src/js/core/dom.js","../src/js/core/range.js","../src/js/editing/Style.js","../src/js/module/Buttons.js","../src/js/settings.js","../src/js/core/sanitise.js","../src/js/renderer.js","../src/js/editing/History.js","../src/js/editing/Table.js","../src/js/core/key.js","../src/js/editing/Typing.js","../src/js/core/markdown.js","../src/js/module/Editor.js","../src/js/module/Toolbar.js","../src/js/module/Statusbar.js","../src/js/module/Clipboard.js","../src/js/module/Placeholder.js","../src/js/module/Codeview.js","../src/js/module/Fullscreen.js","../src/js/module/LinkDialog.js","../src/js/module/ImageDialog.js","../src/js/module/VideoDialog.js","../src/js/module/ImageResizer.js","../src/js/module/VideoResizer.js","../src/js/module/LinkTooltip.js","../src/js/module/ImageTooltip.js","../src/js/module/VideoTooltip.js","../src/js/module/TableTooltip.js","../src/js/module/CodeTooltip.js","../src/js/module/EmojiDialog.js","../src/js/module/IconDialog.js","../src/js/module/ContextMenu.js","../src/js/module/ShortcutsDialog.js","../src/js/module/FindReplace.js","../src/js/Context.js","../src/js/core/lists.js","../src/js/core/env.js","../src/js/index.js"],"sourcesContent":["/**\n * func.js - General utility / functional helpers\n * Inspired by Summernote's func.js\n */\n\n/**\n * Clamp a value between min and max.\n * @param {number} val\n * @param {number} min\n * @param {number} max\n * @returns {number}\n */\nexport function clamp(val, min, max) {\n return Math.min(Math.max(val, min), max);\n}\n\n/**\n * Debounce a function call.\n * @param {Function} fn\n * @param {number} delay - milliseconds\n * @returns {Function}\n */\nexport function debounce(fn, delay) {\n let timer;\n return function (...args) {\n clearTimeout(timer);\n timer = setTimeout(() => fn.apply(this, args), delay);\n };\n}\n\n/**\n * Throttle a function call.\n * @param {Function} fn\n * @param {number} limit - milliseconds\n * @returns {Function}\n */\nexport function throttle(fn, limit) {\n let lastCall = 0;\n return function (...args) {\n const now = Date.now();\n if (now - lastCall >= limit) {\n lastCall = now;\n return fn.apply(this, args);\n }\n };\n}\n\n/**\n * Compose multiple functions right-to-left.\n * @param {...Function} fns\n * @returns {Function}\n */\nexport function compose(...fns) {\n return (x) => fns.reduceRight((v, f) => f(v), x);\n}\n\n/**\n * Identity function.\n * @template T\n * @param {T} x\n * @returns {T}\n */\nexport function identity(x) {\n return x;\n}\n\n/**\n * Determines if a value is null or undefined.\n * @param {*} val\n * @returns {boolean}\n */\nexport function isNil(val) {\n return val === null || val === undefined;\n}\n\n/**\n * Determines if a value is a string.\n * @param {*} val\n * @returns {boolean}\n */\nexport function isString(val) {\n return typeof val === 'string';\n}\n\n/**\n * Determines if a value is a function.\n * @param {*} val\n * @returns {boolean}\n */\nexport function isFunction(val) {\n return typeof val === 'function';\n}\n\n/**\n * Deep-merge two plain objects. Returns a new object.\n * Arrays are cloned (shallow copy) rather than shared by reference so that\n * mutations to the merged result do not bleed back into the source object\n * (e.g. mutating `instance.options.fontFamilies` should not affect\n * `AutumnNote.defaults.fontFamilies`).\n * @param {object} target\n * @param {object} source\n * @returns {object}\n */\nexport function mergeDeep(target, source) {\n // Start with a shallow copy of target; clone any arrays to avoid shared refs\n const output = {};\n for (const key of Object.keys(target)) {\n output[key] = Array.isArray(target[key]) ? [...target[key]] : target[key];\n }\n if (isPlainObject(target) && isPlainObject(source)) {\n for (const key of Object.keys(source)) {\n if (isPlainObject(source[key])) {\n if (!(key in target)) {\n output[key] = mergeDeep({}, source[key]);\n } else {\n output[key] = mergeDeep(target[key], source[key]);\n }\n } else if (Array.isArray(source[key])) {\n output[key] = [...source[key]];\n } else {\n output[key] = source[key];\n }\n }\n }\n return output;\n}\n\n/**\n * Checks if value is a plain object.\n * @param {*} val\n * @returns {boolean}\n */\nexport function isPlainObject(val) {\n return val !== null && typeof val === 'object' && !Array.isArray(val);\n}\n\n/**\n * Convert a DOMRect (or similar bounding object) to a plain object bounding box.\n * Guards against missing/null rect (e.g. in AirMode).\n * @param {DOMRect|null|undefined} rect\n * @returns {{ top: number, left: number, width: number, height: number, bottom: number, right: number }|null}\n */\nexport function rect2bnd(rect) {\n if (!rect) return null;\n return {\n top: Math.round(rect.top),\n left: Math.round(rect.left),\n width: Math.round(rect.width),\n height: Math.round(rect.height),\n bottom: Math.round(rect.bottom),\n right: Math.round(rect.right),\n };\n}\n","/**\n * dom.js - DOM manipulation utilities\n * Inspired by Summernote's dom.js — rewritten for vanilla JS without jQuery\n */\n\n// ---------------------------------------------------------------------------\n// Node type helpers\n// ---------------------------------------------------------------------------\n\nexport const ELEMENT_NODE = 1;\nexport const TEXT_NODE = 3;\n\n/** @param {Node} node */\nexport const isElement = (node) => node && node.nodeType === ELEMENT_NODE;\n/** @param {Node} node */\nexport const isText = (node) => node && node.nodeType === TEXT_NODE;\n/** @param {Node} node */\nexport const isVoid = (node) => isElement(node) && /^(area|base|br|col|embed|hr|img|input|link|meta|param|source|track|wbr)$/i.test(node.nodeName);\n/** @param {Node} node */\nexport const isPara = (node) => isElement(node) && /^(p|div|li|h[1-6]|blockquote|td|th|pre)$/i.test(node.nodeName);\n/** @param {Node} node */\nexport const isLi = (node) => isElement(node) && /^(li)$/i.test(node.nodeName);\n/** @param {Node} node */\nexport const isList = (node) => isElement(node) && /^(ul|ol)$/i.test(node.nodeName);\n/** @param {Node} node */\nexport const isTable = (node) => isElement(node) && node.nodeName.toUpperCase() === 'TABLE';\n/** @param {Node} node */\nexport const isInline = (node) =>\n isElement(node) &&\n /^(a|abbr|acronym|b|bdo|big|br|button|cite|code|dfn|em|i|img|input|kbd|label|map|object|output|q|s|samp|select|small|span|strong|sub|sup|textarea|time|tt|u|var)$/i.test(node.nodeName);\n/** @param {Node} node */\nexport const isEditable = (node) => isElement(node) && node.isContentEditable;\n/** @param {Node} node */\nexport const isAnchor = (node) => isElement(node) && node.nodeName.toUpperCase() === 'A';\n/** @param {Node} node */\nexport const isImage = (node) => isElement(node) && node.nodeName.toUpperCase() === 'IMG';\n\n// ---------------------------------------------------------------------------\n// Tree traversal\n// ---------------------------------------------------------------------------\n\n/**\n * Walk up the DOM tree from node, returning the first element matching predicate (inclusive).\n * @param {Node} node\n * @param {(node: Node) => boolean} predicate\n * @param {Node} [stopAt] - stop traversal at this ancestor (exclusive)\n * @returns {Node|null}\n */\nexport function closest(node, predicate, stopAt) {\n let cur = node;\n while (cur && cur !== stopAt) {\n if (predicate(cur)) return cur;\n cur = cur.parentNode;\n }\n return null;\n}\n\n/**\n * Returns the nearest ancestor that is a paragraph-like block.\n * @param {Node} node\n * @param {Node} [editable]\n * @returns {Node|null}\n */\nexport function closestPara(node, editable) {\n return closest(node, isPara, editable);\n}\n\n/**\n * Returns all ancestors of node up to (but not including) stopAt.\n * @param {Node} node\n * @param {Node} [stopAt]\n * @returns {Node[]}\n */\nexport function ancestors(node, stopAt) {\n const result = [];\n let cur = node.parentNode;\n while (cur && cur !== stopAt) {\n result.push(cur);\n cur = cur.parentNode;\n }\n return result;\n}\n\n/**\n * Returns all children of node as an Array.\n * @param {Node} node\n * @returns {Node[]}\n */\nexport function children(node) {\n return Array.from(node.childNodes);\n}\n\n/**\n * Returns the previous sibling element (skipping text/comment nodes).\n * @param {Node} node\n * @returns {Element|null}\n */\nexport function prevElement(node) {\n let sibling = node.previousSibling;\n while (sibling && !isElement(sibling)) {\n sibling = sibling.previousSibling;\n }\n return sibling;\n}\n\n/**\n * Returns the next sibling element.\n * @param {Node} node\n * @returns {Element|null}\n */\nexport function nextElement(node) {\n let sibling = node.nextSibling;\n while (sibling && !isElement(sibling)) {\n sibling = sibling.nextSibling;\n }\n return sibling;\n}\n\n// ---------------------------------------------------------------------------\n// DOM mutation helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Creates an element with optional attributes and children.\n * @param {string} tag\n * @param {Record<string, string>} [attrs]\n * @param {(Node|string)[]} [childNodes]\n * @returns {HTMLElement}\n */\nexport function createElement(tag, attrs = {}, childNodes = []) {\n const el = document.createElement(tag);\n for (const [k, v] of Object.entries(attrs)) {\n el.setAttribute(k, v);\n }\n for (const child of childNodes) {\n if (typeof child === 'string') {\n el.appendChild(document.createTextNode(child));\n } else {\n el.appendChild(child);\n }\n }\n return el;\n}\n\n/**\n * Removes a node from its parent.\n * @param {Node} node\n */\nexport function remove(node) {\n if (node && node.parentNode) {\n node.parentNode.removeChild(node);\n }\n}\n\n/**\n * Unwraps a node — replaces the node with its children.\n * @param {Node} node\n */\nexport function unwrap(node) {\n const parent = node.parentNode;\n if (!parent) return;\n while (node.firstChild) {\n parent.insertBefore(node.firstChild, node);\n }\n parent.removeChild(node);\n}\n\n/**\n * Wraps a node with a wrapper element.\n * @param {Node} node\n * @param {HTMLElement} wrapper\n * @returns {HTMLElement} the wrapper\n */\nexport function wrap(node, wrapper) {\n node.parentNode.insertBefore(wrapper, node);\n wrapper.appendChild(node);\n return wrapper;\n}\n\n/**\n * Insert node after reference node.\n * @param {Node} newNode\n * @param {Node} refNode\n */\nexport function insertAfter(newNode, refNode) {\n if (refNode.nextSibling) {\n refNode.parentNode.insertBefore(newNode, refNode.nextSibling);\n } else {\n refNode.parentNode.appendChild(newNode);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Content helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Returns the text content of a node (safe).\n * @param {Node} node\n * @returns {string}\n */\nexport function nodeValue(node) {\n return isText(node) ? node.nodeValue : node.textContent || '';\n}\n\n/**\n * Returns true if a node is empty (no visible content).\n * @param {Node} node\n * @returns {boolean}\n */\nexport function isEmpty(node) {\n if (isText(node)) return !node.nodeValue;\n if (isVoid(node)) return false;\n return !node.textContent.trim() && !node.querySelector('img, video, hr, table');\n}\n\n/**\n * Returns the outerHTML of an element.\n * @param {Element} el\n * @returns {string}\n */\nexport function outerHtml(el) {\n return el.outerHTML;\n}\n\n// ---------------------------------------------------------------------------\n// Selection / editing helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Places the caret at the end of a contenteditable element.\n * @param {HTMLElement} el\n */\nexport function placeCaret(el) {\n const range = document.createRange();\n range.selectNodeContents(el);\n range.collapse(false);\n const sel = window.getSelection();\n if (sel) {\n sel.removeAllRanges();\n sel.addRange(range);\n }\n}\n\n/**\n * Returns true if the node is inside a contenteditable root.\n * @param {Node} node\n * @returns {boolean}\n */\nexport function isInsideEditable(node) {\n return !!closest(node, isEditable);\n}\n\n// ---------------------------------------------------------------------------\n// Event helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Adds an event listener and returns a disposer function.\n * @param {EventTarget} target\n * @param {string} type\n * @param {EventListener} handler\n * @param {AddEventListenerOptions} [options]\n * @returns {() => void} disposer\n */\nexport function on(target, type, handler, options) {\n target.addEventListener(type, handler, options);\n return () => target.removeEventListener(type, handler, options);\n}\n\n/**\n * Installs a keyboard focus trap inside a dialog container.\n * - Tab / Shift+Tab cycles focus within the container's focusable children.\n * - Escape calls `onEscape` and removes the trap listener.\n *\n * Returns a disposer function that removes the listener (call on dialog close).\n *\n * @param {HTMLElement} container - the dialog element to trap focus inside\n * @param {() => void} onEscape - called when Escape is pressed\n * @returns {() => void} disposer\n */\nexport function trapFocus(container, onEscape) {\n const FOCUSABLE = 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"])';\n\n const getFocusable = () => Array.from(container.querySelectorAll(FOCUSABLE)).filter(\n (el) => !el.closest('[style*=\"display: none\"]') && !el.closest('[style*=\"display:none\"]'),\n );\n\n const handler = (e) => {\n if (e.key === 'Escape') {\n e.stopPropagation();\n onEscape && onEscape();\n return;\n }\n if (e.key !== 'Tab') return;\n const els = getFocusable();\n if (!els.length) return;\n const first = els[0];\n const last = els[els.length - 1];\n if (e.shiftKey) {\n if (document.activeElement === first) {\n e.preventDefault();\n last.focus();\n }\n } else {\n if (document.activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n }\n };\n\n document.addEventListener('keydown', handler);\n return () => document.removeEventListener('keydown', handler);\n}\n","/**\n * range.js - Selection and Range utilities\n * Inspired by Summernote's range.js — rewritten as vanilla JS\n */\n\nimport { isElement, closest } from './dom.js';\n\n// ---------------------------------------------------------------------------\n// WrappedRange — a convenience wrapper over the native Range API\n// ---------------------------------------------------------------------------\n\nexport class WrappedRange {\n /**\n * @param {Node} sc - start container\n * @param {number} so - start offset\n * @param {Node} ec - end container\n * @param {number} eo - end offset\n */\n constructor(sc, so, ec, eo) {\n this.sc = sc;\n this.so = so;\n this.ec = ec;\n this.eo = eo;\n }\n\n /** @returns {boolean} */\n isCollapsed() {\n return this.sc === this.ec && this.so === this.eo;\n }\n\n /** @returns {Range} */\n toNativeRange() {\n const range = document.createRange();\n try {\n range.setStart(this.sc, this.so);\n range.setEnd(this.ec, this.eo);\n } catch (_e) {\n // Guard against detached nodes\n }\n return range;\n }\n\n /**\n * Select this wrapped range in the window.\n */\n select() {\n const sel = window.getSelection();\n if (!sel) return;\n sel.removeAllRanges();\n sel.addRange(this.toNativeRange());\n }\n\n /**\n * Returns the common ancestor element of this range.\n * @returns {Element|null}\n */\n commonAncestor() {\n const native = this.toNativeRange();\n const ancestor = native.commonAncestorContainer;\n return isElement(ancestor) ? ancestor : ancestor.parentElement;\n }\n\n /**\n * Returns the nearest paragraph/block ancestor within the editable area.\n * @param {HTMLElement} editable\n * @returns {Element|null}\n */\n blockNode(editable) {\n return closest(this.sc, (n) => isElement(n) && n !== editable, editable);\n }\n\n /**\n * Returns either the selected text string or empty string.\n * @returns {string}\n */\n toString() {\n return this.toNativeRange().toString();\n }\n\n /**\n * Returns the bounding DOMRect of the range (or null).\n * @returns {DOMRect|null}\n */\n getClientRects() {\n const rects = this.toNativeRange().getClientRects();\n return rects.length > 0 ? rects[rects.length - 1] : null;\n }\n\n /**\n * Inserts a node at the start of this range.\n * @param {Node} node\n */\n insertNode(node) {\n const native = this.toNativeRange();\n native.insertNode(node);\n }\n\n}\n\n// ---------------------------------------------------------------------------\n// Factory helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Creates a WrappedRange from a native Range object.\n * @param {Range} range\n * @returns {WrappedRange}\n */\nexport function fromNativeRange(range) {\n return new WrappedRange(\n range.startContainer,\n range.startOffset,\n range.endContainer,\n range.endOffset,\n );\n}\n\n/**\n * Returns a WrappedRange for the current window selection,\n * optionally restricted to a given editable element.\n * @param {HTMLElement} [editable]\n * @returns {WrappedRange|null}\n */\nexport function currentRange(editable) {\n const sel = window.getSelection();\n if (!sel || sel.rangeCount === 0) return null;\n const native = sel.getRangeAt(0);\n // Optionally check that the selection is inside the editable element\n if (editable && !editable.contains(native.commonAncestorContainer)) {\n return null;\n }\n return fromNativeRange(native);\n}\n\n/**\n * Creates a WrappedRange that covers the entire content of an element.\n * @param {HTMLElement} el\n * @returns {WrappedRange}\n */\nexport function rangeFromElement(el) {\n return new WrappedRange(el, 0, el, el.childNodes.length);\n}\n\n/**\n * Creates a collapsed range (cursor) at the given node / offset.\n * @param {Node} node\n * @param {number} offset\n * @returns {WrappedRange}\n */\nexport function collapsedRange(node, offset = 0) {\n return new WrappedRange(node, offset, node, offset);\n}\n\n// ---------------------------------------------------------------------------\n// Utility helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Returns true if the current selection is inside the given element.\n * @param {HTMLElement} el\n * @returns {boolean}\n */\nexport function isSelectionInside(el) {\n const sel = window.getSelection();\n if (!sel || sel.rangeCount === 0) return false;\n return el.contains(sel.getRangeAt(0).commonAncestorContainer);\n}\n\n/**\n * Saves the current selection, executes fn, then restores the selection.\n * @param {Function} fn\n */\nexport function withSavedRange(fn) {\n const sel = window.getSelection();\n if (!sel || sel.rangeCount === 0) {\n fn(null);\n return;\n }\n const saved = sel.getRangeAt(0).cloneRange();\n fn(fromNativeRange(saved));\n sel.removeAllRanges();\n sel.addRange(saved);\n}\n\n/**\n * Splits the text node at the given offset and returns the two halves.\n * @param {Text} textNode\n * @param {number} offset\n * @returns {[Text, Text]}\n */\nexport function splitText(textNode, offset) {\n const after = textNode.splitText(offset);\n return [textNode, after];\n}\n","/**\n * Style.js - Inline / block style detection and application utilities\n * Rewritten from Summernote's approach using vanilla JS + execCommand fallback\n */\n\nimport { closest, isElement, isPara } from '../core/dom.js';\nimport { currentRange } from '../core/range.js';\n\n// ---------------------------------------------------------------------------\n// execCommand wrappers (still the most compatible way in contenteditable)\n// ---------------------------------------------------------------------------\n\n/**\n * Applies a document execCommand.\n * @param {string} cmd\n * @param {string} [value]\n * @returns {boolean}\n */\nexport function execCommand(cmd, value = null) {\n return document.execCommand(cmd, false, value);\n}\n\n// ---------------------------------------------------------------------------\n// Inline style helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Bolds / unbolds the selection.\n */\nexport const bold = () => execCommand('bold');\n\n/**\n * Italicises / un-italicises the selection.\n */\nexport const italic = () => execCommand('italic');\n\n/**\n * Underlines / un-underlines the selection.\n * Falls back to manual DOM manipulation when inside <code> where\n * execCommand's state detection is unreliable.\n */\nexport function underline() {\n const sel = window.getSelection();\n if (!sel || !sel.rangeCount) return;\n let container = sel.getRangeAt(0).commonAncestorContainer;\n if (container.nodeType === 3) container = container.parentElement;\n // Check if we're inside a <u> (DOM truth), to guard against unreliable queryCommandState\n const uEl = container && container.closest && container.closest('u');\n const nativeState = document.queryCommandState('underline');\n if (uEl && !nativeState) {\n // Browser doesn't recognise the underline state (e.g. inside <code>).\n // Manually unwrap the <u> element.\n const parent = uEl.parentNode;\n while (uEl.firstChild) parent.insertBefore(uEl.firstChild, uEl);\n parent.removeChild(uEl);\n return;\n }\n execCommand('underline');\n}\n\n/**\n * Strikethrough / removes strikethrough.\n */\nexport const strikethrough = () => execCommand('strikeThrough');\n\n/**\n * Superscript toggle.\n */\nexport const superscript = () => execCommand('superscript');\n\n/**\n * Subscript toggle.\n */\nexport const subscript = () => execCommand('subscript');\n\n/**\n * Sets the foreground colour of the selected text.\n * @param {string} color - CSS colour string\n */\nexport const foreColor = (color) => execCommand('foreColor', color);\n\n/**\n * Sets the background (highlight) colour of the selected text.\n * @param {string} color - CSS colour string\n */\nexport const backColor = (color) => execCommand('hiliteColor', color);\n\n/**\n * Sets the font name for the selection.\n * @param {string} name\n */\nexport const fontName = (name) => execCommand('fontName', name);\n\n/**\n * Sets the font size (in pt or with unit) for the selection.\n * Uses a span-based approach to set px sizes precisely.\n * @param {string} size - e.g. '14px'\n * @param {HTMLElement} [editable] - scoping element to avoid touching nodes outside this editor\n */\nexport function fontSize(size, editable = document) {\n execCommand('fontSize', '7'); // placeholder\n // Replace font elements with spans, scoped to the active editable\n editable.querySelectorAll('font[size=\"7\"]').forEach((el) => {\n const span = document.createElement('span');\n span.style.fontSize = size;\n el.parentNode.insertBefore(span, el);\n while (el.firstChild) span.appendChild(el.firstChild);\n el.parentNode.removeChild(el);\n });\n}\n\n// ---------------------------------------------------------------------------\n// Block style helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Wraps the selection in the given block tag (p, h1-h6, blockquote, pre).\n * @param {string} tagName\n */\nexport const formatBlock = (tagName) => execCommand('formatBlock', `<${tagName}>`);\n\n/**\n * Left-aligns the current block.\n */\nexport const justifyLeft = () => execCommand('justifyLeft');\n\n/**\n * Center-aligns the current block.\n */\nexport const justifyCenter = () => execCommand('justifyCenter');\n\n/**\n * Right-aligns the current block.\n */\nexport const justifyRight = () => execCommand('justifyRight');\n\n/**\n * Fully justifies the current block.\n */\nexport const justifyFull = () => execCommand('justifyFull');\n\n/**\n * Indents the list or block.\n */\nexport const indent = () => execCommand('indent');\n\n/**\n * Outdents the list or block.\n */\nexport const outdent = () => execCommand('outdent');\n\n/**\n * Inserts an unordered list or converts selection.\n */\nexport const insertUnorderedList = () => execCommand('insertUnorderedList');\n\n/**\n * Inserts an ordered list or converts selection.\n */\nexport const insertOrderedList = () => execCommand('insertOrderedList');\n\n// ---------------------------------------------------------------------------\n// Line-height helper\n// ---------------------------------------------------------------------------\n\n/**\n * Applies a line-height value to every block-level element that intersects\n * the current selection.\n * @param {string} value - unitless multiplier, e.g. '1.5'\n */\nexport function lineHeight(value) {\n const sel = window.getSelection();\n if (!sel || sel.rangeCount === 0) return;\n\n const range = sel.getRangeAt(0);\n const BLOCK_TAGS = new Set(['P', 'DIV', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'LI', 'BLOCKQUOTE', 'PRE', 'TD', 'TH']);\n\n const nearestBlock = (node) => {\n let el = node instanceof Element ? node : node.parentElement;\n while (el) {\n if (BLOCK_TAGS.has(el.tagName)) return el;\n el = el.parentElement;\n }\n return null;\n };\n\n if (range.collapsed) {\n const block = nearestBlock(range.startContainer);\n if (block) block.style.lineHeight = value;\n return;\n }\n\n // For a range selection, collect all unique block ancestors of text nodes\n const blocks = new Set();\n const iter = document.createNodeIterator(range.commonAncestorContainer, NodeFilter.SHOW_TEXT, null);\n let textNode;\n while ((textNode = iter.nextNode())) {\n if (range.intersectsNode(textNode)) {\n const block = nearestBlock(textNode);\n if (block) blocks.add(block);\n }\n }\n if (blocks.size === 0) {\n const block = nearestBlock(range.commonAncestorContainer);\n if (block) blocks.add(block);\n }\n blocks.forEach((block) => { block.style.lineHeight = value; });\n}\n\n// ---------------------------------------------------------------------------\n// Style query helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Returns the computed styles relevant to the current cursor position.\n * @param {HTMLElement} editable\n * @returns {object} styleMap\n */\nexport function currentStyle(editable) {\n const range = currentRange(editable);\n if (!range) return {};\n\n const container = range.isCollapsed()\n ? range.sc\n : range.commonAncestor();\n\n const el = isElement(container) ? container : container.parentElement;\n if (!el) return {};\n\n const computed = window.getComputedStyle(el);\n\n return {\n bold: document.queryCommandState('bold'),\n italic: document.queryCommandState('italic'),\n underline: document.queryCommandState('underline'),\n strikethrough: document.queryCommandState('strikeThrough'),\n superscript: document.queryCommandState('superscript'),\n subscript: document.queryCommandState('subscript'),\n fontSize: computed.fontSize,\n fontFamily: computed.fontFamily,\n color: computed.color,\n backgroundColor: computed.backgroundColor,\n textAlign: computed.textAlign,\n lineHeight: computed.lineHeight,\n formatBlock: (closest(el, isPara, editable) || { nodeName: 'p' }).nodeName.toLowerCase(),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Inline code toggle\n// ---------------------------------------------------------------------------\n\n/**\n * Wraps the selection in an inline <code> element, or unwraps it if the\n * cursor is already inside a <code> that is not inside a <pre>.\n * @param {HTMLElement} [editable]\n */\nexport function toggleInlineCode(editable) {\n const sel = window.getSelection();\n if (!sel || !sel.rangeCount) return;\n const range = sel.getRangeAt(0);\n let container = range.commonAncestorContainer;\n if (container.nodeType === 3) container = container.parentElement;\n const codeEl = container && container.closest ? container.closest('code') : null;\n if (codeEl && !codeEl.closest('pre')) {\n // Unwrap\n const parent = codeEl.parentNode;\n while (codeEl.firstChild) parent.insertBefore(codeEl.firstChild, codeEl);\n parent.removeChild(codeEl);\n if (editable) editable.normalize();\n } else {\n if (range.collapsed) return;\n try {\n const code = document.createElement('code');\n range.surroundContents(code);\n // Re-select wrapped content so subsequent format toggles work\n const newRange = document.createRange();\n newRange.selectNodeContents(code);\n sel.removeAllRanges();\n sel.addRange(newRange);\n } catch {\n // surroundContents fails across element boundaries — extract and rewrap\n const frag = range.extractContents();\n const code = document.createElement('code');\n code.appendChild(frag);\n range.insertNode(code);\n // Re-select wrapped content\n const newRange = document.createRange();\n newRange.selectNodeContents(code);\n sel.removeAllRanges();\n sel.addRange(newRange);\n }\n }\n}\n\n/**\n * Returns true when the cursor / selection is inside an inline <code>\n * (not nested in a <pre>).\n * @returns {boolean}\n */\nexport function isInlineCode() {\n const sel = window.getSelection();\n if (!sel || !sel.rangeCount) return false;\n let container = sel.getRangeAt(0).commonAncestorContainer;\n if (container.nodeType === 3) container = container.parentElement;\n const code = container && container.closest ? container.closest('code') : null;\n return !!(code && !code.closest('pre'));\n}\n\n// ---------------------------------------------------------------------------\n// Checklist (task list)\n// ---------------------------------------------------------------------------\n\n/**\n * Toggles a task-list at the cursor.\n * If inside a checklist <li>, converts it back to a <p>.\n * Otherwise inserts a new <ul class=\"an-checklist\"> with one item.\n */\nexport function toggleChecklist() {\n const sel = window.getSelection();\n if (!sel || !sel.rangeCount) return;\n const range = sel.getRangeAt(0);\n let container = range.commonAncestorContainer;\n if (container.nodeType === 3) container = container.parentElement;\n const li = container && container.closest ? container.closest('.an-checklist li') : null;\n if (li) {\n // Exit checklist — convert item to a <p>\n const ul = li.closest('.an-checklist');\n const text = Array.from(li.childNodes)\n .filter((n) => !(n.nodeType === 1 && n.tagName === 'INPUT'))\n .map((n) => n.textContent).join('').replace(/\\u00a0/g, ' ').trim();\n const p = document.createElement('p');\n p.textContent = text || '\\u00a0';\n ul.parentNode.insertBefore(p, ul.nextSibling);\n ul.removeChild(li);\n if (ul.children.length === 0) ul.remove();\n const nr = document.createRange();\n // Point into the text node (or first child) rather than the element node\n // so the cursor is at a well-defined text position, not element-offset 0.\n const startNode = p.firstChild || p;\n nr.setStart(startNode, 0);\n nr.collapse(true);\n sel.removeAllRanges();\n sel.addRange(nr);\n } else {\n // Use a temporary marker attribute so the new <li> can be found reliably\n // even when execCommand('insertHTML') places the cursor outside the list.\n // Chrome often moves the caret to a generated <p> after the <ul> rather\n // than staying inside the <li>, making a selection-based lookup fail.\n const MARKER = 'data-an-new-cli';\n execCommand('insertHTML',\n `<ul class=\"an-checklist\"><li ${MARKER}><input type=\"checkbox\" contenteditable=\"false\"></li></ul>`);\n const newLi = document.querySelector(`[${MARKER}]`);\n if (newLi) {\n newLi.removeAttribute(MARKER);\n const cbEl = newLi.querySelector('input[type=\"checkbox\"]');\n if (cbEl) {\n // Use \\u200B (zero-width space) instead of an empty string.\n // Chrome does not reliably honour a Selection pointing into an empty\n // text node and may silently normalise it to an element-level offset,\n // rendering the caret before the absolutely-positioned checkbox.\n // \\u200B is invisible/zero-width and is stripped by getHTML().\n let textNode = cbEl.nextSibling;\n if (!textNode || textNode.nodeType !== Node.TEXT_NODE) {\n textNode = document.createTextNode('\\u200B');\n newLi.appendChild(textNode);\n } else if (!textNode.textContent) {\n textNode.textContent = '\\u200B';\n }\n const nr = document.createRange();\n nr.setStart(textNode, 0);\n nr.collapse(true);\n sel.removeAllRanges();\n sel.addRange(nr);\n }\n }\n }\n}\n\n/**\n * Returns true when the cursor is inside a checklist item.\n * @returns {boolean}\n */\nexport function isInChecklist() {\n const sel = window.getSelection();\n if (!sel || !sel.rangeCount) return false;\n let container = sel.getRangeAt(0).commonAncestorContainer;\n if (container.nodeType === 3) container = container.parentElement;\n return !!(container && container.closest && container.closest('.an-checklist li'));\n}\n","/**\n * Buttons.js - Toolbar button definitions and factories\n * All buttons are plain objects describing their appearance and action.\n * They are rendered by the Toolbar module.\n */\n\nimport * as Style from '../editing/Style.js';\n\n// ---------------------------------------------------------------------------\n// Dropdown definition helper\n// ---------------------------------------------------------------------------\n\n/**\n * @typedef {object} DropdownDef\n * @property {string} name - unique identifier\n * @property {'select'} type - discriminator for Toolbar renderer\n * @property {string} tooltip\n * @property {string[]} [items] - overridden at render time from options\n * @property {Function} action - called with (context, value)\n * @property {Function} [getValue] - called with (context) to get current value\n */\n\n// ---------------------------------------------------------------------------\n// Button factory helpers\n// ---------------------------------------------------------------------------\n\n/**\n * @typedef {object} ButtonDef\n * @property {string} name - unique identifier\n * @property {string} icon - SVG or HTML icon markup / text\n * @property {string} tooltip - tooltip string\n * @property {Function} action - called with (context) when clicked\n * @property {Function} [isActive] - called with (context) to determine active state\n * @property {Function} [isDisabled] - called with (context) to determine disabled state\n * @property {string} [className] - extra CSS class(es)\n */\n\n/**\n * Creates a simple button definition.\n * @param {string} name\n * @param {string} icon\n * @param {string} tooltip\n * @param {Function} action\n * @param {Function} [isActive]\n * @param {Function} [isDisabled]\n * @returns {ButtonDef}\n */\nfunction btn(name, icon, tooltip, action, isActive, isDisabled) {\n // `icon` is an identifier (e.g. 'bold', 'italic'). Rendering to\n // visual markup (FontAwesome or fallback) is done in Toolbar._createButton\n return { name, icon, tooltip, action, isActive, isDisabled };\n}\n\n// ---------------------------------------------------------------------------\n// Style buttons\n// ---------------------------------------------------------------------------\n\nexport const boldBtn = btn('bold', 'bold', 'Bold (Ctrl+B)', () => Style.bold(), () => document.queryCommandState('bold'));\nexport const italicBtn = btn('italic', 'italic', 'Italic (Ctrl+I)', () => Style.italic(), () => document.queryCommandState('italic'));\nexport const underlineBtn = btn('underline', 'underline', 'Underline (Ctrl+U)', () => Style.underline(), () => {\n // queryCommandState('underline') is unreliable inside <code> elements;\n // also check for a <u> ancestor in the DOM.\n if (document.queryCommandState('underline')) return true;\n const sel = window.getSelection();\n if (!sel || !sel.rangeCount) return false;\n let container = sel.getRangeAt(0).commonAncestorContainer;\n if (container.nodeType === 3) container = container.parentElement;\n return !!(container && container.closest && container.closest('u'));\n});\nexport const strikeBtn = btn('strikethrough', 'strikethrough', 'Strikethrough', () => Style.strikethrough(), () => document.queryCommandState('strikeThrough'));\nexport const superscriptBtn = btn('superscript', 'superscript', 'Superscript', () => Style.superscript(), () => document.queryCommandState('superscript'));\nexport const subscriptBtn = btn('subscript', 'subscript', 'Subscript', () => Style.subscript(), () => document.queryCommandState('subscript'));\n\n// ---------------------------------------------------------------------------\n// Alignment buttons\n// ---------------------------------------------------------------------------\n\nexport const alignLeftBtn = btn('alignLeft', 'align-left', 'Align Left', () => Style.justifyLeft());\nexport const alignCenterBtn = btn('alignCenter', 'align-center', 'Align Center', () => Style.justifyCenter());\nexport const alignRightBtn = btn('alignRight', 'align-right', 'Align Right', () => Style.justifyRight());\nexport const alignJustifyBtn = btn('alignJustify', 'align-justify', 'Justify', () => Style.justifyFull());\n\n// ---------------------------------------------------------------------------\n// List buttons\n// ---------------------------------------------------------------------------\n\nexport const ulBtn = btn('ul', 'list-ul', 'Unordered List', () => Style.insertUnorderedList());\nexport const olBtn = btn('ol', 'list-ol', 'Ordered List', () => Style.insertOrderedList());\n\n// ---------------------------------------------------------------------------\n// Indent buttons\n// ---------------------------------------------------------------------------\n\nexport const indentBtn = btn('indent', 'indent', 'Indent', () => Style.indent());\nexport const outdentBtn = btn('outdent', 'outdent', 'Outdent', () => Style.outdent());\n\n// ---------------------------------------------------------------------------\n// Undo / redo buttons\n// ---------------------------------------------------------------------------\n\nexport const undoBtn = btn('undo', 'undo', 'Undo (Ctrl+Z)', (_ctx) => _ctx.invoke('editor.undo'), undefined, (ctx) => !ctx.invoke('editor.canUndo'));\nexport const redoBtn = btn('redo', 'redo', 'Redo (Ctrl+Y)', (_ctx) => _ctx.invoke('editor.redo'), undefined, (ctx) => !ctx.invoke('editor.canRedo'));\n\n// ---------------------------------------------------------------------------\n// Insert media — HR, Link, Image\n// ---------------------------------------------------------------------------\n\nexport const hrBtn = btn('hr', 'minus', 'Horizontal Rule', () => Style.execCommand('insertHorizontalRule'));\nexport const linkBtn = btn('link', 'link', 'Insert Link', (ctx) => ctx.invoke('linkDialog.show'));\nexport const imageBtn = btn('image', 'image', 'Insert Image', (ctx) => ctx.invoke('imageDialog.show'));\nexport const videoBtn = btn('video', 'video', 'Insert Video', (ctx) => ctx.invoke('videoDialog.show'));\nexport const emojiBtn = btn('emoji', 'emoji', 'Insert Emoji', (ctx) => ctx.invoke('emojiDialog.show'));\nexport const iconBtn = btn('icon', 'icon', 'Insert FA Icon', (ctx) => ctx.invoke('iconDialog.show'));\n\n/** @type {ButtonDef & { type: 'grid' }} */\nexport const tableBtn = {\n name: 'table',\n type: 'grid',\n icon: 'table',\n tooltip: 'Insert Table',\n action: (ctx, rows, cols) => {\n ctx.invoke('editor.insertTable', cols, rows);\n ctx.invoke('editor.afterCommand');\n },\n};\n\n// ---------------------------------------------------------------------------\n// Font size dropdown\n// ---------------------------------------------------------------------------\n\n/** @type {DropdownDef} */\nexport const fontSizeBtn = {\n name: 'fontSize',\n type: 'select',\n tooltip: 'Font Size',\n placeholder: 'Size',\n selectClass: 'an-select-narrow',\n items: ['8px', '10px', '11px', '12px', '13px', '14px', '16px', '18px', '20px', '24px', '28px', '32px', '36px', '48px', '72px'],\n action: (ctx, value) => Style.fontSize(value, ctx.layoutInfo.editable),\n getValue: (ctx) => {\n try {\n const sel = window.getSelection();\n if (sel && sel.rangeCount) {\n let el = sel.getRangeAt(0).startContainer;\n if (el.nodeType === 3) el = el.parentElement;\n while (el && el.nodeType === 1 && !el.style.fontSize) el = el.parentElement;\n const size = (el && el.style && el.style.fontSize) ? el.style.fontSize : '';\n if (size) return size;\n }\n // Fallback: read the base font size from the editable element itself\n const editable = ctx && ctx.layoutInfo && ctx.layoutInfo.editable;\n if (editable) return editable.style.fontSize || '';\n return '';\n } catch { return ''; }\n },\n};\n\n// ---------------------------------------------------------------------------\n// Remove format button\n// ---------------------------------------------------------------------------\n\nexport const removeFormatBtn = btn('removeFormat', 'remove-format', 'Remove Format', () => Style.execCommand('removeFormat'));\n\n// ---------------------------------------------------------------------------\n// Direction (LTR / RTL) toggle button\n// ---------------------------------------------------------------------------\n\nexport const directionBtn = btn(\n 'direction',\n 'direction',\n 'Toggle Text Direction (LTR / RTL)',\n (ctx) => {\n const editable = ctx.layoutInfo.editable;\n const current = editable.getAttribute('dir') || 'ltr';\n const next = current === 'ltr' ? 'rtl' : 'ltr';\n editable.setAttribute('dir', next);\n editable.style.textAlign = next === 'rtl' ? 'right' : 'left';\n ctx.invoke('editor.afterCommand');\n },\n);\n\n// ---------------------------------------------------------------------------\n// Font family dropdown\n// ---------------------------------------------------------------------------\n\n/** @type {DropdownDef} */\nexport const fontFamilyBtn = {\n name: 'fontFamily',\n type: 'select',\n tooltip: 'Font Family',\n action: (ctx, value) => Style.fontName(value),\n getValue: () => {\n try { return document.queryCommandValue('fontName') || ''; } catch { return ''; }\n },\n};\n\n// ---------------------------------------------------------------------------\n// Paragraph style dropdown (Normal / H1-H6 / Quote / Code)\n// ---------------------------------------------------------------------------\n\n/** @type {DropdownDef} */\nexport const paragraphStyleBtn = {\n name: 'paragraphStyle',\n type: 'select',\n tooltip: 'Paragraph Style',\n placeholder: 'Style',\n selectClass: 'an-select-style',\n items: [\n { value: 'p', label: 'Normal' },\n { value: 'h1', label: 'H1' },\n { value: 'h2', label: 'H2' },\n { value: 'h3', label: 'H3' },\n { value: 'h4', label: 'H4' },\n { value: 'h5', label: 'H5' },\n { value: 'h6', label: 'H6' },\n { value: 'blockquote', label: 'Quote' },\n { value: 'pre', label: 'Code' },\n ],\n action: (_ctx, value) => Style.formatBlock(value),\n getValue: () => {\n try {\n const raw = document.queryCommandValue('formatBlock').toLowerCase().replace(/[<>]/g, '');\n return raw === 'div' ? 'p' : (raw || 'p');\n } catch { return ''; }\n },\n};\n\n// ---------------------------------------------------------------------------\n// Line-height dropdown\n// ---------------------------------------------------------------------------\n\n/** @type {DropdownDef} */\nexport const lineHeightBtn = {\n name: 'lineHeight',\n type: 'select',\n tooltip: 'Line Height',\n placeholder: '\\u2195 Line',\n selectClass: 'an-select-narrow',\n items: ['1.0', '1.15', '1.5', '1.75', '2.0', '2.5', '3.0'],\n action: (_ctx, value) => Style.lineHeight(value),\n getValue: () => {\n try {\n const sel = window.getSelection();\n if (!sel || !sel.rangeCount) return '';\n const BLOCKS = new Set(['P','DIV','H1','H2','H3','H4','H5','H6','LI','BLOCKQUOTE','PRE','TD','TH']);\n let el = sel.getRangeAt(0).startContainer;\n if (el.nodeType === 3) el = el.parentElement;\n while (el && !BLOCKS.has(el.tagName)) el = el.parentElement;\n if (!el) return '';\n return el.style.lineHeight || getComputedStyle(el).lineHeight || '';\n } catch { return ''; }\n },\n};\n\n// ---------------------------------------------------------------------------\n// Code view / fullscreen\n// ---------------------------------------------------------------------------\n\nexport const codeviewBtn = btn('codeview', 'code', 'HTML Code View', (ctx) => ctx.invoke('codeview.toggle'), (ctx) => ctx.invoke('codeview.isActive'));\nexport const fullscreenBtn = btn('fullscreen', 'expand', 'Fullscreen', (ctx) => ctx.invoke('fullscreen.toggle'), (ctx) => ctx.invoke('fullscreen.isActive'));\nexport const shortcutsBtn = btn('shortcuts', 'keyboard', 'Keyboard Shortcuts (Ctrl+Shift+/)', (ctx) => ctx.invoke('shortcutsDialog.show'));\nexport const findBtn = btn('find', 'search', 'Find (Ctrl+F)', (ctx) => ctx.invoke('findReplace.show', 'find'));\nexport const findReplaceBtn = btn('findReplace', 'find-replace', 'Find & Replace (Ctrl+H)', (ctx) => ctx.invoke('findReplace.show', 'replace'));\nexport const inlineCodeBtn = btn('inlineCode', 'inline-code', 'Inline Code (Ctrl+`)', (ctx) => ctx.invoke('editor.inlineCode'), () => Style.isInlineCode());\nexport const checklistBtn = btn('checklist', 'checklist', 'Checklist', (ctx) => ctx.invoke('editor.toggleChecklist'), () => Style.isInChecklist());\nexport const printBtn = btn('print', 'print', 'Print', (ctx) => ctx.invoke('editor.print'));\n\n// ---------------------------------------------------------------------------\n// Text / background colour pickers\n// ---------------------------------------------------------------------------\n\n/** @type {{ name: string, type: 'colorpicker', icon: string, tooltip: string, defaultColor: string, action: Function }} */\nexport const foreColorBtn = {\n name: 'foreColor',\n type: 'colorpicker',\n icon: 'foreColor',\n tooltip: 'Text Color',\n defaultColor: '#e11d48',\n action: (ctx, color) => Style.foreColor(color),\n};\n\n/** @type {{ name: string, type: 'colorpicker', icon: string, tooltip: string, defaultColor: string, action: Function }} */\nexport const backColorBtn = {\n name: 'backColor',\n type: 'colorpicker',\n icon: 'backColor',\n tooltip: 'Highlight Color',\n defaultColor: '#fbbf24',\n action: (ctx, color) => Style.backColor(color),\n};\n\n// ---------------------------------------------------------------------------\n// Default toolbar layout\n// ---------------------------------------------------------------------------\n\n/**\n * The default toolbar button groups.\n * Each sub-array is a button group (separated by a divider).\n */\nexport const defaultToolbar = [\n [paragraphStyleBtn, fontFamilyBtn, fontSizeBtn, lineHeightBtn],\n [undoBtn, redoBtn],\n [boldBtn, italicBtn, underlineBtn, strikeBtn, inlineCodeBtn],\n [superscriptBtn, subscriptBtn],\n [foreColorBtn, backColorBtn],\n [alignLeftBtn, alignCenterBtn, alignRightBtn, alignJustifyBtn],\n [ulBtn, olBtn, checklistBtn, indentBtn, outdentBtn],\n [hrBtn, linkBtn, imageBtn, videoBtn, tableBtn, emojiBtn, iconBtn],\n [removeFormatBtn, codeviewBtn, fullscreenBtn, findBtn, printBtn, shortcutsBtn],\n];\n","/**\n * settings.js - Default editor options\n * Inspired by Summernote's settings.js\n */\n\nimport { defaultToolbar } from './module/Buttons.js';\n\n/**\n * @typedef {object} AsnOptions\n * @property {string} [placeholder] - Placeholder text when editor is empty\n * @property {number} [height] - Editor height in px (min)\n * @property {number} [minHeight] - Minimum height in px\n * @property {number} [maxHeight] - Maximum height in px (0 = unlimited)\n * @property {boolean} [focus] - Auto-focus on init\n * @property {boolean} [resizable] - Show resize handle\n * @property {Array} [toolbar] - Toolbar button group config\n * @property {boolean} [pasteAsPlainText] - Force plain-text paste\n * @property {boolean} [pasteCleanHTML] - Sanitise HTML on paste\n * @property {boolean} [pasteStripAttributes] - Strip class/style/data-* from pasted HTML (default: false)\n * @property {boolean} [allowImageUpload] - Allow file upload in image dialog\n * @property {number} [maxImageSize] - Max upload size in MB\n * @property {number} [tabSize] - Spaces per tab in non-list context\n * @property {Function} [onChange] - Callback on content change\n * @property {Function} [onFocus] - Callback on focus\n * @property {Function} [onBlur] - Callback on blur\n * @property {Function} [onImageUpload] - Custom upload handler: (files) => void\n * @property {boolean} [stickyToolbar] - Stick the toolbar to the viewport top when scrolling\n * @property {number} [stickyToolbarOffset] - Top offset in px for sticky toolbar (e.g. fixed nav height)\n * @property {string} [theme] - 'light' (default) | 'dark'\n * @property {boolean} [codeHighlight] - Auto-load Prism.js for syntax highlighting of code blocks\n * @property {string} [codeHighlightCDN] - CDN base URL for Prism assets (defaults to cdnjs)\n * @property {boolean} [markdownPaste] - Convert pasted Markdown text to HTML (default: true)\n * @property {boolean} [readOnly] - Start editor in read-only / non-editable mode\n * @property {boolean} [spellcheck] - Enable browser spellcheck in the editable area (default: true)\n * @property {string} [direction] - Text direction: 'ltr' (default) | 'rtl'\n * @property {string} [toolbarOverflow] - Toolbar overflow strategy: 'wrap' (default) | 'scroll'\n * @property {boolean} [autoSave] - Auto-save content to localStorage on change\n * @property {string} [autoSaveKey] - localStorage key used for auto-save (default: 'autumnnote-autosave')\n * @property {number} [maxChars] - Maximum character count (0 = unlimited). Shows warning in statusbar.\n * @property {number} [maxWords] - Maximum word count (0 = unlimited). Shows warning in statusbar.\n * @property {boolean} [tableHeaderRow] - Insert a header row (<thead><th>) when creating tables\n * @property {Function} [onPaste] - Callback fired on every paste: ({ text, html }) => void\n * @property {Function} [onSelectionChange] - Callback fired on cursor/selection change: (context) => void\n * @property {string[]} [colorSwatches] - Custom brand colour swatches prepended to the colour-picker palette\n * @property {Function} [onDestroy] - Callback fired when the editor is destroyed: (context) => void\n * @property {Function} [onCharLimitReached] - Callback fired when the character limit is hit: (context) => void\n * @property {Function} [onWordLimitReached] - Callback fired when the word limit is hit: (context) => void\n * @property {string} [focusColor] - Custom focus ring colour, e.g. '#f97316'. Overrides the default blue.\n */\n\n/** @type {AsnOptions} */\nexport const defaultOptions = {\n placeholder: '',\n height: 200,\n minHeight: 100,\n maxHeight: 0,\n focus: false,\n resizable: true,\n toolbar: defaultToolbar,\n // UI integration options\n // If `useBootstrap` is true, toolbar buttons will use the Bootstrap button classes\n // (set `toolbarButtonClass` to customize). Works with Bootstrap 4 and 5.\n useBootstrap: false,\n toolbarButtonClass: 'btn btn-sm btn-light',\n // Icon options — uses Font Awesome by default. Consumers must include Font Awesome CSS.\n useFontAwesome: true,\n // Default FontAwesome prefix — 'fas' for FA5, 'fa-solid' for FA6. Change if needed.\n fontAwesomeClass: 'fas',\n pasteAsPlainText: false,\n pasteCleanHTML: true,\n pasteStripAttributes: false,\n allowImageUpload: true,\n maxImageSize: 5,\n tabSize: 4,\n onChange: null,\n onFocus: null,\n onBlur: null,\n onInit: null,\n onImageUpload: null,\n onImageError: null,\n stickyToolbar: false,\n stickyToolbarOffset: 0,\n theme: 'light',\n codeHighlight: true,\n codeHighlightCDN: 'https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0',\n markdownPaste: true,\n historyLimit: 100,\n // Default font family applied to the editor and shown in the dropdown when no explicit font is set\n defaultFontFamily: 'Arial',\n // Default font size applied to the editor and shown in the size dropdown when no explicit size is set\n defaultFontSize: '14px',\n // Font families shown in the toolbar font-family dropdown\n fontFamilies: [\n 'Arial',\n 'Arial Black',\n 'Comic Sans MS',\n 'Courier New',\n 'Georgia',\n 'Impact',\n 'Tahoma',\n 'Times New Roman',\n 'Trebuchet MS',\n 'Verdana',\n ],\n // Read-only mode — disables all editing when true\n readOnly: false,\n // Enable/disable browser spell-check on the editable area\n spellcheck: true,\n // Text direction: 'ltr' (default) or 'rtl'\n direction: 'ltr',\n // How the toolbar handles overflow: 'wrap' (default, wraps to next line) or 'scroll' (single scrollable row)\n toolbarOverflow: 'wrap',\n // Auto-save content to localStorage on every change\n autoSave: false,\n // localStorage key used when autoSave is enabled\n autoSaveKey: 'autumnnote-autosave',\n // Maximum character count (0 = unlimited)\n maxChars: 0,\n // Maximum word count (0 = unlimited)\n maxWords: 0,\n // Insert a header row (<thead>) when creating new tables\n tableHeaderRow: false,\n // Callback fired on every cursor/selection change inside the editor\n onSelectionChange: null,\n // Custom brand colour swatches to prepend to the toolbar colour-picker palette\n colorSwatches: [],\n // Callback fired after a paste event: function({ text, html })\n onPaste: null,\n // Callback fired just before the editor instance is destroyed\n onDestroy: null,\n // Callback fired when the character limit is reached: function(context)\n onCharLimitReached: null,\n // Callback fired when the word limit is reached: function(context)\n onWordLimitReached: null,\n // Custom focus ring colour — overrides the default blue when set.\n // Accepts any valid CSS colour string, e.g. '#f97316', 'hsl(25,90%,55%)'.\n focusColor: null,\n};\n","/**\n * sanitise.js - Shared HTML and URL sanitisation utilities\n *\n * Single source of truth used by Editor, Clipboard, Codeview, and renderer.\n * DOM-parser based — no regex-based stripping of HTML (avoids bypass tricks).\n */\n\n/** Tags that are unconditionally removed from editor content. */\nconst PROHIBITED_TAGS = ['script', 'style', 'iframe', 'object', 'embed', 'form', 'input', 'button'];\n\n/** Attributes whose values must be sanitised as URLs. */\nconst URL_ATTRS = ['href', 'src', 'action', 'formaction'];\n\n/** Trusted hosts for iframe embeds when allowIframes is enabled. */\nconst TRUSTED_IFRAME_HOSTS = new Set([\n 'www.youtube.com',\n 'youtube.com',\n 'm.youtube.com',\n 'www.youtube-nocookie.com',\n 'youtube-nocookie.com',\n 'player.vimeo.com',\n]);\n\n/**\n * Sanitises an HTML string by removing dangerous elements and attributes.\n * Uses DOMParser so the sanitisation follows normal browser parsing rules —\n * no regex shortcuts that can be bypassed by encoding tricks.\n *\n * - Strips PROHIBITED_TAGS (script, style, iframe, object, embed, form, input, button)\n * - Removes all on* event-handler attributes\n * - Rejects javascript: and vbscript: URLs in URL attributes\n * - Rejects data: URIs everywhere except img[src] (base64 uploads)\n *\n * @param {string} html\n * @returns {string}\n */\nexport function sanitiseHTML(html, { allowIframes = false } = {}) {\n const doc = new DOMParser().parseFromString(`<body>${html || ''}</body>`, 'text/html');\n\n // Remove outright dangerous elements (optionally preserve iframes for video embeds)\n const tags = allowIframes ? PROHIBITED_TAGS.filter((t) => t !== 'iframe') : PROHIBITED_TAGS;\n tags.forEach((tag) => {\n doc.querySelectorAll(tag).forEach((el) => el.remove());\n });\n\n // Strip dangerous attributes from remaining elements\n doc.querySelectorAll('*').forEach((el) => {\n Array.from(el.attributes).forEach((attr) => {\n // Remove all event handlers (onclick, onload, onerror, …)\n if (attr.name.startsWith('on')) {\n el.removeAttribute(attr.name);\n return;\n }\n // Sanitise URL attributes\n if (URL_ATTRS.includes(attr.name)) {\n const val = attr.value.trim();\n // Block javascript: and vbscript: protocols\n if (/^(javascript|vbscript):/i.test(val)) {\n el.removeAttribute(attr.name);\n return;\n }\n // Allow data: URIs only on img[src] (base64 image uploads); block elsewhere\n if (/^data:/i.test(val) && !(attr.name === 'src' && el.tagName === 'IMG')) {\n el.removeAttribute(attr.name);\n }\n }\n\n // Strip iframe HTML-injection vectors and limit iframe src to trusted hosts.\n if (el.tagName === 'IFRAME') {\n if (attr.name === 'srcdoc') {\n el.removeAttribute(attr.name);\n return;\n }\n if (attr.name === 'src') {\n if (!isTrustedIframeSrc(attr.value)) {\n el.removeAttribute(attr.name);\n }\n return;\n }\n }\n });\n });\n\n return doc.body.innerHTML;\n}\n\n/**\n * Returns true if iframe src points to an approved video host.\n * Relative, protocol-relative and invalid URLs are rejected.\n * @param {string} src\n * @returns {boolean}\n */\nfunction isTrustedIframeSrc(src) {\n const trimmed = (src || '').trim();\n if (!trimmed) return false;\n if (trimmed.startsWith('//') || trimmed.startsWith('/')) return false;\n try {\n const url = new URL(trimmed);\n if (url.protocol !== 'https:') return false;\n return TRUSTED_IFRAME_HOSTS.has(url.hostname.toLowerCase());\n } catch {\n return false;\n }\n}\n\n/**\n * Sanitises a URL string, rejecting dangerous protocols.\n *\n * Blocked protocols: javascript:, vbscript:\n * Optionally blocked: data: (safe to allow for img/src base64 embeds)\n *\n * @param {string} url\n * @param {{ allowData?: boolean }} [opts]\n * @returns {string|null} The original URL if safe, null if rejected.\n */\nexport function sanitiseUrl(url, { allowData = false } = {}) {\n const trimmed = (url || '').trim();\n if (/^(javascript|vbscript):/i.test(trimmed)) return null;\n if (!allowData && /^data:/i.test(trimmed)) return null;\n return url;\n}\n","/**\n * renderer.js - Builds the editor DOM structure\n * Inspired by Summernote's renderer.js\n */\n\nimport { createElement } from './core/dom.js';\nimport { sanitiseHTML } from './core/sanitise.js';\n\n/**\n * Renders the editor layout around the original element.\n *\n * Structure:\n * <div class=\"an-container\">\n * <div class=\"an-toolbar\">...</div>\n * <div class=\"an-editable\" contenteditable=\"true\">...</div>\n * <div class=\"an-statusbar\">...</div>\n * </div>\n *\n * @param {HTMLElement} targetEl - the original element to replace/wrap\n * @param {import('./settings.js').AsnOptions} options\n * @returns {{ container: HTMLElement, editable: HTMLElement }}\n */\nexport function renderLayout(targetEl, options) {\n const container = createElement('div', { class: 'an-container' });\n\n // Editable area\n const editable = createElement('div', {\n class: 'an-editable',\n contenteditable: options.readOnly ? 'false' : 'true',\n spellcheck: String(options.spellcheck !== false),\n 'aria-multiline': 'true',\n 'aria-label': 'Rich text editor',\n role: 'textbox',\n });\n\n // Restore auto-saved content when available; fall back to element content\n let initialContent = '';\n if (options.autoSave && options.autoSaveKey) {\n try { initialContent = localStorage.getItem(options.autoSaveKey) || ''; } catch (_) {}\n }\n if (!initialContent) {\n initialContent = targetEl.tagName === 'TEXTAREA'\n ? (targetEl.value || '').trim()\n : (targetEl.innerHTML || '').trim();\n }\n editable.innerHTML = sanitiseHTML(initialContent, { allowIframes: true });\n\n // Apply default font family so the editable renders in the configured font\n const defaultFont = options.defaultFontFamily || (options.fontFamilies && options.fontFamilies[0]);\n if (defaultFont) {\n editable.style.fontFamily = defaultFont;\n }\n\n // Apply default font size so the size dropdown shows the correct value on startup\n if (options.defaultFontSize) {\n editable.style.fontSize = options.defaultFontSize;\n }\n\n // Apply height options.\n // `height` sets the initial visible height (takes priority).\n // `minHeight` is the drag-resize floor — only applied when no explicit `height` is given.\n if (options.height) {\n editable.style.minHeight = `${options.height}px`;\n } else if (options.minHeight) {\n editable.style.minHeight = `${options.minHeight}px`;\n }\n if (options.maxHeight) {\n editable.style.maxHeight = `${options.maxHeight}px`;\n }\n\n container.appendChild(editable);\n\n // Apply dark theme\n if (options.theme === 'dark') {\n container.classList.add('an-theme-dark');\n }\n\n // Read-only mode\n if (options.readOnly) {\n container.classList.add('an-disabled');\n }\n\n // Text direction\n if (options.direction === 'rtl') {\n editable.setAttribute('dir', 'rtl');\n container.classList.add('an-dir-rtl');\n }\n\n // Toolbar overflow\n if (options.toolbarOverflow === 'scroll') {\n container.classList.add('an-toolbar-overflow-scroll');\n }\n\n // Configure sticky toolbar\n if (options.stickyToolbar) {\n container.classList.add('an-sticky-toolbar');\n if (options.stickyToolbarOffset) {\n container.style.setProperty('--an-sticky-top', `${options.stickyToolbarOffset}px`);\n }\n }\n\n // Custom focus ring colour\n if (options.focusColor) {\n container.style.setProperty('--an-focus-color', options.focusColor);\n }\n\n // Hide the original element; keep it in DOM for form submission\n targetEl.style.display = 'none';\n targetEl.insertAdjacentElement('afterend', container);\n\n return { container, editable };\n}\n","/**\n * History.js - Undo / redo stack for editor content\n * Inspired by Summernote's History module, rewritten without jQuery\n */\n\nexport class History {\n /**\n * @param {HTMLElement} editable - the contenteditable element\n * @param {number} [limit=100] - maximum number of undo/redo states\n */\n constructor(editable, limit = 100) {\n this.editable = editable;\n this._limit = limit;\n /** @type {Array<{html: string, range: {sc: string, so: number, ec: string, eo: number}|null}>} */\n this.stack = [];\n this.stackOffset = -1;\n this._savePoint();\n }\n\n // ---------------------------------------------------------------------------\n // Private helpers\n // ---------------------------------------------------------------------------\n\n _serialize() {\n return this.editable.innerHTML;\n }\n\n /**\n * Serializes the current selection as character offsets from the start of\n * the editable element, so it can be restored after innerHTML replacement.\n * @returns {{ start: number, end: number }|null}\n */\n _serializeSelection() {\n const sel = window.getSelection();\n if (!sel || sel.rangeCount === 0) return null;\n const range = sel.getRangeAt(0);\n if (!this.editable.contains(range.startContainer)) return null;\n return {\n start: this._charOffset(range.startContainer, range.startOffset),\n end: this._charOffset(range.endContainer, range.endOffset),\n };\n }\n\n /**\n * Returns the character offset of (node, offset) from the beginning of\n * the editable's text content.\n * @param {Node} node\n * @param {number} offset\n * @returns {number}\n */\n _charOffset(node, offset) {\n let count = 0;\n const walker = document.createTreeWalker(this.editable, NodeFilter.SHOW_TEXT, null);\n let cur;\n while ((cur = walker.nextNode())) {\n if (cur === node) return count + offset;\n count += cur.length;\n }\n return 0;\n }\n\n /**\n * Restores a previously serialized selection inside the editable.\n * @param {{ start: number, end: number }|null} saved\n */\n _restoreSelection(saved) {\n if (!saved) return;\n let startNode = null, startOff = 0;\n let endNode = null, endOff = 0;\n let count = 0;\n const walker = document.createTreeWalker(this.editable, NodeFilter.SHOW_TEXT, null);\n let cur;\n while ((cur = walker.nextNode())) {\n const len = cur.length;\n if (!startNode && count + len >= saved.start) {\n startNode = cur;\n startOff = saved.start - count;\n }\n if (!endNode && count + len >= saved.end) {\n endNode = cur;\n endOff = saved.end - count;\n break;\n }\n count += len;\n }\n if (!startNode) {\n // Offset exceeds content (e.g. undo to a shorter state): place at end\n const lastWalker = document.createTreeWalker(this.editable, NodeFilter.SHOW_TEXT, null);\n let lastNode = null;\n while ((lastNode = lastWalker.nextNode())) { startNode = lastNode; }\n startOff = startNode ? startNode.length : 0;\n endNode = startNode;\n endOff = startOff;\n }\n if (!endNode) { endNode = startNode; endOff = startOff; }\n try {\n const range = document.createRange();\n range.setStart(startNode, startOff);\n range.setEnd(endNode, endOff);\n const sel = window.getSelection();\n sel.removeAllRanges();\n sel.addRange(range);\n } catch (_) { /* detached node — ignore */ }\n }\n\n _savePoint() {\n // Trim future history if we're mid-stack\n if (this.stackOffset < this.stack.length - 1) {\n this.stack = this.stack.slice(0, this.stackOffset + 1);\n }\n const raw = this._serialize();\n const { html, images } = this._tokenizeImages(raw);\n this.stack.push({ html, images, sel: this._serializeSelection() });\n if (this.stack.length > this._limit) {\n this.stack.shift();\n } else {\n this.stackOffset++;\n }\n }\n\n _restore(point) {\n if (!point) return;\n this.editable.innerHTML = this._detokenizeImages(point);\n this._restoreSelection(point.sel);\n }\n\n // ---------------------------------------------------------------------------\n // Base64 tokenisation — keeps snapshot strings small so that the\n // per-keystroke `recordUndo` string comparison stays fast even when the\n // editor contains large embedded images.\n // ---------------------------------------------------------------------------\n\n /**\n * Replaces every `data:…;base64,…` occurrence in `html` with a compact\n * token `__asn_img_0__`, `__asn_img_1__`, … and returns the tokenized\n * string together with a map from token → original data URL.\n * @param {string} html\n * @returns {{ html: string, images: Object<string,string> }}\n */\n _tokenizeImages(html) {\n const images = {};\n let index = 0;\n const tokenized = html.replace(/data:[^;]+;base64,[^\"' >]*/g, (match) => {\n const token = `__asn_img_${index}__`;\n images[token] = match;\n index++;\n return token;\n });\n return { html: tokenized, images };\n }\n\n /**\n * Restores a snapshot by replacing tokens back with their data URLs.\n * @param {{ html: string, images: Object<string,string> }} point\n * @returns {string}\n */\n _detokenizeImages(point) {\n if (!point.images || Object.keys(point.images).length === 0) return point.html;\n return point.html.replace(/__asn_img_\\d+__/g, (token) => point.images[token] || token);\n }\n\n // ---------------------------------------------------------------------------\n // Public API\n // ---------------------------------------------------------------------------\n\n /**\n * Records the current editor state as a history checkpoint.\n */\n recordUndo() {\n const current = this._serialize();\n const { html: tokenized } = this._tokenizeImages(current);\n const prev = this.stack[this.stackOffset];\n if (prev && prev.html === tokenized) return; // No change\n this._savePoint();\n }\n\n /**\n * Undo to the previous state.\n */\n undo() {\n if (this.stackOffset <= 0) return;\n this.stackOffset--;\n this._restore(this.stack[this.stackOffset]);\n }\n\n /**\n * Redo to the next state.\n */\n redo() {\n if (this.stackOffset >= this.stack.length - 1) return;\n this.stackOffset++;\n this._restore(this.stack[this.stackOffset]);\n }\n\n /**\n * Resets the history stack (e.g. on editor destroy or full content replace).\n */\n reset() {\n this.stack = [];\n this.stackOffset = -1;\n this._savePoint();\n }\n\n /** @returns {boolean} */\n canUndo() {\n return this.stackOffset > 0;\n }\n\n /** @returns {boolean} */\n canRedo() {\n return this.stackOffset < this.stack.length - 1;\n }\n}\n","/**\n * Table.js - Table creation and manipulation utilities\n * Inspired by Summernote's table handling\n */\n\nimport { createElement } from '../core/dom.js';\nimport { execCommand } from './Style.js';\n\n// ---------------------------------------------------------------------------\n// Table creation\n// ---------------------------------------------------------------------------\n\n/**\n * Creates a table element with the specified dimensions.\n * @param {number} cols\n * @param {number} rows\n * @param {{ headerRow?: boolean }} [opts]\n * @returns {HTMLTableElement}\n */\nexport function createTable(cols, rows, opts = {}) {\n const { headerRow = false } = opts;\n const table = createElement('table', { class: 'an-table' });\n\n if (headerRow && rows > 0) {\n const thead = createElement('thead');\n const tr = createElement('tr');\n for (let c = 0; c < cols; c++) {\n const th = createElement('th', {}, ['\\u00a0']);\n tr.appendChild(th);\n }\n thead.appendChild(tr);\n table.appendChild(thead);\n }\n\n const bodyRows = headerRow ? Math.max(rows - 1, 1) : rows;\n const tbody = createElement('tbody');\n table.appendChild(tbody);\n\n for (let r = 0; r < bodyRows; r++) {\n const tr = createElement('tr');\n for (let c = 0; c < cols; c++) {\n const td = createElement('td', {}, ['\\u00a0']); // \n tr.appendChild(td);\n }\n tbody.appendChild(tr);\n }\n return table;\n}\n\n/**\n * Inserts a table at the current cursor position.\n * @param {number} cols\n * @param {number} rows\n * @param {{ headerRow?: boolean }} [opts]\n */\nexport function insertTable(cols, rows, opts = {}) {\n const table = createTable(cols, rows, opts);\n execCommand('insertHTML', table.outerHTML);\n}\n","/**\n * key.js - Keyboard key code constants\n * Inspired by Summernote's key.js\n */\n\nexport const key = {\n BACKSPACE: 'Backspace',\n TAB: 'Tab',\n ENTER: 'Enter',\n ESCAPE: 'Escape',\n SPACE: ' ',\n PAGE_UP: 'PageUp',\n PAGE_DOWN: 'PageDown',\n END: 'End',\n HOME: 'Home',\n LEFT: 'ArrowLeft',\n UP: 'ArrowUp',\n RIGHT: 'ArrowRight',\n DOWN: 'ArrowDown',\n DELETE: 'Delete',\n // Numbers\n NUM0: '0',\n NUM1: '1',\n NUM2: '2',\n NUM3: '3',\n NUM4: '4',\n NUM5: '5',\n NUM6: '6',\n NUM7: '7',\n NUM8: '8',\n // Letters\n B: 'b',\n E: 'e',\n I: 'i',\n J: 'j',\n K: 'k',\n L: 'l',\n R: 'r',\n S: 's',\n U: 'u',\n V: 'v',\n Y: 'y',\n Z: 'z',\n SLASH: '/',\n PERIOD: '.',\n};\n\n/**\n * Returns true if the event matches the given key\n * @param {KeyboardEvent} event\n * @param {string} keyName - one of key.*\n * @returns {boolean}\n */\nexport function isKey(event, keyName) {\n return event.key === keyName || event.key === keyName.toUpperCase();\n}\n\n/**\n * Returns true if the event is a modifier key press (Ctrl/Cmd + key)\n * @param {KeyboardEvent} event\n * @param {string} keyName\n * @returns {boolean}\n */\nexport function isModifier(event, keyName) {\n return (event.ctrlKey || event.metaKey) && isKey(event, keyName);\n}\n","/**\n * Typing.js - Keyboard typing event handling (Enter, Tab, Backspace behaviour)\n * Inspired by Summernote's Typing module\n */\n\nimport { key, isKey } from '../core/key.js';\nimport { closestPara, isLi } from '../core/dom.js';\nimport { execCommand } from './Style.js';\nimport { currentRange } from '../core/range.js';\n\n/**\n * Handles special keydown behaviour inside the editor.\n * @param {KeyboardEvent} event\n * @param {HTMLElement} editable\n * @param {object} options - editor options\n * @returns {boolean} true if the event was consumed\n */\nexport function handleKeydown(event, editable, options = {}) {\n const isFAIcon = (n) => !!(n && n.nodeName === 'I' && /\\bfa-/.test(n.className || ''));\n const isZwsAnchor = (n) => !!(n && n.nodeType === Node.TEXT_NODE && (n.textContent === '\\u200B' || n.textContent === ''));\n const moveCaret = (setFn) => {\n const sel = window.getSelection();\n if (!sel) return false;\n const nr = document.createRange();\n setFn(nr);\n nr.collapse(true);\n sel.removeAllRanges();\n sel.addRange(nr);\n return true;\n };\n\n // -------------------------------------------------------------------------\n // Backspace key — one-press deletion of a preceding FA icon (<i> element)\n // -------------------------------------------------------------------------\n if (isKey(event, key.BACKSPACE)) {\n const sel = window.getSelection();\n if (sel && sel.rangeCount > 0) {\n const r = sel.getRangeAt(0);\n if (r.collapsed && r.startContainer.nodeType === Node.TEXT_NODE) {\n const textNode = r.startContainer;\n // Case A: cursor at offset 0, preceding sibling is an FA icon\n if (r.startOffset === 0 && isFAIcon(textNode.previousSibling)) {\n event.preventDefault();\n textNode.previousSibling.remove();\n return true;\n }\n\n // Case B: cursor at offset 1 of a ZWS-only text node whose preceding\n // sibling is an FA icon. The ZWS is the invisible caret anchor inserted\n // by IconDialog; treat the whole Backspace as \"delete icon + its anchor\".\n if (r.startOffset === 1 && textNode.textContent === '\\u200B' &&\n isFAIcon(textNode.previousSibling)) {\n event.preventDefault();\n textNode.previousSibling.remove();\n textNode.remove();\n return true;\n }\n }\n }\n return false;\n }\n\n // -------------------------------------------------------------------------\n // ArrowLeft / ArrowRight — one-press navigation across FA icon nodes\n // -------------------------------------------------------------------------\n if (isKey(event, key.LEFT) || isKey(event, key.RIGHT)) {\n const sel = window.getSelection();\n if (!sel || sel.rangeCount === 0) return false;\n\n const r = sel.getRangeAt(0);\n if (!r.collapsed) return false;\n\n const sc = r.startContainer;\n const movingLeft = isKey(event, key.LEFT);\n\n if (sc.nodeType === Node.TEXT_NODE) {\n const textNode = sc;\n\n if (movingLeft &&\n r.startOffset === 1 &&\n textNode.textContent === '\\u200B' &&\n isFAIcon(textNode.previousSibling)) {\n event.preventDefault();\n return moveCaret((nr) => nr.setStartBefore(textNode.previousSibling));\n }\n\n if (movingLeft && r.startOffset === 0 && isFAIcon(textNode.previousSibling)) {\n event.preventDefault();\n return moveCaret((nr) => nr.setStartBefore(textNode.previousSibling));\n }\n\n if (movingLeft &&\n r.startOffset === 0 &&\n isZwsAnchor(textNode.previousSibling) &&\n isFAIcon(textNode.previousSibling.previousSibling)) {\n event.preventDefault();\n return moveCaret((nr) => nr.setStartBefore(textNode.previousSibling.previousSibling));\n }\n\n if (!movingLeft &&\n r.startOffset === textNode.textContent.length &&\n isFAIcon(textNode.nextSibling)) {\n const icon = textNode.nextSibling;\n const after = icon.nextSibling;\n event.preventDefault();\n if (after && after.nodeType === Node.TEXT_NODE) {\n const offset = ((after.textContent || '').startsWith('\\u200B')) ? 1 : 0;\n return moveCaret((nr) => nr.setStart(after, Math.min(offset, after.textContent.length)));\n }\n return moveCaret((nr) => nr.setStartAfter(icon));\n }\n\n if (!movingLeft &&\n r.startOffset === textNode.textContent.length &&\n isZwsAnchor(textNode.nextSibling) &&\n isFAIcon(textNode.nextSibling.nextSibling)) {\n const icon = textNode.nextSibling.nextSibling;\n const after = icon.nextSibling;\n event.preventDefault();\n if (after && after.nodeType === Node.TEXT_NODE) {\n const offset = ((after.textContent || '').startsWith('\\u200B')) ? 1 : 0;\n return moveCaret((nr) => nr.setStart(after, Math.min(offset, after.textContent.length)));\n }\n return moveCaret((nr) => nr.setStartAfter(icon));\n }\n }\n\n if (sc.nodeType === Node.ELEMENT_NODE) {\n const el = sc;\n if (movingLeft && r.startOffset > 0) {\n const prev = el.childNodes[r.startOffset - 1];\n if (isFAIcon(prev)) {\n event.preventDefault();\n return moveCaret((nr) => nr.setStartBefore(prev));\n }\n if (isZwsAnchor(prev) && isFAIcon(prev.previousSibling)) {\n event.preventDefault();\n return moveCaret((nr) => nr.setStartBefore(prev.previousSibling));\n }\n }\n if (!movingLeft && r.startOffset < el.childNodes.length) {\n const next = el.childNodes[r.startOffset];\n if (isFAIcon(next)) {\n const after = next.nextSibling;\n event.preventDefault();\n if (after && after.nodeType === Node.TEXT_NODE) {\n const offset = ((after.textContent || '').startsWith('\\u200B')) ? 1 : 0;\n return moveCaret((nr) => nr.setStart(after, Math.min(offset, after.textContent.length)));\n }\n return moveCaret((nr) => nr.setStartAfter(next));\n }\n if (isZwsAnchor(next) && isFAIcon(next.nextSibling)) {\n const icon = next.nextSibling;\n const after = icon.nextSibling;\n event.preventDefault();\n if (after && after.nodeType === Node.TEXT_NODE) {\n const offset = ((after.textContent || '').startsWith('\\u200B')) ? 1 : 0;\n return moveCaret((nr) => nr.setStart(after, Math.min(offset, after.textContent.length)));\n }\n return moveCaret((nr) => nr.setStartAfter(icon));\n }\n }\n }\n }\n\n // -------------------------------------------------------------------------\n // Tab key — indent / outdent list items, or insert soft tab in code blocks\n // -------------------------------------------------------------------------\n if (isKey(event, key.TAB)) {\n const range = currentRange(editable);\n if (!range) return false;\n\n const para = closestPara(range.sc, editable);\n if (para && isLi(para)) {\n event.preventDefault();\n if (event.shiftKey) {\n execCommand('outdent');\n } else {\n execCommand('indent');\n }\n return true;\n }\n\n // In a pre/code block, insert spaces\n if (para && para.nodeName.toUpperCase() === 'PRE') {\n if (event.shiftKey) return false;\n event.preventDefault();\n execCommand('insertText', ' ');\n return true;\n }\n\n // Default: insert * tabSize\n if (options.tabSize) {\n if (event.shiftKey) return false;\n event.preventDefault();\n execCommand('insertText', ' '.repeat(options.tabSize));\n return true;\n }\n }\n\n // -------------------------------------------------------------------------\n // Shift+Enter — insert <br> instead of opening a new block element\n // -------------------------------------------------------------------------\n if (isKey(event, key.ENTER) && event.shiftKey) {\n event.preventDefault();\n execCommand('insertLineBreak');\n return true;\n }\n\n // -------------------------------------------------------------------------\n // Enter key — keep consistent paragraph insertion\n // -------------------------------------------------------------------------\n if (isKey(event, key.ENTER) && !event.shiftKey) {\n const range = currentRange(editable);\n if (!range) return false;\n\n // Hoist sc/el once so all guards below can reuse them.\n const sc = range.sc;\n const el = sc.nodeType === 3 ? sc.parentElement : sc;\n\n // Guard: if the cursor is inside a <i> FA icon element (zero text children,\n // rendered entirely by CSS ::before), pressing Enter would split the block\n // and leave an orphan <i> in the new paragraph — visually an \"auto-created\n // icon\". Push the cursor to just after the <i> first, then fall through so\n // the browser fires its default Enter at a safe text boundary.\n if (el && el.nodeName === 'I' && /\\bfa-/.test(el.className || '')) {\n const nr = document.createRange();\n nr.setStartAfter(el);\n nr.collapse(true);\n const selI = window.getSelection();\n if (selI) { selI.removeAllRanges(); selI.addRange(nr); }\n return false; // cursor is now outside <i> — let browser default handle Enter\n }\n\n // Video wrapper — Enter should create a new paragraph after the wrapper,\n // not split the wrapper's container and produce an empty video clone.\n const videoWrapper = el && el.closest && el.closest('.an-video-wrapper');\n if (videoWrapper) {\n event.preventDefault();\n const p = document.createElement('p');\n p.innerHTML = '\\u00a0';\n videoWrapper.parentNode.insertBefore(p, videoWrapper.nextSibling);\n const nr = document.createRange();\n nr.setStart(p, 0);\n nr.collapse(true);\n const sel = window.getSelection();\n sel.removeAllRanges();\n sel.addRange(nr);\n return true;\n }\n\n // Checklist — Enter creates new item; empty item exits the list\n const checkLi = el && el.closest && el.closest('.an-checklist li');\n if (checkLi) {\n event.preventDefault();\n const ul = checkLi.closest('.an-checklist');\n const sel = window.getSelection();\n let nativeRange = sel.getRangeAt(0);\n\n // Helper: get trimmed text content of a li, excluding the checkbox INPUT.\n // Strip both \\u00a0 (placeholder nbsp) and \\u200B (ZWS cursor anchors).\n const liText = (li) =>\n Array.from(li.childNodes)\n .filter((n) => !(n.nodeType === 1 && n.tagName === 'INPUT'))\n .map((n) => n.textContent).join('').replace(/[\\u00a0\\u200B]/g, ' ').trim();\n\n // 1. Check if the ENTIRE item is empty BEFORE any DOM mutation.\n // (Do NOT check only the \"before-cursor\" part — that check incorrectly\n // exits the list when cursor is at the start of a non-empty item.)\n if (!liText(checkLi)) {\n // Empty item — exit checklist, insert <p> after list\n const p = document.createElement('p');\n p.innerHTML = '\\u00a0';\n ul.parentNode.insertBefore(p, ul.nextSibling);\n checkLi.remove();\n if (ul.children.length === 0) ul.remove();\n const nr = document.createRange();\n nr.setStart(p.firstChild, 0);\n nr.collapse(true);\n sel.removeAllRanges();\n sel.addRange(nr);\n return true;\n }\n\n // 2. If selection is not collapsed, delete the selected content first —\n // mirrors browser-default Enter behaviour (delete selection, then split).\n if (!nativeRange.collapsed) {\n nativeRange.deleteContents();\n // nativeRange is now collapsed at the deletion point; re-read it\n nativeRange = sel.getRangeAt(0);\n }\n\n // 3. Extract everything from cursor to end of li into afterFrag.\n // Use startContainer/startOffset (cursor position after potential delete),\n // NOT endContainer/endOffset which is wrong for non-collapsed ranges.\n const afterRange = document.createRange();\n afterRange.setStart(nativeRange.startContainer, nativeRange.startOffset);\n afterRange.setEnd(checkLi, checkLi.childNodes.length);\n const afterFrag = afterRange.extractContents();\n\n // 4. Build the new checklist item with the extracted \"after\" content.\n const newLi = document.createElement('li');\n const cb = document.createElement('input');\n cb.type = 'checkbox';\n cb.setAttribute('contenteditable', 'false');\n newLi.appendChild(cb);\n\n // Append extracted \"after\" content (if any) then insert the new item.\n if (afterFrag.textContent.replace(/[\\u00a0\\u200B]/g, '').length > 0) {\n newLi.appendChild(afterFrag);\n }\n\n // Always ensure a text node exists so the cursor has a text-level\n // anchor. Use \\u200B (zero-width space) instead of an empty string:\n // Chrome does not reliably honour a Selection in an empty text node and\n // may normalise it to element-level, placing the caret before the\n // absolutely-positioned checkbox. \\u200B is stripped by getHTML().\n let cursorNode = newLi.childNodes[1]; // first child after checkbox\n if (!cursorNode || cursorNode.nodeType !== Node.TEXT_NODE) {\n cursorNode = document.createTextNode('\\u200B');\n newLi.appendChild(cursorNode);\n }\n checkLi.insertAdjacentElement('afterend', newLi);\n\n const nr = document.createRange();\n nr.setStart(cursorNode, 0);\n nr.collapse(true);\n sel.removeAllRanges();\n sel.addRange(nr);\n return true;\n }\n\n const para = closestPara(range.sc, editable);\n\n // Pressing Enter at the end of a blockquote should exit it\n if (para && para.nodeName.toUpperCase() === 'BLOCKQUOTE') {\n const native = range.toNativeRange();\n native.setEnd(para, para.childNodes.length);\n if (native.toString() === '' && range.isCollapsed()) {\n event.preventDefault();\n execCommand('formatBlock', '<p>');\n return true;\n }\n }\n }\n\n return false;\n}\n","/**\n * markdown.js - Lightweight Markdown → HTML converter for paste handling.\n *\n * Handles: headings H1–H6, bold/italic/strikethrough/inline-code, fenced code\n * blocks (with language), blockquotes, unordered/ordered lists, horizontal\n * rules, links, images, and plain paragraphs.\n *\n * The HTML output MUST be passed through sanitiseHTML() before insertion.\n */\n\n/**\n * Converts an HTML string to Markdown.\n * Handles: headings, paragraphs, bold/italic/del/code, links, images,\n * unordered/ordered lists, blockquote, pre/code blocks, tables, hr.\n * @param {string} html\n * @returns {string}\n */\nexport function htmlToMarkdown(html) {\n const doc = new DOMParser().parseFromString(`<body>${html || ''}</body>`, 'text/html');\n return _domToMd(doc.body).replace(/\\n{3,}/g, '\\n\\n').trim();\n}\n\nfunction _domToMd(node) {\n if (node.nodeType === 3) {\n return node.textContent.replace(/\\s+/g, ' ');\n }\n if (node.nodeType !== 1) return '';\n\n const tag = node.nodeName.toLowerCase();\n const inner = () => Array.from(node.childNodes).map(_domToMd).join('');\n\n switch (tag) {\n case 'p':\n case 'div': return `\\n\\n${inner()}\\n\\n`;\n case 'br': return ' \\n';\n case 'h1': return `\\n\\n# ${inner()}\\n\\n`;\n case 'h2': return `\\n\\n## ${inner()}\\n\\n`;\n case 'h3': return `\\n\\n### ${inner()}\\n\\n`;\n case 'h4': return `\\n\\n#### ${inner()}\\n\\n`;\n case 'h5': return `\\n\\n##### ${inner()}\\n\\n`;\n case 'h6': return `\\n\\n###### ${inner()}\\n\\n`;\n case 'strong':\n case 'b': return `**${inner()}**`;\n case 'em':\n case 'i': return `*${inner()}*`;\n case 'del':\n case 's':\n case 'strike': return `~~${inner()}~~`;\n case 'sup': return `^${inner()}`;\n case 'sub': return `~${inner()}`;\n case 'code': {\n // Inside <pre> we emit raw text; outside we wrap in backticks\n if (node.closest('pre')) return inner();\n return `\\`${inner()}\\``;\n }\n case 'pre': {\n const codeEl = node.querySelector('code');\n const langMatch = ((codeEl && codeEl.className) || '').match(/language-(\\S+)/);\n const lang = langMatch ? langMatch[1] : '';\n const content = (codeEl || node).textContent || '';\n return `\\n\\n\\`\\`\\`${lang}\\n${content}\\n\\`\\`\\`\\n\\n`;\n }\n case 'blockquote': {\n const lines = inner().trim().split('\\n');\n return `\\n\\n${lines.map((l) => `> ${l}`).join('\\n')}\\n\\n`;\n }\n case 'a': {\n const href = node.getAttribute('href') || '';\n return `[${inner()}](${href})`;\n }\n case 'img': {\n const src = node.getAttribute('src') || '';\n const alt = node.getAttribute('alt') || '';\n return ``;\n }\n case 'ul': {\n const items = Array.from(node.querySelectorAll(':scope > li'));\n if (!items.length) return inner();\n return `\\n\\n${items.map((li) => `- ${_domToMd(li).trim()}`).join('\\n')}\\n\\n`;\n }\n case 'ol': {\n const items = Array.from(node.querySelectorAll(':scope > li'));\n if (!items.length) return inner();\n return `\\n\\n${items.map((li, i) => `${i + 1}. ${_domToMd(li).trim()}`).join('\\n')}\\n\\n`;\n }\n case 'li': return inner();\n case 'hr': return '\\n\\n---\\n\\n';\n case 'table': {\n const rows = Array.from(node.querySelectorAll('tr'));\n if (!rows.length) return inner();\n const cellTexts = rows.map((tr) =>\n Array.from(tr.querySelectorAll('th, td')).map((c) => c.textContent.trim().replace(/\\|/g, '\\\\|')),\n );\n const cols = Math.max(...cellTexts.map((r) => r.length));\n const padRow = (row) => { const r = [...row]; while (r.length < cols) r.push(''); return r; };\n let md = '\\n\\n';\n md += `| ${padRow(cellTexts[0]).join(' | ')} |\\n`;\n md += `| ${Array(cols).fill('---').join(' | ')} |\\n`;\n for (let r = 1; r < cellTexts.length; r++) {\n md += `| ${padRow(cellTexts[r]).join(' | ')} |\\n`;\n }\n return md + '\\n';\n }\n default: return inner();\n }\n}\n\n/**\n * Returns true if the text contains recognisable Markdown patterns.\n * @param {string} text\n * @returns {boolean}\n */\nexport function isMarkdown(text) {\n return /^#{1,6} \\S|^\\s*[-*+] \\S|^\\s*\\d+\\. \\S|^> \\S|\\*{2}.+?\\*{2}|^```/m.test(text);\n}\n\n/**\n * Converts a Markdown string to an HTML string.\n * @param {string} text\n * @returns {string}\n */\nexport function markdownToHTML(text) {\n const lines = text.replace(/\\r\\n/g, '\\n').replace(/\\r/g, '\\n').split('\\n');\n const out = [];\n let i = 0;\n\n while (i < lines.length) {\n const line = lines[i];\n\n // ---- Fenced code block ``` lang ... ``` -----------------------------------\n const fenceMatch = line.match(/^```(\\S*)$/);\n if (fenceMatch) {\n const lang = fenceMatch[1];\n const codeLines = [];\n i++;\n while (i < lines.length && !lines[i].startsWith('```')) {\n codeLines.push(_esc(lines[i]));\n i++;\n }\n const langAttr = lang ? ` class=\"language-${_escAttr(lang)}\"` : '';\n out.push(`<pre><code${langAttr}>${codeLines.join('\\n')}</code></pre>`);\n i++; // skip closing ```\n continue;\n }\n\n // ---- Horizontal rule --- / *** / _________________________________________\n if (/^(-{3,}|\\*{3,}|_{3,})\\s*$/.test(line)) {\n out.push('<hr>');\n i++;\n continue;\n }\n\n // ---- ATX Headings # – ###### -------------------------------------------\n const hMatch = line.match(/^(#{1,6})\\s+(.+)$/);\n if (hMatch) {\n const level = hMatch[1].length;\n out.push(`<h${level}>${_inline(hMatch[2])}</h${level}>`);\n i++;\n continue;\n }\n\n // ---- Blockquote > text --------------------------------------------------\n if (line.startsWith('> ')) {\n const bqLines = [];\n while (i < lines.length && lines[i].startsWith('> ')) {\n bqLines.push(lines[i].slice(2));\n i++;\n }\n out.push(`<blockquote>${bqLines.map(_inline).join('<br>')}</blockquote>`);\n continue;\n }\n\n // ---- Unordered list - / * / + item ------------------------------------\n if (/^[-*+] /.test(line)) {\n const items = [];\n while (i < lines.length && /^[-*+] /.test(lines[i])) {\n items.push(`<li>${_inline(lines[i].slice(2))}</li>`);\n i++;\n }\n out.push(`<ul>${items.join('')}</ul>`);\n continue;\n }\n\n // ---- Ordered list 1. item ----------------------------------------------\n if (/^\\d+\\. /.test(line)) {\n const items = [];\n while (i < lines.length && /^\\d+\\. /.test(lines[i])) {\n items.push(`<li>${_inline(lines[i].replace(/^\\d+\\. /, ''))}</li>`);\n i++;\n }\n out.push(`<ol>${items.join('')}</ol>`);\n continue;\n }\n\n // ---- Blank line ----------------------------------------------------------\n if (line.trim() === '') {\n i++;\n continue;\n }\n\n // ---- GFM Table | col | col | -------------------------------------------\n // A table starts with a pipe-prefixed or pipe-containing line followed by\n // a separator row (| --- | --- |). We detect and collect all rows.\n if (/^\\|.+\\|/.test(line) && i + 1 < lines.length && /^\\|[\\s|:-]+\\|/.test(lines[i + 1])) {\n const headerCells = _parseTableRow(line);\n i += 2; // skip header + separator\n const bodyRows = [];\n while (i < lines.length && /^\\|.+\\|/.test(lines[i])) {\n bodyRows.push(_parseTableRow(lines[i]));\n i++;\n }\n const thead = `<thead><tr>${headerCells.map((c) => `<th>${_inline(c)}</th>`).join('')}</tr></thead>`;\n const tbody = bodyRows.length\n ? `<tbody>${bodyRows.map((row) => `<tr>${row.map((c) => `<td>${_inline(c)}</td>`).join('')}</tr>`).join('')}</tbody>`\n : '';\n out.push(`<table>${thead}${tbody}</table>`);\n continue;\n }\n\n // ---- Paragraph: collect consecutive non-block lines ---------------------\n const paraLines = [];\n while (\n i < lines.length &&\n lines[i].trim() !== '' &&\n !/^(#{1,6} |> |[-*+] |\\d+\\. |```|---\\s*$|\\*{3}\\s*$|_{3}\\s*$)/.test(lines[i]) &&\n !/^\\|.+\\|/.test(lines[i])\n ) {\n paraLines.push(lines[i]);\n i++;\n }\n if (paraLines.length) {\n out.push(`<p>${_inline(paraLines.join(' '))}</p>`);\n }\n }\n\n return out.join('');\n}\n\n// ---------------------------------------------------------------------------\n// Inline formatting\n// ---------------------------------------------------------------------------\n\n/**\n * Splits a GFM table row string into trimmed cell strings.\n * '| a | b | c |' → ['a', 'b', 'c']\n * @param {string} row\n * @returns {string[]}\n */\nfunction _parseTableRow(row) {\n return row\n .replace(/^\\|/, '')\n .replace(/\\|$/, '')\n .split('|')\n .map((c) => c.trim());\n}\n\nfunction _inline(text) {\n // Images before links (they share [] syntax)\n text = text.replace(/!\\[([^\\]]*)\\]\\(([^)]+)\\)/g, (_, alt, src) =>\n `<img src=\"${_escAttr(src)}\" alt=\"${_escAttr(alt)}\" class=\"an-image\">`);\n // Links\n text = text.replace(/\\[([^\\]]+)\\]\\(([^)]+)\\)/g, (_, label, href) =>\n `<a href=\"${_escAttr(href)}\">${_esc(label)}</a>`);\n // Bold + italic ***text***\n text = text.replace(/\\*{3}(.+?)\\*{3}/g, (_, c) => `<strong><em>${_esc(c)}</em></strong>`);\n text = text.replace(/_{3}(.+?)_{3}/g, (_, c) => `<strong><em>${_esc(c)}</em></strong>`);\n // Bold **text**\n text = text.replace(/\\*{2}(.+?)\\*{2}/g, (_, c) => `<strong>${_esc(c)}</strong>`);\n text = text.replace(/_{2}(.+?)_{2}/g, (_, c) => `<strong>${_esc(c)}</strong>`);\n // Italic *text* _text_\n text = text.replace(/\\*([^*\\n]+?)\\*/g, (_, c) => `<em>${_esc(c)}</em>`);\n text = text.replace(/_([^_\\n]+?)_/g, (_, c) => `<em>${_esc(c)}</em>`);\n // Strikethrough ~~text~~\n text = text.replace(/~~(.+?)~~/g, (_, c) => `<del>${_esc(c)}</del>`);\n // Inline code `code`\n text = text.replace(/`([^`]+)`/g, (_, c) => `<code>${_esc(c)}</code>`);\n return text;\n}\n\nfunction _esc(v) {\n return String(v)\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>');\n}\n\nfunction _escAttr(v) {\n return String(v)\n .replace(/&/g, '&')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n .replace(/</g, '<')\n .replace(/>/g, '>');\n}\n","/**\n * Editor.js - Core editing command module\n * Wraps all execCommand calls, undo/redo, and fires events via the context.\n * Inspired by Summernote's Editor module.\n */\n\nimport { History } from '../editing/History.js';\nimport * as Style from '../editing/Style.js';\nimport { insertTable } from '../editing/Table.js';\nimport { isModifier } from '../core/key.js';\nimport { handleKeydown } from '../editing/Typing.js';\nimport { on } from '../core/dom.js';\nimport { sanitiseHTML, sanitiseUrl } from '../core/sanitise.js';\nimport { markdownToHTML, htmlToMarkdown } from '../core/markdown.js';\n\nexport class Editor {\n /**\n * @param {import('../Context.js').Context} context\n */\n constructor(context) {\n this.context = context;\n this.options = context.options;\n /** @type {History|null} */\n this._history = null;\n this._disposers = [];\n /** @type {number|null} Timer handle for debounced undo snapshot */\n this._snapshotTimer = null;\n }\n\n // ---------------------------------------------------------------------------\n // Lifecycle\n // ---------------------------------------------------------------------------\n\n initialize() {\n const editable = this.context.layoutInfo.editable;\n this._history = new History(editable, this.options.historyLimit || 100);\n this._bindEvents(editable);\n return this;\n }\n\n destroy() {\n this._disposers.forEach((d) => d());\n this._disposers = [];\n this._history = null;\n clearTimeout(this._snapshotTimer);\n this._snapshotTimer = null;\n }\n\n // ---------------------------------------------------------------------------\n // Event binding\n // ---------------------------------------------------------------------------\n\n _bindEvents(editable) {\n // Keyboard shortcuts\n const onKeydown = (event) => this._onKeydown(event);\n // Catch ALL content mutations: typing, IME, spellcheck, voice, drag-drop text.\n const onInput = () => this.afterCommand();\n // Hard-enforce maxChars / maxWords before content is mutated\n const onBeforeInput = (event) => this._enforceLimit(event);\n // Refresh toolbar on selection change, scoped to this editor\n const onSelChange = () => {\n if (!this.context._alive) return;\n const sel = window.getSelection();\n if (sel && sel.rangeCount > 0 && editable.contains(sel.anchorNode)) {\n this.context.invoke('toolbar.refresh');\n if (typeof this.options.onSelectionChange === 'function') {\n this.options.onSelectionChange(this.context);\n }\n }\n };\n\n // Checklist checkboxes are contenteditable=false so native clicks work;\n // hook afterCommand so the checked state is preserved in undo history.\n const onCheckboxClick = (e) => {\n if (e.target.type === 'checkbox' && e.target.closest('.an-checklist')) {\n this.afterCommand();\n }\n };\n\n // Guard: when cursor lands at the <li> element node of a checklist item\n // (before the checkbox), nudge it to the correct text position.\n //\n // mouseup: use caretRangeFromPoint / caretPositionFromPoint so the cursor\n // lands WHERE the user actually clicked (middle, end of text…).\n // keyup : arrow-key navigation may land at <li>[0]; move to start-of-text.\n const fixChecklistCursor = (event) => {\n const sel = window.getSelection();\n if (!sel || !sel.rangeCount) return;\n const r = sel.getRangeAt(0);\n if (!r.collapsed) return;\n const sc = r.startContainer;\n\n // Only act when cursor is at the <li> element node itself (not inside\n // a text node — the browser already placed it correctly in that case).\n if (sc.nodeType !== Node.ELEMENT_NODE) return;\n const li = sc.matches && sc.matches('.an-checklist li') ? sc : null;\n if (!li) return;\n const cb = li.querySelector('input[type=\"checkbox\"]');\n if (!cb) return;\n\n // For mouse events: ask the browser where the pointer landed so the\n // cursor respects the actual click position inside the text.\n if (event && event.type === 'mouseup') {\n let caret = null;\n if (document.caretRangeFromPoint) {\n caret = document.caretRangeFromPoint(event.clientX, event.clientY);\n } else if (document.caretPositionFromPoint) {\n const cp = document.caretPositionFromPoint(event.clientX, event.clientY);\n if (cp) {\n caret = document.createRange();\n caret.setStart(cp.offsetNode, cp.offset);\n }\n }\n // If the caret from point landed inside a text node of this li, use it\n if (caret && editable.contains(caret.startContainer) &&\n caret.startContainer !== li) {\n caret.collapse(true);\n sel.removeAllRanges();\n sel.addRange(caret);\n return;\n }\n }\n\n // Fallback (keyboard nav, or caretRangeFromPoint not available / landed\n // at li again): prefer the first text node after the checkbox so the\n // cursor renders at the padding-left edge (after the visual checkbox)\n // rather than at element-level where the browser may place it at x=0.\n const nr = document.createRange();\n let anchorNode = null;\n for (const child of li.childNodes) {\n if (child !== cb && child.nodeType === Node.TEXT_NODE) {\n anchorNode = child;\n break;\n }\n }\n if (anchorNode) {\n nr.setStart(anchorNode, 0);\n } else {\n nr.setStartAfter(cb);\n }\n nr.collapse(true);\n sel.removeAllRanges();\n sel.addRange(nr);\n };\n\n this._disposers.push(\n on(editable, 'keydown', onKeydown),\n on(editable, 'beforeinput', onBeforeInput),\n on(editable, 'input', onInput),\n on(document, 'selectionchange', onSelChange),\n on(editable, 'click', onCheckboxClick),\n on(editable, 'mouseup', fixChecklistCursor),\n on(editable, 'keyup', fixChecklistCursor),\n );\n }\n\n _onKeydown(event) {\n const editable = this.context.layoutInfo.editable;\n\n // Let Typing module handle special keys (Tab, Enter etc.)\n if (handleKeydown(event, editable, this.options)) return;\n\n // Built-in shortcuts\n if (isModifier(event, 'z') && !event.shiftKey) {\n event.preventDefault();\n this.undo();\n return;\n }\n if ((isModifier(event, 'z') && event.shiftKey) || isModifier(event, 'y')) {\n event.preventDefault();\n this.redo();\n return;\n }\n if (isModifier(event, 'b')) { event.preventDefault(); this.bold(); return; }\n if (isModifier(event, 'i')) { event.preventDefault(); this.italic(); return; }\n if (isModifier(event, 'u')) { event.preventDefault(); this.underline(); return; }\n if (isModifier(event, 'k')) { event.preventDefault(); this.context.invoke('linkDialog.show'); return; }\n\n // Ctrl+Shift+V — paste as plain text (signals Clipboard module)\n if (isModifier(event, 'v') && event.shiftKey) {\n this.context.invoke('clipboard.setForcePlain', true);\n return; // let the native paste event fire\n }\n\n // Show keyboard shortcuts dialog: Ctrl+Shift+/\n if (event.key === '/' && event.shiftKey && event.ctrlKey && !event.metaKey) {\n event.preventDefault();\n this.context.invoke('shortcutsDialog.show');\n return;\n }\n // Find: Ctrl+F\n if (isModifier(event, 'f')) {\n event.preventDefault();\n this.context.invoke('findReplace.show', 'find');\n return;\n }\n // Ctrl+H — Find & Replace\n if (isModifier(event, 'h')) {\n event.preventDefault();\n this.context.invoke('findReplace.show', 'replace');\n }\n // Ctrl+` — Inline Code\n if (isModifier(event, '`')) {\n event.preventDefault();\n this.inlineCode();\n }\n }\n\n // ---------------------------------------------------------------------------\n // Limit enforcement\n // ---------------------------------------------------------------------------\n\n /**\n * Called from beforeinput to block typing when char/word limits are reached.\n * Deletions and non-typing input types are always allowed.\n * @param {InputEvent} event\n */\n _enforceLimit(event) {\n const maxChars = this.options.maxChars || 0;\n const maxWords = this.options.maxWords || 0;\n if (!maxChars && !maxWords) return;\n\n const type = event.inputType || '';\n // Allow deletions, undo, redo and non-insert operations\n if (type.startsWith('delete') || type === 'historyUndo' || type === 'historyRedo') return;\n // Allow paste/drop — handled after the fact by Clipboard\n if (type === 'insertFromPaste' || type === 'insertFromDrop') return;\n // Only enforce for keyboard/IME/composition insertions\n if (!type.startsWith('insert')) return;\n\n const text = this.context.layoutInfo.editable.innerText || '';\n const chars = text.replace(/\\n/g, '').length;\n\n if (maxChars && chars >= maxChars) {\n event.preventDefault();\n if (typeof this.options.onCharLimitReached === 'function') {\n this.options.onCharLimitReached(this.context);\n }\n return;\n }\n\n // Word limit: block space / newline insertion when already at the limit\n if (maxWords && (event.data === ' ' || type === 'insertParagraph' || type === 'insertLineBreak')) {\n const words = text.trim() ? text.trim().split(/\\s+/).length : 0;\n if (words >= maxWords) {\n event.preventDefault();\n if (typeof this.options.onWordLimitReached === 'function') {\n this.options.onWordLimitReached(this.context);\n }\n }\n }\n }\n\n // ---------------------------------------------------------------------------\n // Post-command hook — records undo, fires change event\n // ---------------------------------------------------------------------------\n\n afterCommand() {\n // Immediate: keep toolbar and statusbar in sync on every mutation.\n this.context.invoke('toolbar.refresh');\n this.context.invoke('statusbar.update');\n // Debounced: recording an undo snapshot and firing the change event require\n // a full innerHTML serialization. Batching rapid keystrokes prevents the\n // browser from re-serializing large content (e.g. embedded images) on every\n // single key press.\n this._scheduleSnapshot();\n }\n\n /**\n * Schedules a debounced undo snapshot + change event.\n * Resets the timer on each call so rapid typing produces one snapshot.\n */\n _scheduleSnapshot() {\n clearTimeout(this._snapshotTimer);\n this._snapshotTimer = setTimeout(() => {\n this._snapshotTimer = null;\n if (this._history) this._history.recordUndo();\n this.context.triggerEvent('change', this.getHTML());\n }, 400);\n }\n\n // ---------------------------------------------------------------------------\n // Focus management\n // ---------------------------------------------------------------------------\n\n focus() {\n const editable = this.context.layoutInfo.editable;\n editable.focus();\n }\n\n // ---------------------------------------------------------------------------\n // Content API\n // ---------------------------------------------------------------------------\n\n /**\n * Returns the editor HTML content.\n * @returns {string}\n */\n getHTML() {\n // Strip zero-width spaces inserted after icons to allow caret placement.\n const raw = this.context.layoutInfo.editable.innerHTML.replace(/\\u200B/g, '');\n // Replace any blob: URLs (lightweight DOM references to pasted/dropped images)\n // with their original data URLs so the returned HTML is fully self-contained.\n return this.context.invoke('clipboard.resolveImages', raw) ?? raw;\n }\n\n /**\n * Sets the editor HTML content.\n * @param {string} html - HTML string (will be sanitised)\n */\n setHTML(html) {\n this.context.layoutInfo.editable.innerHTML = sanitiseHTML(html);\n if (this._history) this._history.reset();\n this.afterCommand();\n }\n\n /**\n * Returns the editor plain text content.\n * @returns {string}\n */\n getText() {\n return this.context.layoutInfo.editable.innerText || '';\n }\n\n /**\n * Sets the editor content as plain text.\n * @param {string} text\n */\n setText(text) {\n this.context.layoutInfo.editable.textContent = text;\n if (this._history) this._history.reset();\n this.afterCommand();\n }\n\n /**\n * Clears the editor content.\n */\n clear() {\n this.setHTML('');\n }\n\n /**\n * Resets the undo/redo history stack.\n */\n clearHistory() {\n if (this._history) this._history.reset();\n }\n\n /**\n * Returns true when the editor has no meaningful content.\n * @returns {boolean}\n */\n isEmpty() {\n const text = (this.context.layoutInfo.editable.innerText || '')\n .trim()\n .replace(/\\u00a0/g, '');\n const hasMedia = !!this.context.layoutInfo.editable.querySelector('img, video, iframe, table');\n return !text && !hasMedia;\n }\n\n /**\n * Inserts HTML at the current cursor position.\n * @param {string} html\n */\n insertHTML(html) {\n if (!html) return;\n Style.execCommand('insertHTML', sanitiseHTML(html));\n this.afterCommand();\n }\n\n /**\n * Inserts plain text at the current cursor position.\n * @param {string} text\n */\n insertText(text) {\n if (!text) return;\n Style.execCommand('insertText', text);\n this.afterCommand();\n }\n\n /**\n * Sets editor content from a Markdown string.\n * @param {string} md\n */\n setMarkdown(md) {\n this.setHTML(markdownToHTML(md || ''));\n }\n\n /**\n * Returns the editor content as Markdown.\n * @returns {string}\n */\n getMarkdown() {\n return htmlToMarkdown(this.getHTML());\n }\n\n // ---------------------------------------------------------------------------\n // Undo / redo\n // ---------------------------------------------------------------------------\n\n undo() {\n if (this._history) {\n clearTimeout(this._snapshotTimer);\n this._snapshotTimer = null;\n this._history.undo();\n this.context.invoke('toolbar.refresh');\n this.context.invoke('statusbar.update');\n this.context.triggerEvent('change', this.getHTML());\n }\n }\n\n redo() {\n if (this._history) {\n clearTimeout(this._snapshotTimer);\n this._snapshotTimer = null;\n this._history.redo();\n this.context.invoke('toolbar.refresh');\n this.context.invoke('statusbar.update');\n this.context.triggerEvent('change', this.getHTML());\n }\n }\n\n canUndo() {\n return this._history ? this._history.canUndo() : false;\n }\n\n canRedo() {\n return this._history ? this._history.canRedo() : false;\n }\n\n // ---------------------------------------------------------------------------\n // Style commands (delegated to Style module)\n // ---------------------------------------------------------------------------\n\n bold() { Style.bold(); this.afterCommand(); }\n italic() { Style.italic(); this.afterCommand(); }\n underline() { Style.underline(); this.afterCommand(); }\n strikethrough() { Style.strikethrough(); this.afterCommand(); }\n superscript() { Style.superscript(); this.afterCommand(); }\n subscript() { Style.subscript(); this.afterCommand(); }\n justifyLeft() { Style.justifyLeft(); this.afterCommand(); }\n justifyCenter() { Style.justifyCenter(); this.afterCommand(); }\n justifyRight() { Style.justifyRight(); this.afterCommand(); }\n justifyFull() { Style.justifyFull(); this.afterCommand(); }\n indent() { Style.indent(); this.afterCommand(); }\n outdent() { Style.outdent(); this.afterCommand(); }\n insertUL() { Style.insertUnorderedList(); this.afterCommand(); }\n insertOL() { Style.insertOrderedList(); this.afterCommand(); }\n inlineCode() { Style.toggleInlineCode(this.context.layoutInfo.editable); this.afterCommand(); }\n toggleChecklist() { Style.toggleChecklist(); this.afterCommand(); }\n print() { this.context.print(); }\n\n /**\n * @param {string} tagName - e.g. 'h1', 'p', 'blockquote'\n */\n formatBlock(tagName) { Style.formatBlock(tagName); this.afterCommand(); }\n\n /**\n * @param {string} color\n */\n foreColor(color) { Style.foreColor(color); this.afterCommand(); }\n\n /**\n * @param {string} color\n */\n backColor(color) { Style.backColor(color); this.afterCommand(); }\n\n /**\n * @param {string} name\n */\n fontName(name) { Style.fontName(name); this.afterCommand(); }\n\n /**\n * @param {string} size - e.g. '14px'\n */\n fontSize(size) { Style.fontSize(size, this.context.layoutInfo.editable); this.afterCommand(); }\n\n // ---------------------------------------------------------------------------\n // Insert helpers\n // ---------------------------------------------------------------------------\n\n /**\n * Inserts a horizontal rule at the cursor.\n */\n insertHr() {\n Style.execCommand('insertHorizontalRule');\n this.afterCommand();\n }\n\n /**\n * Creates a link at the current selection.\n * @param {string} url\n * @param {string} text\n * @param {boolean} [openInNewTab=false]\n */\n insertLink(url, text, openInNewTab = false) {\n const sel = window.getSelection();\n if (!sel || sel.rangeCount === 0) return;\n const safeUrl = sanitiseUrl(url);\n if (!safeUrl) return;\n\n const hasText = sel.toString().trim().length > 0;\n if (!hasText) {\n const displayText = this._escapeAttr(text || safeUrl);\n Style.execCommand('insertHTML', `<a href=\"${this._escapeAttr(safeUrl)}\"${openInNewTab ? ' target=\"_blank\" rel=\"noopener noreferrer\"' : ''}>${displayText}</a>`);\n } else {\n Style.execCommand('createLink', safeUrl);\n if (openInNewTab) {\n const link = this._getClosestAnchor();\n if (link) {\n link.setAttribute('target', '_blank');\n link.setAttribute('rel', 'noopener noreferrer');\n }\n }\n }\n this.afterCommand();\n }\n\n /**\n * Removes the link from the selected anchor.\n */\n unlink() {\n Style.execCommand('unlink');\n this.afterCommand();\n }\n\n /**\n * Inserts an image.\n * @param {string} src - URL or data-URI\n * @param {string} [alt]\n */\n insertImage(src, alt = '', align = '') {\n const safeSrc = sanitiseUrl(src, { allowData: true });\n if (!safeSrc) return;\n const styleMap = {\n left: 'float:left;margin:0 1em 1em 0',\n center: 'display:block;margin:0 auto',\n right: 'float:right;margin:0 0 1em 1em',\n };\n const style = styleMap[align] || '';\n const styleAttr = style ? ` style=\"${style}\"` : '';\n Style.execCommand('insertHTML', `<img src=\"${this._escapeAttr(safeSrc)}\" alt=\"${this._escapeAttr(alt)}\" class=\"an-image\"${styleAttr}>`);\n this.afterCommand();\n }\n\n /**\n * Inserts a video embed (iframe or <video> element).\n * The html string is already validated/built by VideoDialog.\n * @param {string} html\n */\n insertVideo(html) {\n if (!html) return;\n Style.execCommand('insertHTML', html);\n this.afterCommand();\n }\n\n /**\n * Inserts a table.\n * @param {number} cols\n * @param {number} rows\n */\n insertTable(cols, rows) {\n insertTable(cols, rows, { headerRow: this.context.options.tableHeaderRow });\n this.afterCommand();\n }\n\n // ---------------------------------------------------------------------------\n // Helpers\n // ---------------------------------------------------------------------------\n\n _getClosestAnchor() {\n const sel = window.getSelection();\n if (!sel || sel.rangeCount === 0) return null;\n let node = sel.getRangeAt(0).startContainer;\n while (node) {\n if (node.nodeName === 'A') return node;\n node = node.parentNode;\n }\n return null;\n }\n\n /**\n * Escapes a string for safe use inside an HTML attribute value.\n * @param {string} str\n * @returns {string}\n */\n _escapeAttr(str) {\n return String(str ?? '')\n .replace(/&/g, '&')\n .replace(/\"/g, '"')\n .replace(/</g, '<')\n .replace(/>/g, '>');\n }\n\n // --- delegated to shared sanitise.js ---\n}\n","/**\n * Toolbar.js - Builds and manages the editor toolbar UI\n * Inspired by Summernote's Toolbar module — rewritten without jQuery\n */\n\nimport { createElement, on } from '../core/dom.js';\n\n// Module-level cache for FontAwesome detection.\n// Evaluated once per page load so all Toolbar instances on the same page agree\n// on whether the HOST PAGE included FA — regardless of whether IconDialog later\n// auto-injects its own FA <link> for the icon-picker glyph rendering.\nlet _faPageLevelReady = null;\n\nexport class Toolbar {\n /**\n * @param {import('../Context.js').Context} context\n */\n constructor(context) {\n this.context = context;\n this.options = context.options;\n /** @type {HTMLElement|null} */\n this.el = null;\n /** @type {Array<() => void>} disposers */\n this._disposers = [];\n /** @type {Array<() => void>} closers for all open color picker popups */\n this._colorPickerClosers = [];\n }\n\n // ---------------------------------------------------------------------------\n // Lifecycle\n // ---------------------------------------------------------------------------\n\n initialize() {\n this.el = createElement('div', { class: 'an-toolbar' });\n // Detect FontAwesome once at toolbar build time to avoid re-querying the DOM\n // for every button rendered.\n this._faReady = this._detectFontAwesome();\n this._buildButtons();\n this._btnMap = new Map((this.options.toolbar || []).flat().map((b) => [b.name, b]));\n return this;\n }\n\n destroy() {\n this._disposers.forEach((d) => d());\n this._disposers = [];\n if (this.el && this.el.parentNode) {\n this.el.parentNode.removeChild(this.el);\n }\n this.el = null;\n }\n\n // ---------------------------------------------------------------------------\n // Build\n // ---------------------------------------------------------------------------\n\n _buildButtons() {\n const toolbar = this.options.toolbar || [];\n toolbar.forEach((group) => {\n const groupEl = createElement('div', { class: 'an-btn-group' });\n group.forEach((btnDef) => {\n let el;\n if (btnDef.type === 'select') el = this._createSelect(btnDef);\n else if (btnDef.type === 'grid') el = this._createGridPicker(btnDef);\n else if (btnDef.type === 'colorpicker') el = this._createColorPicker(btnDef);\n else el = this._createButton(btnDef);\n groupEl.appendChild(el);\n });\n this.el.appendChild(groupEl);\n });\n }\n\n /**\n * Creates a table-grid picker button with a hoverable row/col selector popup.\n * @param {import('./Buttons.js').ButtonDef} def\n * @returns {HTMLDivElement}\n */\n _createGridPicker(def) {\n const ROWS = 10;\n const COLS = 10;\n\n const wrap = createElement('div', { class: 'an-table-picker-wrap' });\n\n const useBootstrap = !!this.options.useBootstrap;\n const baseClass = useBootstrap\n ? (this.options.toolbarButtonClass || 'btn btn-sm btn-light')\n : 'an-btn';\n const btn = createElement('button', {\n type: 'button',\n class: baseClass,\n title: def.tooltip || '',\n 'data-btn': def.name,\n 'aria-label': def.tooltip || def.name,\n 'aria-haspopup': 'true',\n 'aria-expanded': 'false',\n });\n\n // Set icon — inline SVG (table) with optional FontAwesome fallback\n if (this._faReady) {\n const faPrefix = this.options.fontAwesomeClass || 'fas';\n btn.innerHTML = `<i class=\"${faPrefix} fa-table\" aria-hidden=\"true\"></i>`;\n } else {\n const S = 'stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"';\n btn.innerHTML = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" ${S} style=\"display:block\"><rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"1\"/><line x1=\"3\" y1=\"9\" x2=\"21\" y2=\"9\"/><line x1=\"3\" y1=\"15\" x2=\"21\" y2=\"15\"/><line x1=\"9\" y1=\"3\" x2=\"9\" y2=\"21\"/><line x1=\"15\" y1=\"3\" x2=\"15\" y2=\"21\"/></svg>`;\n }\n\n // Popup\n const popup = createElement('div', {\n class: 'an-table-picker-popup',\n role: 'dialog',\n 'aria-label': 'Select table size',\n });\n const grid = createElement('div', { class: 'an-table-grid' });\n const label = createElement('div', { class: 'an-table-label' });\n label.textContent = 'Insert Table';\n\n const cells = [];\n for (let r = 1; r <= ROWS; r++) {\n for (let c = 1; c <= COLS; c++) {\n const cell = createElement('div', {\n class: 'an-table-cell',\n 'data-row': String(r),\n 'data-col': String(c),\n });\n cells.push(cell);\n grid.appendChild(cell);\n }\n }\n\n popup.appendChild(grid);\n popup.appendChild(label);\n\n let isOpen = false;\n\n const setHighlight = (rows, cols) => {\n cells.forEach((cell) => {\n const r = +cell.getAttribute('data-row');\n const c = +cell.getAttribute('data-col');\n cell.classList.toggle('active', r <= rows && c <= cols);\n });\n label.textContent = (rows && cols) ? `${rows} × ${cols}` : 'Insert Table';\n };\n\n const openPopup = () => {\n isOpen = true;\n popup.style.display = 'block';\n btn.setAttribute('aria-expanded', 'true');\n };\n\n const closePopup = () => {\n isOpen = false;\n popup.style.display = 'none';\n btn.setAttribute('aria-expanded', 'false');\n setHighlight(0, 0);\n };\n\n const d1 = on(btn, 'click', (e) => {\n e.stopPropagation();\n if (isOpen) closePopup(); else openPopup();\n });\n\n const d2 = on(grid, 'mouseover', (e) => {\n const cell = e.target.closest('.an-table-cell');\n if (!cell) return;\n setHighlight(+cell.getAttribute('data-row'), +cell.getAttribute('data-col'));\n });\n\n const d3 = on(grid, 'mouseleave', () => setHighlight(0, 0));\n\n const d4 = on(grid, 'click', (e) => {\n const cell = e.target.closest('.an-table-cell');\n if (!cell) return;\n const rows = +cell.getAttribute('data-row');\n const cols = +cell.getAttribute('data-col');\n closePopup();\n this.context.invoke('editor.focus');\n def.action(this.context, rows, cols);\n });\n\n const d5 = on(document, 'click', () => { if (isOpen) closePopup(); });\n\n this._disposers.push(d1, d2, d3, d4, d5);\n\n wrap.appendChild(btn);\n wrap.appendChild(popup);\n return wrap;\n }\n\n /**\n * Creates a split color-picker widget:\n * [icon + strip | ▾] — left applies current color, right opens swatch popup.\n * @param {{ name: string, type: 'colorpicker', tooltip: string, defaultColor: string, action: Function }} def\n * @returns {HTMLDivElement}\n */\n _createColorPicker(def) {\n const PRESETS = [\n // Grayscale\n '#000000', '#434343', '#666666', '#999999', '#b7b7b7', '#cccccc', '#efefef', '#ffffff',\n // Saturated\n '#ff0000', '#ff9900', '#ffff00', '#00ff00', '#00ffff', '#4a86e8', '#9900ff', '#ff00ff',\n // Pastel\n '#f4cccc', '#fce5cd', '#fff2cc', '#d9ead3', '#d0e0e3', '#c9daf8', '#d9d2e9', '#ead1dc',\n ];\n\n let currentColor = def.defaultColor || '#000000';\n\n const wrap = createElement('div', { class: 'an-color-picker-wrap' });\n\n const useBootstrap = !!this.options.useBootstrap;\n const baseClass = useBootstrap ? (this.options.toolbarButtonClass || 'btn btn-sm btn-light') : 'an-btn';\n\n // ---- Apply button (icon + color strip) ----\n const applyBtn = createElement('button', {\n type: 'button',\n class: `${baseClass} an-color-btn`,\n title: def.tooltip || '',\n 'data-btn': def.name,\n 'aria-label': def.tooltip || def.name,\n });\n\n const S = 'stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"';\n const iconSvg = def.name === 'foreColor'\n ? `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" ${S} style=\"display:block\"><path d=\"M4 20L12 4L20 20\"/><line x1=\"7.5\" y1=\"14\" x2=\"16.5\" y2=\"14\"/></svg>`\n : `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" ${S} style=\"display:block\"><path d=\"M3 21v-4l9-9 4 4-9 9z\"/><path d=\"M12 8l4 4\"/></svg>`;\n\n applyBtn.innerHTML = iconSvg;\n const strip = createElement('span', { class: 'an-color-strip' });\n strip.style.background = currentColor;\n applyBtn.appendChild(strip);\n\n // ---- Arrow button (open popup) ----\n const arrowBtn = createElement('button', {\n type: 'button',\n class: `${baseClass} an-color-arrow`,\n title: `Choose ${def.name === 'foreColor' ? 'text' : 'highlight'} color`,\n 'aria-haspopup': 'true',\n 'aria-expanded': 'false',\n });\n arrowBtn.innerHTML = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"8\" height=\"8\" viewBox=\"0 0 24 24\" fill=\"currentColor\" stroke=\"none\" style=\"display:block\"><path d=\"M7 10l5 5 5-5H7z\"/></svg>`;\n\n // ---- Popup ----\n const popup = createElement('div', { class: 'an-color-popup' });\n popup.style.display = 'none';\n\n const swatches = createElement('div', { class: 'an-color-swatches' });\n const userSwatches = Array.isArray(this.options.colorSwatches) ? this.options.colorSwatches : [];\n const allColors = [...new Set([...userSwatches, ...PRESETS])];\n allColors.forEach((color) => {\n const sw = createElement('div', { class: 'an-color-swatch', title: color, 'data-color': color });\n sw.style.background = color;\n swatches.appendChild(sw);\n });\n\n const customRow = createElement('div', { class: 'an-color-custom' });\n const colorInput = createElement('input', { type: 'color', value: currentColor, title: 'Custom color' });\n const customLabel = createElement('span', {}, ['Custom color']);\n customRow.appendChild(colorInput);\n customRow.appendChild(customLabel);\n\n popup.appendChild(swatches);\n popup.appendChild(customRow);\n\n // ---- State ----\n let isOpen = false;\n /** @type {Range|null} saved selection range before popup opens */\n let savedRange = null;\n\n const saveSelection = () => {\n const sel = window.getSelection();\n savedRange = (sel && sel.rangeCount) ? sel.getRangeAt(0).cloneRange() : null;\n };\n\n const restoreSelection = () => {\n if (!savedRange) return;\n const sel = window.getSelection();\n if (sel) {\n sel.removeAllRanges();\n sel.addRange(savedRange);\n }\n };\n\n const openPopup = () => {\n // Close any other open color picker before opening this one\n this._colorPickerClosers.forEach((fn) => { if (fn !== closePopup) fn(); });\n saveSelection();\n isOpen = true;\n // Use fixed positioning so the popup escapes any overflow-clipping ancestor\n // (notably toolbar scroll mode, where overflow-x:auto coerces overflow-y)\n const rect = arrowBtn.getBoundingClientRect();\n const popupMinW = 184;\n let left = rect.left;\n if (left + popupMinW > window.innerWidth) left = rect.right - popupMinW;\n popup.style.top = `${rect.bottom + 4}px`;\n popup.style.left = `${Math.max(4, left)}px`;\n popup.style.display = 'block';\n arrowBtn.setAttribute('aria-expanded', 'true');\n };\n\n const closePopup = () => {\n isOpen = false;\n popup.style.display = 'none';\n popup.style.top = '';\n popup.style.left = '';\n arrowBtn.setAttribute('aria-expanded', 'false');\n };\n\n const applyColor = (color) => {\n currentColor = color;\n strip.style.background = color;\n colorInput.value = color;\n restoreSelection();\n def.action(this.context, color);\n this.context.invoke('editor.afterCommand');\n closePopup();\n };\n\n const d1 = on(applyBtn, 'click', (e) => {\n e.preventDefault();\n restoreSelection();\n def.action(this.context, currentColor);\n this.context.invoke('editor.afterCommand');\n });\n\n const d2 = on(arrowBtn, 'mousedown', (e) => {\n // Prevent editor blur so selection is preserved when the popup opens\n e.preventDefault();\n });\n\n const d2b = on(arrowBtn, 'click', (e) => {\n e.stopPropagation();\n if (isOpen) closePopup(); else openPopup();\n });\n\n const d3 = on(swatches, 'mousedown', (e) => {\n // Prevent blur before the click handler fires\n e.preventDefault();\n });\n\n const d3b = on(swatches, 'click', (e) => {\n const sw = e.target.closest('.an-color-swatch');\n if (sw) applyColor(sw.dataset.color);\n });\n\n const d4 = on(colorInput, 'change', (e) => {\n applyColor(e.target.value);\n });\n\n const d5 = on(document, 'click', (e) => {\n // popup is in document.body, not inside wrap — check both\n if (isOpen && !wrap.contains(e.target) && !popup.contains(e.target)) closePopup();\n });\n\n const d6 = on(popup, 'click', (e) => e.stopPropagation());\n\n // Close the popup when the viewport scrolls or resizes so the fixed-position\n // popup doesn't drift away from the button it belongs to.\n const onScrollResize = () => { if (isOpen) closePopup(); };\n document.addEventListener('scroll', onScrollResize, { passive: true, capture: true });\n window.addEventListener('resize', onScrollResize, { passive: true });\n\n this._disposers.push(d1, d2, d2b, d3, d3b, d4, d5, d6,\n () => document.removeEventListener('scroll', onScrollResize, { capture: true }),\n () => window.removeEventListener('resize', onScrollResize),\n // Remove popup from body on editor destroy\n () => { if (popup.parentNode) popup.parentNode.removeChild(popup); },\n );\n\n // Register this popup's closer so other color pickers can close it\n this._colorPickerClosers.push(closePopup);\n this._disposers.push(() => {\n const idx = this._colorPickerClosers.indexOf(closePopup);\n if (idx !== -1) this._colorPickerClosers.splice(idx, 1);\n });\n\n // Append popup to document.body so it escapes all overflow-clipping and\n // contain:layout ancestors (contain:layout makes the container a fixed-pos\n // containing block per the CSS Contain spec, breaking viewport coordinates).\n wrap.appendChild(applyBtn);\n wrap.appendChild(arrowBtn);\n document.body.appendChild(popup);\n return wrap;\n }\n\n /**\n * Creates a <select> dropdown for font-family (or similar) options.\n * @param {import('./Buttons.js').DropdownDef} def\n * @returns {HTMLSelectElement}\n */\n _createSelect(def) {\n const items = (def.name === 'fontFamily')\n ? (this.options.fontFamilies || [])\n : (def.items || []);\n\n const cls = def.selectClass ? `an-select ${def.selectClass}` : 'an-select';\n const select = createElement('select', {\n class: cls,\n title: def.tooltip || '',\n 'data-btn': def.name,\n 'aria-label': def.tooltip || def.name,\n });\n\n // Blank \"placeholder\" option (non-selectable header)\n const placeholderText = def.placeholder || 'Font';\n const placeholder = createElement('option', { value: '', disabled: '', hidden: '' }, [placeholderText]);\n select.appendChild(placeholder);\n\n items.forEach((item) => {\n const value = (typeof item === 'object') ? item.value : item;\n const label = (typeof item === 'object') ? item.label : item;\n const isHeader = (typeof item === 'object') && !!item.disabled;\n const attrs = { value };\n if (isHeader) attrs.disabled = '';\n const opt = createElement('option', attrs, [label]);\n // Only apply fontFamily face preview on real (non-header) entries\n if (def.name === 'fontFamily' && !isHeader) opt.style.fontFamily = value;\n select.appendChild(opt);\n });\n\n const disposer = on(select, 'change', (e) => {\n const value = e.target.value;\n const selectedOpt = e.target.options[e.target.selectedIndex];\n if (!value || selectedOpt.disabled) return;\n this.context.invoke('editor.focus');\n def.action(this.context, value);\n this.context.invoke('editor.afterCommand');\n });\n\n this._disposers.push(disposer);\n return select;\n }\n\n /**\n * @param {import('./Buttons.js').ButtonDef} btnDef\n * @returns {HTMLButtonElement}\n */\n _createButton(btnDef) {\n // Determine classes based on whether the consumer wants Bootstrap styling\n const useBootstrap = !!this.options.useBootstrap;\n const baseClass = useBootstrap ? (this.options.toolbarButtonClass || 'btn btn-sm btn-light') : `an-btn`;\n const extra = btnDef.className ? ` ${btnDef.className}` : '';\n const classAttr = `${baseClass}${extra}`;\n\n const btn = createElement('button', {\n type: 'button',\n class: classAttr,\n title: btnDef.tooltip || '',\n 'data-btn': btnDef.name,\n 'aria-label': btnDef.tooltip || btnDef.name,\n });\n\n // Render icon: prefer FontAwesome if enabled; otherwise fall back to SVG or text.\n\n // Heroicons-style stroke SVGs — consistent with context menu icons\n const S = 'stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"';\n const svgWrap = (paths) => `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" ${S} style=\"display:block\">${paths}</svg>`;\n\n const svgMap = new Map([\n // Format\n ['bold', svgWrap('<path d=\"M6 4h8a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z\"/><path d=\"M6 12h9a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z\"/>')],\n ['italic', svgWrap('<line x1=\"19\" y1=\"4\" x2=\"10\" y2=\"4\"/><line x1=\"14\" y1=\"20\" x2=\"5\" y2=\"20\"/><line x1=\"15\" y1=\"4\" x2=\"9\" y2=\"20\"/>')],\n ['underline', svgWrap('<path d=\"M6 3v7a6 6 0 0 0 6 6 6 6 0 0 0 6-6V3\"/><line x1=\"4\" y1=\"21\" x2=\"20\" y2=\"21\"/>')],\n ['strikethrough', svgWrap('<path d=\"M17.3 12H6.7\"/><path d=\"M10 6.5C10 5.1 11.1 4 12.5 4c1.4 0 2.5 1.1 2.5 2.5 0 .8-.4 1.5-1 2\"/><path d=\"M14 17.5C14 19 12.9 20 11.5 20 10.1 20 9 18.9 9 17.5c0-.8.4-1.5 1-2\"/>')],\n ['superscript', svgWrap('<path d=\"m4 19 8-8\"/><path d=\"m12 19-8-8\"/><path d=\"M20 12h-4c0-1.5.44-2 1.5-2.5S20 8.33 20 7.25C20 6 19 5 17.5 5S15 6 15 7\"/>')],\n ['subscript', svgWrap('<path d=\"m4 5 8 8\"/><path d=\"m12 5-8 8\"/><path d=\"M20 21h-4c0-1.5.44-2 1.5-2.5S20 17.33 20 16.25C20 15 19 14 17.5 14S15 15 15 16\"/>')],\n // Alignment\n ['align-left', svgWrap('<line x1=\"21\" y1=\"6\" x2=\"3\" y2=\"6\"/><line x1=\"15\" y1=\"12\" x2=\"3\" y2=\"12\"/><line x1=\"17\" y1=\"18\" x2=\"3\" y2=\"18\"/>')],\n ['align-center', svgWrap('<line x1=\"21\" y1=\"6\" x2=\"3\" y2=\"6\"/><line x1=\"18\" y1=\"12\" x2=\"6\" y2=\"12\"/><line x1=\"21\" y1=\"18\" x2=\"3\" y2=\"18\"/>')],\n ['align-right', svgWrap('<line x1=\"21\" y1=\"6\" x2=\"3\" y2=\"6\"/><line x1=\"21\" y1=\"12\" x2=\"9\" y2=\"12\"/><line x1=\"21\" y1=\"18\" x2=\"7\" y2=\"18\"/>')],\n ['align-justify', svgWrap('<line x1=\"21\" y1=\"6\" x2=\"3\" y2=\"6\"/><line x1=\"21\" y1=\"12\" x2=\"3\" y2=\"12\"/><line x1=\"21\" y1=\"18\" x2=\"3\" y2=\"18\"/>')],\n // Lists\n ['list-ul', svgWrap('<line x1=\"9\" y1=\"6\" x2=\"20\" y2=\"6\"/><line x1=\"9\" y1=\"12\" x2=\"20\" y2=\"12\"/><line x1=\"9\" y1=\"18\" x2=\"20\" y2=\"18\"/><circle cx=\"4\" cy=\"6\" r=\"1\" fill=\"currentColor\" stroke=\"none\"/><circle cx=\"4\" cy=\"12\" r=\"1\" fill=\"currentColor\" stroke=\"none\"/><circle cx=\"4\" cy=\"18\" r=\"1\" fill=\"currentColor\" stroke=\"none\"/>')],\n ['list-ol', svgWrap('<line x1=\"10\" y1=\"6\" x2=\"21\" y2=\"6\"/><line x1=\"10\" y1=\"12\" x2=\"21\" y2=\"12\"/><line x1=\"10\" y1=\"18\" x2=\"21\" y2=\"18\"/><path d=\"M4 6h1V3\"/><path d=\"M4 10h2l-2 2h2\"/><path d=\"M4 16.5A1.5 1.5 0 0 1 5.5 15a1.5 1.5 0 0 1 0 3H4\"/>')],\n ['indent', svgWrap('<polyline points=\"3 8 7 12 3 16\"/><line x1=\"21\" y1=\"12\" x2=\"11\" y2=\"12\"/><line x1=\"21\" y1=\"6\" x2=\"11\" y2=\"6\"/><line x1=\"21\" y1=\"18\" x2=\"11\" y2=\"18\"/>')],\n ['outdent', svgWrap('<polyline points=\"7 8 3 12 7 16\"/><line x1=\"21\" y1=\"12\" x2=\"11\" y2=\"12\"/><line x1=\"21\" y1=\"6\" x2=\"11\" y2=\"6\"/><line x1=\"21\" y1=\"18\" x2=\"11\" y2=\"18\"/>')],\n // History\n ['undo', svgWrap('<path d=\"M3 7v6h6\"/><path d=\"M21 17a9 9 0 0 0-9-9 9 9 0 0 0-6 2.3L3 13\"/>')],\n ['redo', svgWrap('<path d=\"M21 7v6h-6\"/><path d=\"M3 17a9 9 0 0 1 9-9 9 9 0 0 1 6 2.3L21 13\"/>')],\n // Insert\n ['minus', svgWrap('<line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/>')],\n ['link', svgWrap('<path d=\"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71\"/><path d=\"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71\"/>')],\n ['image', svgWrap('<rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\"/><circle cx=\"8.5\" cy=\"8.5\" r=\"1.5\"/><polyline points=\"21 15 16 10 5 21\"/>')],\n ['video', svgWrap('<polygon points=\"23 7 16 12 23 17 23 7\"/><rect x=\"1\" y=\"5\" width=\"15\" height=\"14\" rx=\"2\"/>')],\n ['table', svgWrap('<rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"1\"/><line x1=\"3\" y1=\"9\" x2=\"21\" y2=\"9\"/><line x1=\"3\" y1=\"15\" x2=\"21\" y2=\"15\"/><line x1=\"9\" y1=\"3\" x2=\"9\" y2=\"21\"/><line x1=\"15\" y1=\"3\" x2=\"15\" y2=\"21\"/>')],\n ['emoji', svgWrap('<circle cx=\"12\" cy=\"12\" r=\"10\"/><path d=\"M8.5 14.5s1.5 2.5 3.5 2.5 3.5-2.5 3.5-2.5\"/><circle cx=\"9\" cy=\"9\" r=\"1.5\" fill=\"currentColor\" stroke=\"none\"/><circle cx=\"15\" cy=\"9\" r=\"1.5\" fill=\"currentColor\" stroke=\"none\"/>')],\n ['icon', svgWrap('<circle cx=\"8\" cy=\"8\" r=\"3\"/><circle cx=\"16\" cy=\"8\" r=\"3\"/><rect x=\"5\" y=\"13\" width=\"6\" height=\"6\" rx=\"1\"/><rect x=\"13\" y=\"13\" width=\"6\" height=\"6\" rx=\"1\"/>')],\n // View\n ['code', svgWrap('<polyline points=\"16 18 22 12 16 6\"/><polyline points=\"8 6 2 12 8 18\"/>')],\n ['expand', svgWrap('<polyline points=\"15 3 21 3 21 9\"/><polyline points=\"9 21 3 21 3 15\"/><line x1=\"21\" y1=\"3\" x2=\"14\" y2=\"10\"/><line x1=\"3\" y1=\"21\" x2=\"10\" y2=\"14\"/>')],\n // Color pickers\n ['foreColor', svgWrap('<path d=\"M4 20L12 4L20 20\"/><line x1=\"7.5\" y1=\"14\" x2=\"16.5\" y2=\"14\"/>')],\n ['backColor', svgWrap('<path d=\"M3 21v-4l9-9 4 4-9 9z\"/><path d=\"M12 8l4 4\"/>')],\n ['keyboard', svgWrap('<rect x=\"2\" y=\"6\" width=\"20\" height=\"12\" rx=\"2\"/><line x1=\"6\" y1=\"10\" x2=\"6\" y2=\"10\" stroke-width=\"2.5\"/><line x1=\"10\" y1=\"10\" x2=\"10\" y2=\"10\" stroke-width=\"2.5\"/><line x1=\"14\" y1=\"10\" x2=\"14\" y2=\"10\" stroke-width=\"2.5\"/><line x1=\"18\" y1=\"10\" x2=\"18\" y2=\"10\" stroke-width=\"2.5\"/><line x1=\"8\" y1=\"14\" x2=\"16\" y2=\"14\" stroke-width=\"2\"/>')],\n ['caption', svgWrap('<rect x=\"3\" y=\"3\" width=\"18\" height=\"11\" rx=\"2\"/><line x1=\"6\" y1=\"18\" x2=\"18\" y2=\"18\"/><line x1=\"9\" y1=\"21\" x2=\"15\" y2=\"21\"/>')],\n ['remove-format', svgWrap('<path d=\"m7 21-4.3-4.3c-1-1-1-2.5 0-3.4l9.6-9.6c1-1 2.5-1 3.4 0l5.6 5.6c1 1 1 2.5 0 3.4L13 21\"/><path d=\"M22 21H7\"/><path d=\"m5 11 9 9\"/>')],\n ['direction', svgWrap('<path d=\"M12 20V4\"/><path d=\"m9 7-3 3 3 3\"/><path d=\"M4 10h8\"/><path d=\"m15 7 3 3-3 3\"/><path d=\"M20 10h-8\"/>')],\n ['search', svgWrap('<circle cx=\"11\" cy=\"11\" r=\"7\"/><line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\"/>')],\n ['find-replace', svgWrap('<circle cx=\"10\" cy=\"10\" r=\"6\"/><line x1=\"18\" y1=\"18\" x2=\"14.35\" y2=\"14.35\"/><path d=\"M16 19h6\"/><path d=\"M19 16v6\"/>')],\n ['inline-code', svgWrap('<path d=\"M8 3H7a2 2 0 0 0-2 2v5a2 2 0 0 1-2 2 2 2 0 0 1 2 2v5c0 1.1.9 2 2 2h1\"/><path d=\"M16 3h1a2 2 0 0 1 2 2v5c0 1.1.9 2 2 2a2 2 0 0 1-2 2v5a2 2 0 0 1-2 2h-1\"/>')],\n ['checklist', svgWrap('<rect x=\"3\" y=\"4\" width=\"5\" height=\"5\" rx=\"1\"/><path d=\"m4 6.5 1 1 2-2\"/><rect x=\"3\" y=\"13\" width=\"5\" height=\"5\" rx=\"1\"/><line x1=\"10\" y1=\"6.5\" x2=\"21\" y2=\"6.5\"/><line x1=\"10\" y1=\"15.5\" x2=\"21\" y2=\"15.5\"/>')],\n ['print', svgWrap('<path d=\"M6 9V2h12v7\"/><path d=\"M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2\"/><rect x=\"6\" y=\"14\" width=\"12\" height=\"8\"/>')],\n ]);\n\n const faPrefix = this.options.fontAwesomeClass || 'fas';\n const faMap = new Map([\n ['bold', 'fa-bold'],\n ['italic', 'fa-italic'],\n ['underline', 'fa-underline'],\n ['strikethrough', 'fa-strikethrough'],\n ['superscript', 'fa-superscript'],\n ['subscript', 'fa-subscript'],\n ['align-left', 'fa-align-left'],\n ['align-center', 'fa-align-center'],\n ['align-right', 'fa-align-right'],\n ['align-justify', 'fa-align-justify'],\n ['list-ul', 'fa-list-ul'],\n ['list-ol', 'fa-list-ol'],\n ['indent', 'fa-indent'],\n ['outdent', 'fa-outdent'],\n ['undo', 'fa-rotate-left'],\n ['redo', 'fa-rotate-right'],\n ['minus', 'fa-minus'],\n ['link', 'fa-link'],\n ['image', 'fa-image'],\n ['code', 'fa-code'],\n ['expand', 'fa-expand'],\n ['emoji', 'fa-face-smile'],\n ['icon', 'fa-icons'],\n ['foreColor', 'fa-font'],\n ['backColor', 'fa-highlighter'],\n ['keyboard', 'fa-keyboard'],\n ['remove-format', 'fa-remove-format'],\n ['direction', 'fa-arrow-right-arrow-left'],\n ['search', 'fa-magnifying-glass'],\n ['find-replace', 'fa-magnifying-glass-plus'],\n ['inline-code', 'fa-code'],\n ['checklist', 'fa-list-check'],\n ['print', 'fa-print'],\n ]);\n\n const useFaNow = this._faReady;\n if (useFaNow) {\n const faName = faMap.get(btnDef.icon) || faMap.get(btnDef.name) || null;\n if (faName) {\n btn.innerHTML = `<i class=\"${faPrefix} ${faName}\" aria-hidden=\"true\"></i>`;\n } else if (svgMap.has(btnDef.icon)) {\n btn.innerHTML = svgMap.get(btnDef.icon);\n } else {\n btn.textContent = btnDef.icon || btnDef.name;\n }\n } else {\n // FontAwesome absent: use SVG fallback when available\n if (svgMap.has(btnDef.icon)) {\n btn.innerHTML = svgMap.get(btnDef.icon);\n } else if (svgMap.has(btnDef.name)) {\n btn.innerHTML = svgMap.get(btnDef.name);\n } else {\n btn.textContent = btnDef.icon || btnDef.name;\n }\n }\n\n const disposer = on(btn, 'click', (event) => {\n event.preventDefault();\n // Restore focus to the editor before executing the action\n this.context.invoke('editor.focus');\n btnDef.action(this.context);\n this.context.invoke('editor.afterCommand');\n this.refresh();\n });\n\n this._disposers.push(disposer);\n return btn;\n }\n\n // ---------------------------------------------------------------------------\n // FontAwesome detection (run once at initialize time)\n // ---------------------------------------------------------------------------\n\n _detectFontAwesome() {\n if (!this.options.useFontAwesome) return false;\n // Return cached result when available. This ensures that a later-initialised\n // toolbar sees the same detection state as the first one — even if IconDialog\n // has since injected its own FA <link> into <head> for the icon-picker UI.\n if (_faPageLevelReady !== null) return _faPageLevelReady;\n if (document.querySelector('.fa, .fas, .far, .fal, .fab, .fa-solid')) {\n _faPageLevelReady = true;\n return true;\n }\n // Exclude the editor-self-injected link (id='an-fontawesome-css') so it doesn't\n // count as \"the host page loaded FA\" for toolbar icon rendering purposes.\n const links = Array.from(document.querySelectorAll('link[rel=\"stylesheet\"]'))\n .filter((l) => l.id !== 'an-fontawesome-css')\n .map((l) => l.href || '').join(' ');\n _faPageLevelReady = /fontawesome|font-awesome|use\\.fontawesome|all\\.css/.test(links);\n return _faPageLevelReady;\n }\n\n // ---------------------------------------------------------------------------\n // State refresh (active / disabled states)\n // ---------------------------------------------------------------------------\n\n refresh() {\n if (!this.el) return;\n const btnMap = this._btnMap || new Map();\n\n // Sync button active states\n this.el.querySelectorAll('button[data-btn]').forEach((btn) => {\n const def = btnMap.get(btn.getAttribute('data-btn'));\n if (def && typeof def.isActive === 'function') {\n btn.classList.toggle('active', !!def.isActive(this.context));\n }\n if (def && typeof def.isDisabled === 'function') {\n btn.disabled = !!def.isDisabled(this.context);\n }\n });\n\n // Sync select dropdowns (e.g. font family) with current cursor position\n this.el.querySelectorAll('select[data-btn]').forEach((select) => {\n const def = btnMap.get(select.getAttribute('data-btn'));\n if (!def || typeof def.getValue !== 'function') return;\n // queryCommandValue returns the font name, possibly quoted — strip quotes\n let raw = (def.getValue(this.context) || '').replace(/[\"']/g, '').trim();\n // Fallback: when no selection/font set, use the configured default font\n if (!raw) {\n raw = this.options.defaultFontFamily\n || (this.options.fontFamilies && this.options.fontFamilies[0])\n || '';\n }\n // Try to match against available options (case-insensitive)\n const matched = Array.from(select.options).find(\n (opt) => opt.value && opt.value.toLowerCase() === raw.toLowerCase()\n );\n select.value = matched ? matched.value : '';\n });\n }\n\n /**\n * Shows the toolbar.\n */\n show() {\n if (this.el) this.el.style.display = '';\n }\n\n /**\n * Hides the toolbar.\n */\n hide() {\n if (this.el) this.el.style.display = 'none';\n }\n}\n","/**\n * Statusbar.js - Displays word count, character count and resize handle\n * Inspired by Summernote's Statusbar module — rewritten without jQuery\n */\n\nimport { createElement, on } from '../core/dom.js';\nimport { debounce } from '../core/func.js';\n\n// Cache the segmenter instance at module level to avoid per-call allocation\nconst _segmenter =\n typeof Intl !== 'undefined' && typeof Intl.Segmenter === 'function'\n ? new Intl.Segmenter(undefined, { granularity: 'word' })\n : null;\n\n/**\n * Count words in a string, CJK-aware.\n * Uses Intl.Segmenter (Chromium 87+, Firefox 125+, Safari 17+) when available,\n * falling back to a simple whitespace split for older environments.\n * @param {string} text\n * @returns {number}\n */\nfunction _countWords(text) {\n const trimmed = text.trim();\n if (!trimmed) return 0;\n if (_segmenter) {\n let count = 0;\n for (const seg of _segmenter.segment(trimmed)) {\n if (seg.isWordLike) count++;\n }\n return count;\n }\n // Fallback: split on whitespace\n return trimmed.split(/\\s+/).length;\n}\n\n/**\n * Toggles warning/exceeded CSS classes on a count element.\n * @param {HTMLElement} el\n * @param {number} current\n * @param {number} limit 0 = no limit\n */\nfunction _applyLimitClass(el, current, limit) {\n if (!limit) {\n el.classList.remove('an-count-warn', 'an-count-exceeded');\n return;\n }\n if (current > limit) {\n el.classList.add('an-count-exceeded');\n el.classList.remove('an-count-warn');\n } else if (current >= limit * 0.9) {\n el.classList.add('an-count-warn');\n el.classList.remove('an-count-exceeded');\n } else {\n el.classList.remove('an-count-warn', 'an-count-exceeded');\n }\n}\n\nexport class Statusbar {\n /**\n * @param {import('../Context.js').Context} context\n */\n constructor(context) {\n this.context = context;\n this.options = context.options;\n /** @type {HTMLElement|null} */\n this.el = null;\n this._disposers = [];\n /** @type {HTMLElement|null} */\n this._wordCountEl = null;\n /** @type {HTMLElement|null} */\n this._charCountEl = null;\n }\n\n // ---------------------------------------------------------------------------\n // Lifecycle\n // ---------------------------------------------------------------------------\n\n initialize() {\n this.el = createElement('div', { class: 'an-statusbar' });\n\n // Resize handle\n if (this.options.resizable !== false) {\n const handle = createElement('div', {\n class: 'an-resize-handle',\n title: 'Resize editor',\n 'aria-hidden': 'true',\n });\n this._bindResize(handle);\n this.el.appendChild(handle);\n }\n\n // Counters\n this._wordCountEl = createElement('span', { class: 'an-word-count' });\n this._charCountEl = createElement('span', { class: 'an-char-count' });\n const info = createElement('div', { class: 'an-status-info' });\n info.appendChild(this._wordCountEl);\n info.appendChild(this._charCountEl);\n this.el.appendChild(info);\n\n this._bindContentEvents();\n this.update();\n return this;\n }\n\n destroy() {\n this._disposers.forEach((d) => d());\n this._disposers = [];\n if (this._dragDisposers) {\n this._dragDisposers.forEach((d) => d());\n this._dragDisposers = null;\n }\n if (this.el && this.el.parentNode) {\n this.el.parentNode.removeChild(this.el);\n }\n this.el = null;\n }\n\n // ---------------------------------------------------------------------------\n // Resize logic\n // ---------------------------------------------------------------------------\n\n _bindResize(handle) {\n let startY = 0;\n let startH = 0;\n // Resize the container (flex column parent) so that the editable — which\n // has flex:1 / flex-basis:0 — automatically fills the remaining space.\n // Setting height directly on a flex:1 item has no effect because the flex\n // algorithm ignores the height property when flex-basis is non-auto.\n const containerEl = this.context.layoutInfo.container;\n\n const applyDelta = (clientY) => {\n const delta = clientY - startY;\n // Compute the true minimum: fixed elements (toolbar + statusbar) must fit\n // inside the container. Sum the offsetHeight of every child that is NOT\n // the editable area, then add a small floor so the editable stays visible.\n const MIN_EDITABLE = 40;\n const fixedH = Array.from(containerEl.children)\n .filter(child => !child.classList.contains('an-editable'))\n .reduce((sum, child) => sum + child.offsetHeight, 0);\n const trueMin = Math.max(this.options.minHeight || 100, fixedH + MIN_EDITABLE);\n containerEl.style.height = `${Math.max(trueMin, startH + delta)}px`;\n };\n\n // Mouse drag\n const onMouseMove = (event) => applyDelta(event.clientY);\n\n const onMouseUp = () => {\n document.removeEventListener('mousemove', onMouseMove);\n document.removeEventListener('mouseup', onMouseUp);\n this._dragDisposers = null;\n };\n\n const onMouseDown = (event) => {\n startY = event.clientY;\n startH = containerEl.offsetHeight;\n // Clear the editable's inline min-height so the flex layout can compress\n // it freely once the container has a fixed height. Without this, the\n // editable's min-height (set from options.height) overflows the container\n // when the user drags the handle to a size smaller than that value.\n this.context.layoutInfo.editable.style.minHeight = '';\n document.addEventListener('mousemove', onMouseMove);\n document.addEventListener('mouseup', onMouseUp);\n // Track drag-phase listeners so destroy() can remove them mid-drag\n this._dragDisposers = [\n () => document.removeEventListener('mousemove', onMouseMove),\n () => document.removeEventListener('mouseup', onMouseUp),\n ];\n event.preventDefault();\n };\n\n // Touch drag\n const onTouchMove = (event) => {\n const touch = event.touches[0];\n if (touch) { event.preventDefault(); applyDelta(touch.clientY); }\n };\n\n const onTouchEnd = () => {\n document.removeEventListener('touchmove', onTouchMove);\n document.removeEventListener('touchend', onTouchEnd);\n this._dragDisposers = null;\n };\n\n const onTouchStart = (event) => {\n const touch = event.touches[0];\n if (!touch) return;\n startY = touch.clientY;\n startH = containerEl.offsetHeight;\n // Same as onMouseDown: clear editable min-height so flex can compress it\n this.context.layoutInfo.editable.style.minHeight = '';\n document.addEventListener('touchmove', onTouchMove, { passive: false });\n document.addEventListener('touchend', onTouchEnd);\n this._dragDisposers = [\n () => document.removeEventListener('touchmove', onTouchMove),\n () => document.removeEventListener('touchend', onTouchEnd),\n ];\n };\n\n const d1 = on(handle, 'mousedown', onMouseDown);\n const d2 = on(handle, 'touchstart', onTouchStart);\n this._disposers.push(d1, d2);\n }\n\n // ---------------------------------------------------------------------------\n // Counter update\n // ---------------------------------------------------------------------------\n\n _bindContentEvents() {\n const editable = this.context.layoutInfo.editable;\n const updateDebounced = debounce(() => this.update(), 200);\n const d = on(editable, 'input', updateDebounced);\n this._disposers.push(d);\n }\n\n update() {\n if (!this._wordCountEl || !this._charCountEl) return;\n const editable = this.context.layoutInfo.editable;\n const text = editable.innerText || '';\n const words = _countWords(text);\n const chars = text.replace(/\\n/g, '').length;\n const maxWords = this.options.maxWords || 0;\n const maxChars = this.options.maxChars || 0;\n\n this._wordCountEl.textContent = maxWords\n ? `Words: ${words}/${maxWords}`\n : `Words: ${words}`;\n this._charCountEl.textContent = maxChars\n ? `Chars: ${chars}/${maxChars}`\n : `Chars: ${chars}`;\n\n // Apply warning / exceeded styles\n _applyLimitClass(this._wordCountEl, words, maxWords);\n _applyLimitClass(this._charCountEl, chars, maxChars);\n }\n\n /**\n * Returns the current word count of the editor content.\n * @returns {number}\n */\n getWordCount() {\n const editable = this.context.layoutInfo.editable;\n return _countWords(editable.innerText || '');\n }\n\n /**\n * Returns the current character count (excluding newlines) of the editor content.\n * @returns {number}\n */\n getCharCount() {\n const editable = this.context.layoutInfo.editable;\n return ((editable.innerText || '').replace(/\\n/g, '')).length;\n }\n}\n","/**\n * Clipboard.js - Handles paste events to strip unwanted formatting,\n * and paste/drop of image files.\n * Inspired by Summernote's Clipboard module\n */\n\nimport { on } from '../core/dom.js';\nimport { execCommand } from '../editing/Style.js';\nimport { sanitiseHTML } from '../core/sanitise.js';\nimport { isMarkdown, markdownToHTML } from '../core/markdown.js';\n\nexport class Clipboard {\n /**\n * @param {import('../Context.js').Context} context\n */\n constructor(context) {\n this.context = context;\n this.options = context.options;\n this._disposers = [];\n }\n\n initialize() {\n /** @type {Map<string, string>} Maps blob: URL (in DOM) → data: URL (serialisable) */\n this._blobRegistry = new Map();\n /** @type {boolean} Set to true by Ctrl+Shift+V shortcut to force one-shot plain paste */\n this._forcePlain = false;\n const editable = this.context.layoutInfo.editable;\n this._disposers.push(\n on(editable, 'paste', (e) => this._onPaste(e)),\n on(editable, 'dragover', (e) => this._onDragover(e)),\n on(editable, 'drop', (e) => this._onDrop(e)),\n );\n\n // Watch for removed images so their blob: URLs are revoked immediately,\n // preventing memory leaks during long editing sessions.\n this._mutationObserver = new MutationObserver((mutations) => {\n for (const mutation of mutations) {\n for (const node of mutation.removedNodes) {\n this._revokeRemovedBlobs(node);\n }\n }\n });\n this._mutationObserver.observe(editable, { childList: true, subtree: true });\n\n return this;\n }\n\n destroy() {\n this._disposers.forEach((d) => d());\n this._disposers = [];\n if (this._mutationObserver) {\n this._mutationObserver.disconnect();\n this._mutationObserver = null;\n }\n // Release any remaining object URLs\n if (this._blobRegistry) {\n this._blobRegistry.forEach((_, blobUrl) => URL.revokeObjectURL(blobUrl));\n this._blobRegistry.clear();\n }\n }\n\n /**\n * Revokes blob URLs for any <img> elements removed from the DOM.\n * @param {Node} node\n */\n _revokeRemovedBlobs(node) {\n if (!this._blobRegistry || !this._blobRegistry.size) return;\n const imgs = [];\n if (node.nodeName === 'IMG') {\n imgs.push(node);\n } else if (node.querySelectorAll) {\n imgs.push(...node.querySelectorAll('img'));\n }\n imgs.forEach((img) => {\n const src = img.getAttribute('src') || '';\n if (src.startsWith('blob:') && this._blobRegistry.has(src)) {\n URL.revokeObjectURL(src);\n this._blobRegistry.delete(src);\n }\n });\n }\n\n // ---------------------------------------------------------------------------\n // Paste handler\n // ---------------------------------------------------------------------------\n\n /**\n * Strips Microsoft Word / Office HTML artefacts from a pasted HTML string.\n * Removes conditional comments, Office namespace elements, MsoXxx classes,\n * mso-* inline style rules, and empty paragraphs left behind by Word.\n * @param {string} html\n * @returns {string}\n */\n _cleanWordHtml(html) {\n return html\n // Conditional comments <!--[if ...]>...<![endif]-->\n .replace(/<!--\\[if[\\s\\S]*?\\[endif\\]-->/gi, '')\n // XML data blobs <xml>...</xml>\n .replace(/<xml[\\s\\S]*?<\\/xml>/gi, '')\n // XML processing instructions <?xml ... ?>\n .replace(/<\\?xml[\\s\\S]*?\\?>/gi, '')\n // Office namespace elements: <o:p>, <w:sDt>, <m:oMath>, <v:shape> …\n .replace(/<\\/?(o|w|m|v|st1):[a-z][^>]*>/gi, '')\n // MsoNormal, MsoBodyText, etc. class attributes\n .replace(/\\s+class=\"Mso[^\"]*\"/gi, '')\n // mso-* properties inside inline style attributes\n .replace(/\\s+style=\"([^\"]*)\"/gi, (_m, style) => {\n const cleaned = style.split(';')\n .map((s) => s.trim())\n .filter((s) => s && !/^mso-/i.test(s) && !/^(tab-stops|margin-[a-z]+-alt)/i.test(s))\n .join('; ');\n return cleaned ? ` style=\"${cleaned}\"` : '';\n })\n // Empty paragraphs Word sprinkles everywhere\n .replace(/<p[^>]*>\\s*( )?\\s*<\\/p>/gi, '');\n }\n\n /**\n * Detects and strips noise from social media sites (Facebook, X/Twitter, LinkedIn, etc.).\n * These React-based pages produce HTML with utility class names like `x1n2onr6` / `r-bcqeeo`,\n * `data-testid`, `data-lexical-*`, etc. We keep the semantic structure but remove all the noise.\n * @param {string} html\n * @returns {string}\n */\n _cleanSocialHtml(html) {\n const doc = new DOMParser().parseFromString(`<body>${html}</body>`, 'text/html');\n // Unwrap purely presentational wrapper spans/divs with no semantic meaning\n const UNWRAP_TAGS = new Set(['span', 'div']);\n let changed = true;\n // Iteratively unwrap until stable (handles deeply nested span soup)\n while (changed) {\n changed = false;\n doc.querySelectorAll('span, div').forEach((el) => {\n if (!UNWRAP_TAGS.has(el.tagName.toLowerCase())) return;\n // Keep if it has a meaningful role (link, heading, list item are handled by parent)\n if (el.querySelector('a, strong, em, b, i, ul, ol, li, table, img, blockquote, pre, code, h1, h2, h3, h4, h5, h6')) return;\n // Unwrap — replace el with its children\n const parent = el.parentNode;\n if (!parent) return;\n while (el.firstChild) parent.insertBefore(el.firstChild, el);\n parent.removeChild(el);\n changed = true;\n });\n }\n // Strip class and all data-* attributes from every remaining element\n doc.querySelectorAll('*').forEach((el) => {\n el.removeAttribute('class');\n el.removeAttribute('id');\n Array.from(el.attributes)\n .filter((a) => a.name.startsWith('data-') || a.name.startsWith('aria-'))\n .forEach((a) => el.removeAttribute(a.name));\n });\n return doc.body.innerHTML;\n }\n\n /**\n * Strips presentational attributes (class, style, data-*, id) from all elements,\n * keeping only semantic structure and URL attributes.\n * Used when `pasteStripAttributes` option is true.\n * @param {string} html\n * @returns {string}\n */\n _stripAttributes(html) {\n const doc = new DOMParser().parseFromString(`<body>${html}</body>`, 'text/html');\n const KEEP_ATTRS = new Set(['href', 'src', 'alt', 'target', 'rel', 'colspan', 'rowspan', 'type']);\n doc.querySelectorAll('*').forEach((el) => {\n Array.from(el.attributes)\n .filter((a) => !KEEP_ATTRS.has(a.name))\n .forEach((a) => el.removeAttribute(a.name));\n });\n return doc.body.innerHTML;\n }\n\n /**\n * Forces the next paste operation to strip all HTML formatting.\n * Called by Editor when Ctrl+Shift+V is pressed.\n * @param {boolean} val\n */\n setForcePlain(val) {\n this._forcePlain = !!val;\n }\n\n _onPaste(event) {\n const clipboardData = event.clipboardData || window.clipboardData;\n if (!clipboardData) return;\n\n // Consume and reset the one-shot plain-paste flag\n const forcePlain = this._forcePlain;\n this._forcePlain = false;\n\n // 1. Image file in clipboard (screenshot, copy-image-from-browser, etc.)\n if (clipboardData.items) {\n const imageItems = Array.from(clipboardData.items).filter(\n (item) => item.kind === 'file' && item.type.startsWith('image/'),\n );\n if (imageItems.length > 0) {\n event.preventDefault();\n const files = imageItems.map((item) => item.getAsFile()).filter(Boolean);\n this._insertImageFiles(files);\n return;\n }\n }\n\n // Fire onPaste hook so consumers can observe / intercept\n if (typeof this.options.onPaste === 'function') {\n this.options.onPaste({\n text: clipboardData.getData('text/plain') || '',\n html: clipboardData.types.includes('text/html') ? clipboardData.getData('text/html') : null,\n });\n }\n\n // 2. Force plain-text only — strip all formatting\n if (forcePlain || this.options.pasteAsPlainText) {\n event.preventDefault();\n const text = clipboardData.getData('text/plain');\n const html = text\n .split(/\\r?\\n/)\n .map((line) => `<p>${this._escapeHTML(line) || '<br>'}</p>`)\n .join('');\n execCommand('insertHTML', html);\n this.context.invoke('editor.afterCommand');\n return;\n }\n\n // 3. Markdown paste — only when no HTML is on the clipboard (pure text source)\n if (this.options.markdownPaste !== false && !clipboardData.types.includes('text/html')) {\n const text = clipboardData.getData('text/plain');\n if (text && isMarkdown(text)) {\n event.preventDefault();\n const html = sanitiseHTML(markdownToHTML(text));\n execCommand('insertHTML', html);\n this.context.invoke('editor.afterCommand');\n return;\n }\n }\n\n // 4. Sanitise HTML on paste when pasteCleanHTML is true (default)\n if (this.options.pasteCleanHTML !== false && clipboardData.types.includes('text/html')) {\n event.preventDefault();\n const raw = clipboardData.getData('text/html');\n // Detect source type and apply appropriate pre-cleaner\n const isWordContent = /<[a-z]+:[a-z]/i.test(raw) || /class=\"Mso/i.test(raw) || /\\bmso-/i.test(raw);\n const isSocialContent = /\\bdata-testid\\b/.test(raw) || /class=\"[^\"]*\\b(?:x[a-z0-9]{6,}|r-[a-z0-9]{3,})\\b/.test(raw);\n let html = raw;\n if (isWordContent) html = this._cleanWordHtml(html);\n else if (isSocialContent) html = this._cleanSocialHtml(html);\n html = sanitiseHTML(html);\n if (this.options.pasteStripAttributes) html = this._stripAttributes(html);\n execCommand('insertHTML', html);\n this.context.invoke('editor.afterCommand');\n return;\n }\n\n // Otherwise let the browser handle paste natively\n }\n\n // ---------------------------------------------------------------------------\n // Drag & drop handlers\n // ---------------------------------------------------------------------------\n\n _onDragover(event) {\n if (!event.dataTransfer) return;\n const types = Array.from(event.dataTransfer.types || []);\n if (types.includes('Files')) {\n event.preventDefault();\n event.dataTransfer.dropEffect = 'copy';\n }\n }\n\n _onDrop(event) {\n const dt = event.dataTransfer;\n if (!dt || !dt.files || dt.files.length === 0) return;\n\n const imageFiles = Array.from(dt.files).filter((f) => f.type.startsWith('image/'));\n if (imageFiles.length === 0) return;\n\n event.preventDefault();\n event.stopPropagation();\n\n // Place the caret at the drop coordinates before inserting\n this._placeCaretAtPoint(event.clientX, event.clientY);\n this._insertImageFiles(imageFiles);\n }\n\n // ---------------------------------------------------------------------------\n // Image file processing — shared by paste and drop\n // ---------------------------------------------------------------------------\n\n /**\n * Inserts one or more image Files into the editor.\n * Delegates to `options.onImageUpload` when provided; otherwise compresses\n * and embeds as base64.\n * @param {File[]} files\n */\n _insertImageFiles(files) {\n if (!files || files.length === 0) return;\n\n if (typeof this.options.onImageUpload === 'function') {\n this.options.onImageUpload(files);\n return;\n }\n\n const maxBytes = (this.options.maxImageSize || 5) * 1024 * 1024;\n files.forEach((file) => {\n if (!file || !file.type.startsWith('image/')) return;\n if (file.size > maxBytes) {\n const message = `Image \"${file.name}\" exceeds the ${this.options.maxImageSize || 5} MB size limit.`;\n this.context.triggerEvent('imageError', { file, message });\n console.warn(`[AutumnNote] ${message}`);\n return;\n }\n\n const alt = file.name.replace(/\\.[^.]+$/, '');\n this._compressImage(file).then((dataUrl) => {\n // Keep the large data URL in a JS Map; insert a lightweight blob: URL\n // into the DOM so editable.innerHTML never contains the big base64 string.\n const blob = this._dataUrlToBlob(dataUrl);\n const blobUrl = URL.createObjectURL(blob);\n this._blobRegistry.set(blobUrl, dataUrl);\n this.context.invoke('editor.insertImage', blobUrl, alt);\n }).catch((err) => {\n const message = `Image \"${file.name}\" could not be processed.`;\n this.context.triggerEvent('imageError', { file, message, error: err });\n if (typeof process === 'undefined' || process.env?.NODE_ENV !== 'production') {\n console.warn('[AutumnNote]', message, err);\n }\n });\n });\n }\n\n /**\n * Replaces any blob: URLs created by this module with their original data URLs.\n * Called by Editor.getHTML() so the returned HTML is fully self-contained.\n * @param {string} html\n * @returns {string}\n */\n resolveImages(html) {\n if (!this._blobRegistry || !this._blobRegistry.size) return html;\n return html.replace(/blob:[^\"'> \\t\\n\\r]*/g, (url) => this._blobRegistry.get(url) || url);\n }\n\n /**\n * Converts a data URL to a Blob (no FileReader — synchronous).\n * @param {string} dataUrl\n * @returns {Blob}\n */\n _dataUrlToBlob(dataUrl) {\n const [header, b64] = dataUrl.split(',');\n const mime = header.match(/:(.*?);/)[1];\n const binary = atob(b64);\n const arr = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) arr[i] = binary.charCodeAt(i);\n return new Blob([arr], { type: mime });\n }\n\n /**\n * Compresses an image File using a Canvas.\n * - Resizes so the longest edge is at most MAX_DIM pixels.\n * - Encodes as WebP (if supported) or JPEG at quality 0.85.\n * Falls back to plain FileReader if canvas is unavailable.\n * @param {File} file\n * @returns {Promise<string>} data URL\n */\n _compressImage(file) {\n const MAX_DIM = 1920;\n const QUALITY = 0.85;\n\n return new Promise((resolve) => {\n const objectUrl = URL.createObjectURL(file);\n const img = new Image();\n\n img.onload = () => {\n URL.revokeObjectURL(objectUrl);\n\n let { width, height } = img;\n if (width > MAX_DIM || height > MAX_DIM) {\n if (width >= height) {\n height = Math.round((height * MAX_DIM) / width);\n width = MAX_DIM;\n } else {\n width = Math.round((width * MAX_DIM) / height);\n height = MAX_DIM;\n }\n }\n\n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n const ctx = canvas.getContext('2d');\n if (!ctx) {\n // Canvas context unavailable (e.g. device memory limit) — fall back to\n // embedding the original file without compression.\n const reader = new FileReader();\n reader.onload = (e) => resolve(/** @type {string} */ (e.target.result));\n reader.readAsDataURL(file);\n return;\n }\n ctx.drawImage(img, 0, 0, width, height);\n\n // Prefer WebP for better compression; fall back to JPEG\n const webp = canvas.toDataURL('image/webp', QUALITY);\n resolve(webp.startsWith('data:image/webp') ? webp : canvas.toDataURL('image/jpeg', QUALITY));\n };\n\n img.onerror = () => {\n URL.revokeObjectURL(objectUrl);\n // Fallback: embed original without compression\n const reader = new FileReader();\n reader.onload = (e) => resolve(/** @type {string} */ (e.target.result));\n reader.readAsDataURL(file);\n };\n\n img.src = objectUrl;\n });\n }\n\n /**\n * Positions the caret at the given viewport coordinates.\n * Supports both Chrome (caretRangeFromPoint) and Firefox (caretPositionFromPoint).\n * @param {number} x\n * @param {number} y\n */\n _placeCaretAtPoint(x, y) {\n let range;\n if (document.caretRangeFromPoint) {\n range = document.caretRangeFromPoint(x, y);\n } else if (document.caretPositionFromPoint) {\n const pos = document.caretPositionFromPoint(x, y);\n if (pos) {\n range = document.createRange();\n range.setStart(pos.offsetNode, pos.offset);\n range.collapse(true);\n }\n }\n if (!range) return;\n const sel = window.getSelection();\n if (sel) {\n sel.removeAllRanges();\n sel.addRange(range);\n }\n }\n\n // ---------------------------------------------------------------------------\n // Helpers\n // ---------------------------------------------------------------------------\n\n /**\n * Escapes HTML special characters.\n * @param {string} str\n * @returns {string}\n */\n _escapeHTML(str) {\n return str\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n }\n}\n","/**\n * Placeholder.js - Shows placeholder text when the editor is empty\n * Inspired by Summernote's Placeholder module\n */\n\nimport { on } from '../core/dom.js';\n\nexport class Placeholder {\n /**\n * @param {import('../Context.js').Context} context\n */\n constructor(context) {\n this.context = context;\n this.options = context.options;\n this._disposers = [];\n }\n\n initialize() {\n const editable = this.context.layoutInfo.editable;\n const placeholder = this.options.placeholder || '';\n if (placeholder) {\n editable.dataset.placeholder = placeholder;\n }\n\n const update = () => this._update();\n const d1 = on(editable, 'input', update);\n const d2 = on(editable, 'focus', update);\n const d3 = on(editable, 'blur', update);\n this._disposers.push(d1, d2, d3);\n this._update();\n return this;\n }\n\n destroy() {\n this._disposers.forEach((d) => d());\n this._disposers = [];\n }\n\n _update() {\n const editable = this.context.layoutInfo.editable;\n const isFocused = document.activeElement === editable;\n const isEmpty = !editable.textContent.trim() && !editable.querySelector('img, table, hr');\n editable.classList.toggle('an-placeholder', isEmpty && !isFocused);\n }\n}\n","/**\n * Codeview.js - HTML source code view / WYSIWYG toggle\n * Inspired by Summernote's Codeview module\n */\n\nimport { createElement } from '../core/dom.js';\nimport { sanitiseHTML } from '../core/sanitise.js';\n\nexport class Codeview {\n /**\n * @param {import('../Context.js').Context} context\n */\n constructor(context) {\n this.context = context;\n this.options = context.options;\n this._active = false;\n /** @type {HTMLTextAreaElement|null} */\n this._textarea = null;\n this._disposers = [];\n }\n\n initialize() {\n return this;\n }\n\n destroy() {\n this._disposers.forEach((d) => d());\n this._disposers = [];\n if (this._textarea && this._textarea.parentNode) {\n this._textarea.parentNode.removeChild(this._textarea);\n }\n this._textarea = null;\n }\n\n // ---------------------------------------------------------------------------\n // Public API\n // ---------------------------------------------------------------------------\n\n toggle() {\n if (this._active) {\n this.deactivate();\n } else {\n this.activate();\n }\n }\n\n isActive() {\n return this._active;\n }\n\n activate() {\n if (this._active) return;\n const { editable } = this.context.layoutInfo;\n const html = editable.innerHTML;\n\n this._textarea = createElement('textarea', {\n class: 'an-codeview',\n spellcheck: 'false',\n autocomplete: 'off',\n autocorrect: 'off',\n autocapitalize: 'off',\n });\n this._textarea.value = this._prettyPrint(html);\n\n editable.style.display = 'none';\n editable.parentNode.insertBefore(this._textarea, editable.nextSibling);\n\n this._active = true;\n this.context.invoke('toolbar.refresh');\n }\n\n deactivate() {\n if (!this._active || !this._textarea) return;\n const { editable } = this.context.layoutInfo;\n // Sanitise the HTML typed in the textarea before applying (allow iframes for video embeds)\n editable.innerHTML = sanitiseHTML(this._textarea.value, { allowIframes: true });\n this._textarea.parentNode.removeChild(this._textarea);\n this._textarea = null;\n editable.style.display = '';\n this._active = false;\n this.context.invoke('toolbar.refresh');\n this.context.invoke('editor.afterCommand');\n }\n\n // ---------------------------------------------------------------------------\n // Helpers\n // ---------------------------------------------------------------------------\n\n /**\n * Very simple HTML pretty-printer (indent nested tags).\n * Inline elements (a, span, strong, em, etc.) are kept on one line to\n * avoid injecting whitespace that would change rendered text.\n * @param {string} html\n * @returns {string}\n */\n _prettyPrint(html) {\n // Tags whose content must NOT be split with newlines (breaks text rendering)\n const INLINE_RE = /^<(a|abbr|b|bdo|br|button|cite|code|dfn|em|i|img|input|kbd|label|output|q|samp|select|small|span|strong|sub|sup|textarea|time|tt|u|var)([\\s>/])/i;\n let indent = 0;\n return html\n .replace(/>\\s*</g, (match, offset, str) => {\n // Check what comes after the '>' — if it starts an inline tag, keep on same line\n const remaining = str.slice(offset + 1);\n if (INLINE_RE.test(remaining.trimStart())) return '><';\n return '>\\n<';\n })\n .split('\\n')\n .map((line) => {\n const stripped = line.trim();\n if (!stripped) return '';\n if (/^<\\//.test(stripped)) indent = Math.max(0, indent - 1);\n const out = ' '.repeat(indent) + stripped;\n if (\n /^<[^/!][^>]*[^/]>/.test(stripped) &&\n !INLINE_RE.test(stripped) &&\n !/^<(br|hr|img|input|link|meta)/.test(stripped)\n ) {\n indent++;\n }\n return out;\n })\n .filter(Boolean)\n .join('\\n');\n }\n\n}\n\n","/**\n * Fullscreen.js - Toggles the editor in/out of fullscreen mode\n * Inspired by Summernote's Fullscreen module\n */\n\nimport { on } from '../core/dom.js';\nimport { key, isKey } from '../core/key.js';\n\nexport class Fullscreen {\n /**\n * @param {import('../Context.js').Context} context\n */\n constructor(context) {\n this.context = context;\n this._active = false;\n this._disposers = [];\n /** @type {string} cached editable height before fullscreen */\n this._prevHeight = '';\n }\n\n initialize() {\n // Press Escape to exit fullscreen\n const d = on(document, 'keydown', (event) => {\n if (this._active && isKey(event, key.ESCAPE)) {\n this.deactivate();\n }\n });\n this._disposers.push(d);\n return this;\n }\n\n destroy() {\n this._disposers.forEach((d) => d());\n this._disposers = [];\n if (this._active) this.deactivate();\n }\n\n // ---------------------------------------------------------------------------\n // Public API\n // ---------------------------------------------------------------------------\n\n toggle() {\n if (this._active) {\n this.deactivate();\n } else {\n this.activate();\n }\n }\n\n isActive() {\n return this._active;\n }\n\n activate() {\n if (this._active) return;\n const container = this.context.layoutInfo.container;\n // Save the container's explicit height (set by the resize handle) so it\n // can be restored when exiting fullscreen.\n this._prevHeight = container.style.height;\n\n container.classList.add('an-fullscreen');\n // Clear any resize-imposed height so the fullscreen CSS (inset:0) takes over.\n container.style.height = '';\n document.body.style.overflow = 'hidden';\n this._active = true;\n this.context.invoke('toolbar.refresh');\n }\n\n deactivate() {\n if (!this._active) return;\n const container = this.context.layoutInfo.container;\n\n container.classList.remove('an-fullscreen');\n // Restore whatever explicit height the user had set via the resize handle.\n container.style.height = this._prevHeight;\n document.body.style.overflow = '';\n this._active = false;\n this.context.invoke('toolbar.refresh');\n }\n}\n","/**\n * LinkDialog.js - Dialog for inserting / editing hyperlinks\n * Inspired by Summernote's LinkDialog — rewritten without jQuery\n */\n\nimport { createElement, on, trapFocus } from '../core/dom.js';\nimport { withSavedRange } from '../core/range.js';\n\nexport class LinkDialog {\n /**\n * @param {import('../Context.js').Context} context\n */\n constructor(context) {\n this.context = context;\n this.options = context.options;\n /** @type {HTMLElement|null} */\n this._dialog = null;\n this._disposers = [];\n this._savedRange = null;\n }\n\n // ---------------------------------------------------------------------------\n // Lifecycle\n // ---------------------------------------------------------------------------\n\n initialize() {\n this._dialog = this._buildDialog();\n document.body.appendChild(this._dialog);\n return this;\n }\n\n destroy() {\n this._disposers.forEach((d) => d());\n this._disposers = [];\n if (this._dialog && this._dialog.parentNode) {\n this._dialog.parentNode.removeChild(this._dialog);\n }\n this._dialog = null;\n }\n\n // ---------------------------------------------------------------------------\n // Public API\n // ---------------------------------------------------------------------------\n\n /**\n * Opens the link dialog.\n * Pre-fills with the currently selected link if present.\n */\n show() {\n withSavedRange((range) => {\n this._savedRange = range;\n });\n this._prefill();\n this._open();\n }\n\n // ---------------------------------------------------------------------------\n // Build dialog\n // ---------------------------------------------------------------------------\n\n _buildDialog() {\n const overlay = createElement('div', { class: 'an-dialog-overlay', role: 'dialog', 'aria-modal': 'true', 'aria-label': 'Insert link' });\n const box = createElement('div', { class: 'an-dialog-box' });\n\n const title = createElement('h3', { class: 'an-dialog-title' });\n title.textContent = 'Insert Link';\n\n // URL field\n const urlLabel = createElement('label', { class: 'an-label' });\n urlLabel.textContent = 'URL';\n const urlInput = createElement('input', {\n type: 'url',\n class: 'an-input',\n placeholder: 'https://',\n id: 'an-link-url',\n name: 'url',\n autocomplete: 'off',\n });\n this._urlInput = urlInput;\n\n // Text field\n const textLabel = createElement('label', { class: 'an-label' });\n textLabel.textContent = 'Display Text';\n const textInput = createElement('input', {\n type: 'text',\n class: 'an-input',\n placeholder: 'Link text',\n id: 'an-link-text',\n name: 'linkText',\n autocomplete: 'off',\n });\n this._textInput = textInput;\n\n // Open in new tab\n const tabLabel = createElement('label', { class: 'an-label an-label-inline' });\n const tabCheckbox = createElement('input', {\n type: 'checkbox',\n id: 'an-link-newtab',\n name: 'openInNewTab',\n });\n this._tabCheckbox = tabCheckbox;\n tabLabel.appendChild(tabCheckbox);\n tabLabel.appendChild(document.createTextNode(' Open in new tab'));\n\n // Buttons\n const btnRow = createElement('div', { class: 'an-dialog-actions' });\n const insertBtn = createElement('button', { type: 'button', class: 'an-btn an-btn-primary' });\n insertBtn.textContent = 'Insert';\n const cancelBtn = createElement('button', { type: 'button', class: 'an-btn' });\n cancelBtn.textContent = 'Cancel';\n btnRow.appendChild(insertBtn);\n btnRow.appendChild(cancelBtn);\n\n box.append(title, urlLabel, urlInput, textLabel, textInput, tabLabel, btnRow);\n overlay.appendChild(box);\n\n // Events\n const d1 = on(insertBtn, 'click', () => this._onInsert());\n const d2 = on(cancelBtn, 'click', () => this._close());\n const d3 = on(overlay, 'click', (e) => { if (e.target === overlay) this._close(); });\n const d4 = on(urlInput, 'keydown', (e) => { if (e.key === 'Enter') { e.preventDefault(); this._onInsert(); } });\n const d5 = on(textInput, 'keydown', (e) => { if (e.key === 'Enter') { e.preventDefault(); this._onInsert(); } });\n this._disposers.push(d1, d2, d3, d4, d5);\n\n return overlay;\n }\n\n // ---------------------------------------------------------------------------\n // Actions\n // ---------------------------------------------------------------------------\n\n _prefill() {\n // Try to find currently selected anchor\n const sel = window.getSelection();\n let anchor = null;\n if (sel && sel.rangeCount > 0) {\n let node = sel.getRangeAt(0).startContainer;\n while (node) {\n if (node.nodeName === 'A') { anchor = node; break; }\n node = node.parentNode;\n }\n }\n if (anchor) {\n this._urlInput.value = anchor.getAttribute('href') || '';\n this._textInput.value = anchor.textContent || '';\n this._tabCheckbox.checked = anchor.getAttribute('target') === '_blank';\n } else {\n this._urlInput.value = '';\n this._textInput.value = sel ? sel.toString() : '';\n this._tabCheckbox.checked = false;\n }\n }\n\n _onInsert() {\n let url = this._urlInput.value.trim();\n const text = this._textInput.value.trim();\n const newTab = this._tabCheckbox.checked;\n\n if (!url) {\n this._urlInput.focus();\n return;\n }\n\n // Auto-prefix with https:// if no protocol is present\n if (!/^[a-zA-Z][a-zA-Z\\d+\\-.]*:/.test(url)) {\n url = 'https://' + url;\n }\n\n // Block unsafe protocols\n try {\n const parsed = new URL(url);\n if (/^javascript:/i.test(parsed.protocol) || /^vbscript:/i.test(parsed.protocol) || /^data:/i.test(parsed.protocol)) {\n this._urlInput.focus();\n return;\n }\n } catch {\n // URL constructor failed — not a valid URL\n this._urlInput.focus();\n return;\n }\n\n // Restore selection then insert\n if (this._savedRange) {\n this._savedRange.select();\n }\n\n this.context.invoke('editor.insertLink', url, text, newTab);\n this._close();\n }\n\n _open() {\n if (this._dialog) {\n this._dialog.style.display = 'flex';\n this._removeTrap = trapFocus(this._dialog, () => this._close());\n setTimeout(() => this._urlInput && this._urlInput.focus(), 50);\n }\n }\n\n _close() {\n if (this._dialog) this._dialog.style.display = 'none';\n if (this._removeTrap) { this._removeTrap(); this._removeTrap = null; }\n this._savedRange = null;\n }\n}\n","/**\n * ImageDialog.js - Dialog for inserting images (by URL or file upload)\n * Inspired by Summernote's ImageDialog — rewritten without jQuery\n */\n\nimport { createElement, on, trapFocus } from '../core/dom.js';\nimport { withSavedRange } from '../core/range.js';\n\nexport class ImageDialog {\n /**\n * @param {import('../Context.js').Context} context\n */\n constructor(context) {\n this.context = context;\n this.options = context.options;\n /** @type {HTMLElement|null} */\n this._dialog = null;\n this._disposers = [];\n this._savedRange = null;\n }\n\n // ---------------------------------------------------------------------------\n // Lifecycle\n // ---------------------------------------------------------------------------\n\n initialize() {\n this._dialog = this._buildDialog();\n document.body.appendChild(this._dialog);\n return this;\n }\n\n destroy() {\n this._disposers.forEach((d) => d());\n this._disposers = [];\n if (this._dialog && this._dialog.parentNode) {\n this._dialog.parentNode.removeChild(this._dialog);\n }\n this._dialog = null;\n }\n\n // ---------------------------------------------------------------------------\n // Public API\n // ---------------------------------------------------------------------------\n\n show() {\n withSavedRange((range) => {\n this._savedRange = range;\n });\n this._urlInput.value = '';\n this._altInput.value = '';\n if (this._fileInput) this._fileInput.value = '';\n this._open();\n }\n\n // ---------------------------------------------------------------------------\n // Build dialog\n // ---------------------------------------------------------------------------\n\n _buildDialog() {\n const overlay = createElement('div', {\n class: 'an-dialog-overlay',\n role: 'dialog',\n 'aria-modal': 'true',\n 'aria-label': 'Insert image',\n });\n const box = createElement('div', { class: 'an-dialog-box' });\n\n const title = createElement('h3', { class: 'an-dialog-title' });\n title.textContent = 'Insert Image';\n\n // URL tab\n const urlLabel = createElement('label', { class: 'an-label' });\n urlLabel.textContent = 'Image URL';\n const urlInput = createElement('input', {\n type: 'url',\n class: 'an-input',\n placeholder: 'https://example.com/image.png',\n autocomplete: 'off',\n });\n this._urlInput = urlInput;\n\n // Alt text\n const altLabel = createElement('label', { class: 'an-label' });\n altLabel.textContent = 'Alt Text';\n const altInput = createElement('input', {\n type: 'text',\n class: 'an-input',\n placeholder: 'Describe the image',\n autocomplete: 'off',\n });\n this._altInput = altInput;\n\n box.append(title, urlLabel, urlInput, altLabel, altInput);\n\n // Alignment\n const alignLabel = createElement('label', { class: 'an-label' });\n alignLabel.textContent = 'Alignment';\n const alignRow = createElement('div', { class: 'an-align-row' });\n const alignOptions = [\n { value: '', label: 'None' },\n { value: 'left', label: 'Left' },\n { value: 'center', label: 'Center' },\n { value: 'right', label: 'Right' },\n ];\n alignOptions.forEach(({ value, label }) => {\n const radioId = `an-align-${value || 'none'}`;\n const radio = createElement('input', { type: 'radio', name: 'an-img-align', id: radioId, value });\n if (value === '') radio.checked = true;\n const lbl = createElement('label', { for: radioId, class: 'an-align-label' });\n lbl.textContent = label;\n alignRow.append(radio, lbl);\n });\n this._alignRow = alignRow;\n box.append(alignLabel, alignRow);\n if (this.options.allowImageUpload !== false) {\n const fileLabel = createElement('label', { class: 'an-label' });\n fileLabel.textContent = 'Or upload a file';\n const fileInput = createElement('input', {\n type: 'file',\n class: 'an-input',\n accept: 'image/*',\n });\n this._fileInput = fileInput;\n const d = on(fileInput, 'change', () => this._onFileChange());\n this._disposers.push(d);\n box.append(fileLabel, fileInput);\n }\n\n // Buttons\n const btnRow = createElement('div', { class: 'an-dialog-actions' });\n const insertBtn = createElement('button', { type: 'button', class: 'an-btn an-btn-primary' });\n insertBtn.textContent = 'Insert';\n const cancelBtn = createElement('button', { type: 'button', class: 'an-btn' });\n cancelBtn.textContent = 'Cancel';\n btnRow.appendChild(insertBtn);\n btnRow.appendChild(cancelBtn);\n\n box.append(btnRow);\n overlay.appendChild(box);\n\n const d1 = on(insertBtn, 'click', () => this._onInsert());\n const d2 = on(cancelBtn, 'click', () => this._close());\n const d3 = on(overlay, 'click', (e) => { if (e.target === overlay) this._close(); });\n const d4 = on(urlInput, 'keydown', (e) => { if (e.key === 'Enter') { e.preventDefault(); this._onInsert(); } });\n const d5 = on(altInput, 'keydown', (e) => { if (e.key === 'Enter') { e.preventDefault(); this._onInsert(); } });\n this._disposers.push(d1, d2, d3, d4, d5);\n\n return overlay;\n }\n\n // ---------------------------------------------------------------------------\n // Actions\n // ---------------------------------------------------------------------------\n\n _onFileChange() {\n const file = this._fileInput && this._fileInput.files && this._fileInput.files[0];\n if (!file || !file.type.startsWith('image/')) return;\n\n // Validate file size (max 5 MB by default)\n const maxSize = (this.options.maxImageSize || 5) * 1024 * 1024;\n if (file.size > maxSize) {\n const message = `Image file is too large. Maximum allowed size is ${this.options.maxImageSize || 5} MB.`;\n console.warn('[AutumnNote] ImageDialog:', message);\n this.context.triggerEvent('imageError', { file, message });\n this._fileInput.value = '';\n return;\n }\n\n const reader = new FileReader();\n reader.onload = (e) => {\n this._urlInput.value = e.target.result;\n };\n reader.readAsDataURL(file);\n }\n\n _onInsert() {\n const src = this._urlInput.value.trim();\n const alt = this._altInput.value.trim();\n const alignRadio = this._alignRow && this._alignRow.querySelector('input[name=\"an-img-align\"]:checked');\n const align = alignRadio ? alignRadio.value : '';\n\n if (!src) {\n this._urlInput.focus();\n return;\n }\n\n if (this._savedRange) {\n this._savedRange.select();\n }\n\n this.context.invoke('editor.insertImage', src, alt, align);\n this._close();\n }\n\n _open() {\n if (this._dialog) {\n this._dialog.style.display = 'flex';\n this._removeTrap = trapFocus(this._dialog, () => this._close());\n setTimeout(() => this._urlInput && this._urlInput.focus(), 50);\n }\n }\n\n _close() {\n if (this._dialog) this._dialog.style.display = 'none';\n if (this._removeTrap) { this._removeTrap(); this._removeTrap = null; }\n this._savedRange = null;\n }\n}\n","/**\n * VideoDialog.js - Dialog for inserting videos (YouTube, Vimeo, or direct file)\n * Supports:\n * • YouTube watch URLs → <iframe> embed\n * • YouTube short URLs → <iframe> embed\n * • Vimeo URLs → <iframe> embed\n * • Direct video URLs → <video> element (.mp4 / .webm / .ogg)\n */\n\nimport { createElement, on, trapFocus } from '../core/dom.js';\nimport { withSavedRange } from '../core/range.js';\n\nexport class VideoDialog {\n /** @param {import('../Context.js').Context} context */\n constructor(context) {\n this.context = context;\n this.options = context.options;\n /** @type {HTMLElement|null} */\n this._dialog = null;\n this._disposers = [];\n this._savedRange = null;\n }\n\n // ---------------------------------------------------------------------------\n // Lifecycle\n // ---------------------------------------------------------------------------\n\n initialize() {\n this._dialog = this._buildDialog();\n document.body.appendChild(this._dialog);\n return this;\n }\n\n destroy() {\n this._disposers.forEach((d) => d());\n this._disposers = [];\n if (this._dialog && this._dialog.parentNode) {\n this._dialog.parentNode.removeChild(this._dialog);\n }\n this._dialog = null;\n }\n\n // ---------------------------------------------------------------------------\n // Public API\n // ---------------------------------------------------------------------------\n\n show() {\n withSavedRange((range) => {\n this._savedRange = range;\n });\n this._urlInput.value = '';\n this._widthInput.value = '560';\n this._hintEl.textContent = '';\n this._open();\n }\n\n // ---------------------------------------------------------------------------\n // Build dialog\n // ---------------------------------------------------------------------------\n\n _buildDialog() {\n const overlay = createElement('div', {\n class: 'an-dialog-overlay',\n role: 'dialog',\n 'aria-modal': 'true',\n 'aria-label': 'Insert video',\n });\n const box = createElement('div', { class: 'an-dialog-box' });\n\n const title = createElement('h3', { class: 'an-dialog-title' });\n title.textContent = 'Insert Video';\n\n // URL input\n const urlLabel = createElement('label', { class: 'an-label' });\n urlLabel.textContent = 'Video URL';\n const urlInput = createElement('input', {\n type: 'url',\n class: 'an-input',\n placeholder: 'YouTube, Vimeo, or direct .mp4 URL',\n autocomplete: 'off',\n });\n this._urlInput = urlInput;\n\n // Hint (detected source)\n const hintEl = createElement('p', { class: 'an-dialog-hint' });\n this._hintEl = hintEl;\n\n // Width\n const widthLabel = createElement('label', { class: 'an-label' });\n widthLabel.textContent = 'Width (px)';\n const widthInput = createElement('input', {\n type: 'number',\n class: 'an-input',\n placeholder: '560',\n min: '80',\n max: '1920',\n value: '560',\n });\n this._widthInput = widthInput;\n\n // Buttons\n const btnRow = createElement('div', { class: 'an-dialog-actions' });\n const insertBtn = createElement('button', { type: 'button', class: 'an-btn an-btn-primary' });\n insertBtn.textContent = 'Insert';\n const cancelBtn = createElement('button', { type: 'button', class: 'an-btn' });\n cancelBtn.textContent = 'Cancel';\n btnRow.appendChild(insertBtn);\n btnRow.appendChild(cancelBtn);\n\n box.append(title, urlLabel, urlInput, hintEl, widthLabel, widthInput, btnRow);\n overlay.appendChild(box);\n\n // Live URL hint\n const d0 = on(urlInput, 'input', () => {\n const info = this._parseVideoUrl(urlInput.value.trim());\n hintEl.textContent = info ? `Detected: ${info.type}` : (urlInput.value ? 'Unknown format — will try direct video embed' : '');\n });\n\n const d1 = on(insertBtn, 'click', () => this._onInsert());\n const d2 = on(cancelBtn, 'click', () => this._close());\n const d3 = on(overlay, 'click', (e) => { if (e.target === overlay) this._close(); });\n const d4 = on(urlInput, 'keydown', (e) => { if (e.key === 'Enter') { e.preventDefault(); this._onInsert(); } });\n this._disposers.push(d0, d1, d2, d3, d4);\n\n return overlay;\n }\n\n // ---------------------------------------------------------------------------\n // Actions\n // ---------------------------------------------------------------------------\n\n _onInsert() {\n const rawUrl = this._urlInput.value.trim();\n const width = Math.max(80, parseInt(this._widthInput.value, 10) || 560);\n\n if (!rawUrl) {\n this._urlInput.focus();\n return;\n }\n\n const html = this._buildEmbedHtml(rawUrl, width);\n if (!html) {\n this._hintEl.textContent = 'Invalid URL — please enter a valid video link.';\n this._urlInput.focus();\n return;\n }\n\n if (this._savedRange) this._savedRange.select();\n this.context.invoke('editor.insertVideo', html);\n this._close();\n }\n\n _open() {\n if (this._dialog) {\n this._dialog.style.display = 'flex';\n this._removeTrap = trapFocus(this._dialog, () => this._close());\n setTimeout(() => this._urlInput && this._urlInput.focus(), 50);\n }\n }\n\n _close() {\n if (this._dialog) this._dialog.style.display = 'none';\n if (this._removeTrap) { this._removeTrap(); this._removeTrap = null; }\n this._savedRange = null;\n }\n\n // ---------------------------------------------------------------------------\n // URL parsing & HTML building\n // ---------------------------------------------------------------------------\n\n /**\n * Parses a video URL and returns { type, embedUrl } or null.\n * @param {string} url\n * @returns {{ type: string, embedUrl: string }|null}\n */\n _parseVideoUrl(url) {\n if (!url) return null;\n\n // Validate — block javascript: and other dangerous protocols\n try {\n const parsed = new URL(url);\n if (/^javascript:/i.test(parsed.protocol) || /^vbscript:/i.test(parsed.protocol)) return null;\n } catch { return null; }\n\n // YouTube watch: https://www.youtube.com/watch?v=ID\n const ytWatch = url.match(/(?:youtube\\.com\\/watch\\?(?:.*&)?v=|youtube\\.com\\/embed\\/)([a-zA-Z0-9_-]{11})/);\n if (ytWatch) return { type: 'YouTube', embedUrl: `https://www.youtube.com/embed/${ytWatch[1]}` };\n\n // YouTube short: https://youtu.be/ID\n const ytShort = url.match(/youtu\\.be\\/([a-zA-Z0-9_-]{11})/);\n if (ytShort) return { type: 'YouTube', embedUrl: `https://www.youtube.com/embed/${ytShort[1]}` };\n\n // YouTube Shorts: https://www.youtube.com/shorts/ID\n const ytShorts = url.match(/youtube\\.com\\/shorts\\/([a-zA-Z0-9_-]{11})/);\n if (ytShorts) return { type: 'YouTube Shorts', embedUrl: `https://www.youtube.com/embed/${ytShorts[1]}` };\n\n // Vimeo: https://vimeo.com/ID\n const vimeo = url.match(/vimeo\\.com\\/(\\d+)/);\n if (vimeo) return { type: 'Vimeo', embedUrl: `https://player.vimeo.com/video/${vimeo[1]}` };\n\n // Direct video file\n if (/\\.(mp4|webm|ogg|ogv|mov)(#.*|\\?.*)?$/i.test(url)) {\n return { type: 'Direct video', embedUrl: url };\n }\n\n return null;\n }\n\n /**\n * Builds the HTML string to insert.\n * @param {string} url\n * @param {number} width\n * @returns {string|null}\n */\n _buildEmbedHtml(url, width) {\n const info = this._parseVideoUrl(url);\n const height = Math.round(width * 9 / 16); // 16:9\n\n if (info && (info.type === 'YouTube' || info.type === 'YouTube Shorts' || info.type === 'Vimeo')) {\n const iframeTitle = `${info.type} video player`;\n return (\n `<div class=\"an-video-wrapper\" style=\"position:relative;display:block;width:${width}px;max-width:100%\">` +\n `<iframe src=\"${info.embedUrl}\" width=\"${width}\" height=\"${height}\" ` +\n `title=\"${iframeTitle}\" ` +\n `frameborder=\"0\" allowfullscreen ` +\n `allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" ` +\n `style=\"display:block;max-width:100%\"></iframe>` +\n `<div class=\"an-video-shield\"></div>` +\n `</div>`\n );\n }\n\n if (info && info.type === 'Direct video') {\n const src = info.embedUrl.replace(/\"/g, '%22');\n return (\n `<div class=\"an-video-wrapper\" style=\"position:relative;display:block;width:${width}px;max-width:100%\">` +\n `<video src=\"${src}\" width=\"${width}\" height=\"${height}\" controls ` +\n `style=\"display:block;max-width:100%\"></video>` +\n `<div class=\"an-video-shield\"></div>` +\n `</div>`\n );\n }\n\n // Unknown URL — let the user try as a direct video\n const safeSrc = (() => {\n try {\n const p = new URL(url);\n if (/^javascript:/i.test(p.protocol) || /^vbscript:/i.test(p.protocol)) return null;\n return url;\n } catch { return null; }\n })();\n if (!safeSrc) return null;\n\n const escapedSrc = safeSrc.replace(/\"/g, '%22');\n return (\n `<div class=\"an-video-wrapper\" style=\"position:relative;display:block;width:${width}px;max-width:100%\">` +\n `<video src=\"${escapedSrc}\" width=\"${width}\" height=\"${height}\" controls ` +\n `style=\"display:block;max-width:100%\"></video>` +\n `<div class=\"an-video-shield\"></div>` +\n `</div>`\n );\n }\n}\n","// ImageResizer.js - Interactive resize handles for selected images in the editor\nimport { on } from '../core/dom.js';\n\n/**\n * Eight handle positions. 'pos' is used as CSS class suffix and\n * to determine which axis/direction is being dragged.\n *\n * Pos length 2 → corner handle → maintain aspect ratio.\n * Pos length 1 → edge handle → single-axis resize.\n */\nconst HANDLE_DEFS = [\n { pos: 'nw', cursor: 'nw-resize' },\n { pos: 'n', cursor: 'n-resize' },\n { pos: 'ne', cursor: 'ne-resize' },\n { pos: 'e', cursor: 'e-resize' },\n { pos: 'se', cursor: 'se-resize' },\n { pos: 's', cursor: 's-resize' },\n { pos: 'sw', cursor: 'sw-resize' },\n { pos: 'w', cursor: 'w-resize' },\n];\n\nexport class ImageResizer {\n /** @param {import('../Context.js').Context} context */\n constructor(context) {\n this.context = context;\n /** @type {HTMLImageElement|null} */\n this._activeImg = null;\n this._overlay = null;\n this._disposers = [];\n this._positionRaf = null;\n }\n\n initialize() {\n this._overlay = this._buildOverlay();\n const container = this.context.layoutInfo.editable.closest('.an-container') || document.body;\n container.appendChild(this._overlay);\n this._container = container;\n\n const editable = this.context.layoutInfo.editable;\n\n this._disposers.push(\n on(editable, 'click', (e) => this._onEditorClick(e)),\n // Also select on right-click so the highlight shows before the context menu\n on(editable, 'contextmenu', (e) => {\n const img = e.target.closest('img');\n if (img) this._select(img);\n }),\n on(document, 'click', (e) => this._onDocClick(e)),\n on(window, 'scroll', () => this._updateOverlayPosition(), { passive: true }),\n on(window, 'resize', () => this._updateOverlayPosition()),\n on(editable, 'scroll', () => this._updateOverlayPosition(), { passive: true }),\n );\n\n return this;\n }\n\n destroy() {\n this._disposers.forEach((d) => d());\n this._disposers = [];\n if (this._dragDisposers) {\n this._dragDisposers.forEach((d) => d());\n this._dragDisposers = null;\n }\n if (this._positionRaf) {\n cancelAnimationFrame(this._positionRaf);\n this._positionRaf = null;\n }\n this._deselect();\n if (this._overlay && this._overlay.parentNode) {\n this._overlay.parentNode.removeChild(this._overlay);\n }\n this._overlay = null;\n }\n\n // ---------------------------------------------------------------------------\n // Public API used by other modules\n // ---------------------------------------------------------------------------\n\n /** @returns {HTMLImageElement|null} */\n getActiveImage() {\n return this._activeImg;\n }\n\n /** Re-sync overlay position (call after external size changes). */\n updateOverlay() {\n this._updateOverlayPosition();\n }\n\n /** Programmatically clear the current image selection. */\n deselect() {\n this._deselect();\n }\n\n // ---------------------------------------------------------------------------\n // Internal\n // ---------------------------------------------------------------------------\n\n _buildOverlay() {\n const overlay = document.createElement('div');\n overlay.className = 'an-image-resizer';\n overlay.style.display = 'none';\n\n HANDLE_DEFS.forEach(({ pos }) => {\n const h = document.createElement('div');\n h.className = `an-resize-handle an-resize-${pos}`;\n h.dataset.handle = pos;\n // Attach handle listeners here so they're torn down in destroy() via _disposers\n this._disposers.push(\n on(h, 'mousedown', (e) => {\n e.preventDefault();\n e.stopPropagation();\n this._startResize(e, pos);\n }),\n );\n overlay.appendChild(h);\n });\n\n return overlay;\n }\n\n _onEditorClick(e) {\n const img = e.target.closest('img');\n if (img) {\n // Prevent browser from deselecting the current text selection / opening native resize\n e.preventDefault();\n this._select(img);\n }\n }\n\n _onDocClick(e) {\n if (!this._activeImg) return;\n if (e.target === this._activeImg) return;\n if (this._overlay && this._overlay.contains(e.target)) return;\n // Don't deselect while interacting with the context menu\n if (e.target.closest('.an-contextmenu')) return;\n this._deselect();\n }\n\n _select(img) {\n if (this._activeImg && this._activeImg !== img) {\n this._activeImg.classList.remove('an-image-selected');\n }\n this._activeImg = img;\n img.classList.add('an-image-selected');\n this._updateOverlayPosition();\n this._overlay.style.display = 'block';\n }\n\n _deselect() {\n if (this._activeImg) {\n this._activeImg.classList.remove('an-image-selected');\n this._activeImg = null;\n }\n if (this._overlay) this._overlay.style.display = 'none';\n }\n\n _updateOverlayPosition() {\n if (this._positionRaf) cancelAnimationFrame(this._positionRaf);\n this._positionRaf = requestAnimationFrame(() => {\n this._positionRaf = null;\n this._updateOverlayPositionNow();\n });\n }\n\n _updateOverlayPositionNow() {\n if (!this._activeImg || !this._overlay) return;\n const offsetParent = this._overlay.offsetParent || this._container;\n const containerRect = offsetParent.getBoundingClientRect();\n const rect = this._activeImg.getBoundingClientRect();\n const left = rect.left - containerRect.left + offsetParent.scrollLeft;\n const top = rect.top - containerRect.top + offsetParent.scrollTop;\n this._overlay.style.left = `${left}px`;\n this._overlay.style.top = `${top}px`;\n this._overlay.style.width = `${rect.width}px`;\n this._overlay.style.height = `${rect.height}px`;\n }\n\n _startResize(e, pos) {\n const img = this._activeImg;\n if (!img) return;\n\n const startX = e.clientX;\n const startY = e.clientY;\n const startW = img.offsetWidth || img.naturalWidth || 100;\n const startH = img.offsetHeight || img.naturalHeight || 100;\n const aspectRatio = startW / (startH || 1);\n const isCorner = pos.length === 2; // 'nw','ne','se','sw'\n\n const editable = this.context.layoutInfo.editable;\n const onMove = (me) => {\n const dx = me.clientX - startX;\n const dy = me.clientY - startY;\n const maxW = editable.clientWidth || Infinity;\n let newW = startW;\n let newH = startH;\n\n if (pos.includes('e')) newW = Math.max(20, startW + dx);\n if (pos.includes('w')) newW = Math.max(20, startW - dx);\n if (pos.includes('s')) newH = Math.max(20, startH + dy);\n if (pos.includes('n')) newH = Math.max(20, startH - dy);\n\n // Clamp to container width\n newW = Math.min(newW, maxW);\n\n if (isCorner) {\n // Lock aspect ratio: use larger absolute delta to drive both dimensions\n if (Math.abs(dx) >= Math.abs(dy)) {\n newH = Math.max(20, Math.round(newW / aspectRatio));\n } else {\n newW = Math.min(Math.max(20, Math.round(newH * aspectRatio)), maxW);\n newH = Math.max(20, Math.round(newW / aspectRatio));\n }\n }\n\n img.style.width = `${newW}px`;\n img.style.height = `${newH}px`;\n this._updateOverlayPosition();\n };\n\n const onUp = () => {\n document.removeEventListener('mousemove', onMove);\n document.removeEventListener('mouseup', onUp);\n this._dragDisposers = null;\n this.context.invoke('editor.afterCommand');\n };\n\n document.addEventListener('mousemove', onMove);\n document.addEventListener('mouseup', onUp);\n // Track these so destroy() can clean them up if called during an active drag\n this._dragDisposers = [\n () => document.removeEventListener('mousemove', onMove),\n () => document.removeEventListener('mouseup', onUp),\n ];\n }\n}\n","// VideoResizer.js - Interactive resize handles for selected videos in the editor\n// Targets .an-video-wrapper divs (containing <iframe> or <video>)\nimport { on } from '../core/dom.js';\n\nconst HANDLE_DEFS = [\n { pos: 'nw', cursor: 'nw-resize' },\n { pos: 'n', cursor: 'n-resize' },\n { pos: 'ne', cursor: 'ne-resize' },\n { pos: 'e', cursor: 'e-resize' },\n { pos: 'se', cursor: 'se-resize' },\n { pos: 's', cursor: 's-resize' },\n { pos: 'sw', cursor: 'sw-resize' },\n { pos: 'w', cursor: 'w-resize' },\n];\n\nexport class VideoResizer {\n /** @param {import('../Context.js').Context} context */\n constructor(context) {\n this.context = context;\n /** @type {HTMLElement|null} — the .an-video-wrapper div */\n this._activeWrapper = null;\n this._overlay = null;\n this._disposers = [];\n this._positionRaf = null;\n }\n\n initialize() {\n this._overlay = this._buildOverlay();\n const container = this.context.layoutInfo.editable.closest('.an-container') || document.body;\n container.appendChild(this._overlay);\n this._container = container;\n\n const editable = this.context.layoutInfo.editable;\n\n this._disposers.push(\n on(editable, 'click', (e) => this._onEditorClick(e)),\n on(editable, 'contextmenu', (e) => {\n const wrapper = this._findWrapper(e.target);\n if (wrapper) this._select(wrapper);\n }),\n on(document, 'click', (e) => this._onDocClick(e)),\n on(window, 'scroll', () => this._updateOverlayPosition(), { passive: true }),\n on(window, 'resize', () => this._updateOverlayPosition()),\n on(editable, 'scroll', () => this._updateOverlayPosition(), { passive: true }),\n );\n\n return this;\n }\n\n destroy() {\n this._disposers.forEach((d) => d());\n this._disposers = [];\n if (this._dragDisposers) {\n this._dragDisposers.forEach((d) => d());\n this._dragDisposers = null;\n }\n if (this._positionRaf) {\n cancelAnimationFrame(this._positionRaf);\n this._positionRaf = null;\n }\n this._deselect();\n if (this._overlay && this._overlay.parentNode) {\n this._overlay.parentNode.removeChild(this._overlay);\n }\n this._overlay = null;\n }\n\n // ---------------------------------------------------------------------------\n // Public API\n // ---------------------------------------------------------------------------\n\n /** @returns {HTMLElement|null} */\n getActiveWrapper() {\n return this._activeWrapper;\n }\n\n updateOverlay() {\n this._updateOverlayPosition();\n }\n\n deselect() {\n this._deselect();\n }\n\n // ---------------------------------------------------------------------------\n // Internal\n // ---------------------------------------------------------------------------\n\n /**\n * Walk up the DOM from `el` to find the nearest .an-video-wrapper,\n * or an iframe/video whose parent is .an-video-wrapper.\n * @param {EventTarget} el\n * @returns {HTMLElement|null}\n */\n _findWrapper(el) {\n if (!el || !(el instanceof Element)) return null;\n // Direct hit on wrapper\n if (el.classList && el.classList.contains('an-video-wrapper')) return el;\n // Child element (iframe, video, or nested)\n const w = el.closest('.an-video-wrapper');\n if (w) return w;\n return null;\n }\n\n _buildOverlay() {\n const overlay = document.createElement('div');\n overlay.className = 'an-video-resizer';\n overlay.style.display = 'none';\n\n HANDLE_DEFS.forEach(({ pos }) => {\n const h = document.createElement('div');\n h.className = `an-resize-handle an-resize-${pos}`;\n h.dataset.handle = pos;\n this._disposers.push(\n on(h, 'mousedown', (e) => {\n e.preventDefault();\n e.stopPropagation();\n this._startResize(e, pos);\n }),\n );\n overlay.appendChild(h);\n });\n\n return overlay;\n }\n\n _onEditorClick(e) {\n const wrapper = this._findWrapper(e.target);\n if (wrapper) {\n e.preventDefault();\n this._select(wrapper);\n }\n }\n\n _onDocClick(e) {\n if (!this._activeWrapper) return;\n if (this._activeWrapper.contains(e.target)) return;\n if (this._overlay && this._overlay.contains(e.target)) return;\n if (e.target.closest('.an-contextmenu')) return;\n this._deselect();\n }\n\n _select(wrapper) {\n if (this._activeWrapper && this._activeWrapper !== wrapper) {\n this._activeWrapper.classList.remove('an-video-selected');\n }\n this._activeWrapper = wrapper;\n wrapper.classList.add('an-video-selected');\n this._updateOverlayPosition();\n this._overlay.style.display = 'block';\n }\n\n _deselect() {\n if (this._activeWrapper) {\n this._activeWrapper.classList.remove('an-video-selected');\n this._activeWrapper = null;\n }\n if (this._overlay) this._overlay.style.display = 'none';\n }\n\n _updateOverlayPosition() {\n if (this._positionRaf) cancelAnimationFrame(this._positionRaf);\n this._positionRaf = requestAnimationFrame(() => {\n this._positionRaf = null;\n this._updateOverlayPositionNow();\n });\n }\n\n _updateOverlayPositionNow() {\n if (!this._activeWrapper || !this._overlay) return;\n const offsetParent = this._overlay.offsetParent || this._container;\n const containerRect = offsetParent.getBoundingClientRect();\n const rect = this._activeWrapper.getBoundingClientRect();\n const left = rect.left - containerRect.left + offsetParent.scrollLeft;\n const top = rect.top - containerRect.top + offsetParent.scrollTop;\n this._overlay.style.left = `${left}px`;\n this._overlay.style.top = `${top}px`;\n this._overlay.style.width = `${rect.width}px`;\n this._overlay.style.height = `${rect.height}px`;\n }\n\n _startResize(e, pos) {\n const wrapper = this._activeWrapper;\n if (!wrapper) return;\n\n const embed = wrapper.querySelector('iframe, video');\n const startX = e.clientX;\n const startY = e.clientY;\n const startW = wrapper.offsetWidth || 560;\n const startH = wrapper.offsetHeight || 315;\n const aspectRatio = startW / (startH || 1);\n const isCorner = pos.length === 2;\n\n const editable = this.context.layoutInfo.editable;\n const onMove = (me) => {\n const dx = me.clientX - startX;\n const dy = me.clientY - startY;\n const maxW = editable.clientWidth || Infinity;\n let newW = startW;\n let newH = startH;\n\n if (pos.includes('e')) newW = Math.max(80, startW + dx);\n if (pos.includes('w')) newW = Math.max(80, startW - dx);\n if (pos.includes('s')) newH = Math.max(45, startH + dy);\n if (pos.includes('n')) newH = Math.max(45, startH - dy);\n\n // Clamp to container width\n newW = Math.min(newW, maxW);\n\n if (isCorner) {\n if (Math.abs(dx) >= Math.abs(dy)) {\n newH = Math.max(45, Math.round(newW / aspectRatio));\n } else {\n newW = Math.min(Math.max(80, Math.round(newH * aspectRatio)), maxW);\n newH = Math.max(45, Math.round(newW / aspectRatio));\n }\n }\n\n // Resize both the wrapper and the inner embed element\n wrapper.style.width = `${newW}px`;\n wrapper.style.height = `${newH}px`;\n if (embed) {\n embed.width = newW;\n embed.height = newH;\n embed.style.width = `${newW}px`;\n embed.style.height = `${newH}px`;\n }\n this._updateOverlayPosition();\n };\n\n const onUp = () => {\n document.removeEventListener('mousemove', onMove);\n document.removeEventListener('mouseup', onUp);\n this._dragDisposers = null;\n this.context.invoke('editor.afterCommand');\n };\n\n document.addEventListener('mousemove', onMove);\n document.addEventListener('mouseup', onUp);\n // Track these so destroy() can clean them up if called during an active drag\n this._dragDisposers = [\n () => document.removeEventListener('mousemove', onMove),\n () => document.removeEventListener('mouseup', onUp),\n ];\n }\n}\n","// LinkTooltip.js - Hover tooltip for links inside the editor\n// Displays a small action bar with: visit link, edit link, unlink\nimport { createElement, on } from '../core/dom.js';\n\nconst ICONS = {\n open: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\"/><polyline points=\"15 3 21 3 21 9\"/><line x1=\"10\" y1=\"14\" x2=\"21\" y2=\"3\"/></svg>`,\n edit: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7\"/><path d=\"M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z\"/></svg>`,\n unlink: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M18.84 12.25l1.72-1.71h-.02a5.004 5.004 0 0 0-.12-7.07 5.006 5.006 0 0 0-6.95 0l-1.72 1.71\"/><path d=\"M5.17 11.75l-1.71 1.71a5.004 5.004 0 0 0 .12 7.07 5.006 5.006 0 0 0 6.95 0l1.71-1.71\"/><line x1=\"8\" y1=\"2\" x2=\"8\" y2=\"5\"/><line x1=\"2\" y1=\"8\" x2=\"5\" y2=\"8\"/><line x1=\"16\" y1=\"19\" x2=\"16\" y2=\"22\"/><line x1=\"19\" y1=\"16\" x2=\"22\" y2=\"16\"/></svg>`,\n copy: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\"/><path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\"/></svg>`,\n};\n\n/** Delay in ms before showing / after hiding to avoid flicker */\nconst SHOW_DELAY = 120;\nconst HIDE_DELAY = 200;\n\nexport class LinkTooltip {\n /** @param {import('../Context.js').Context} context */\n constructor(context) {\n this.context = context;\n this._el = null;\n this._activeAnchor = null;\n this._showTimer = null;\n this._hideTimer = null;\n this._disposers = [];\n }\n\n initialize() {\n this._el = this._buildTooltip();\n document.body.appendChild(this._el);\n\n const editable = this.context.layoutInfo.editable;\n\n this._disposers.push(\n // Detect when pointer enters a link\n on(editable, 'mouseover', (e) => {\n const anchor = e.target.closest('a[href]');\n if (anchor && editable.contains(anchor)) {\n this._scheduleShow(anchor);\n }\n }),\n // Detect when pointer leaves the editable area entirely\n on(editable, 'mouseout', (e) => {\n const to = e.relatedTarget;\n if (!to || (!editable.contains(to) && !this._el.contains(to))) {\n this._scheduleHide();\n }\n }),\n );\n\n return this;\n }\n\n destroy() {\n this._clearTimers();\n this._disposers.forEach((d) => d());\n this._disposers = [];\n if (this._el && this._el.parentNode) this._el.parentNode.removeChild(this._el);\n this._el = null;\n }\n\n // ---------------------------------------------------------------------------\n // Build\n // ---------------------------------------------------------------------------\n\n _buildTooltip() {\n const el = createElement('div', { class: 'an-link-tooltip', role: 'toolbar', 'aria-label': 'Link actions' });\n el.style.display = 'none';\n\n // URL preview text (truncated)\n this._urlLabel = createElement('span', { class: 'an-link-tooltip-url' });\n el.appendChild(this._urlLabel);\n\n // Separator\n el.appendChild(createElement('div', { class: 'an-link-tooltip-sep' }));\n\n // Action buttons\n this._openBtn = this._makeBtn(ICONS.open, 'Open link', () => this._openLink());\n this._copyBtn = this._makeBtn(ICONS.copy, 'Copy URL', () => this._copyLink());\n this._editBtn = this._makeBtn(ICONS.edit, 'Edit link', () => this._editLink());\n this._unlinkBtn = this._makeBtn(ICONS.unlink, 'Remove link', () => this._unlink());\n\n el.appendChild(this._openBtn);\n el.appendChild(this._copyBtn);\n el.appendChild(this._editBtn);\n el.appendChild(this._unlinkBtn);\n\n // Keep tooltip alive while hovering it\n this._disposers.push(\n on(el, 'mouseenter', () => this._clearTimers()),\n on(el, 'mouseleave', () => this._scheduleHide()),\n );\n\n return el;\n }\n\n _makeBtn(icon, title, handler) {\n const btn = createElement('button', { type: 'button', class: 'an-link-tooltip-btn', title });\n btn.innerHTML = icon;\n this._disposers.push(on(btn, 'click', (e) => { e.preventDefault(); e.stopPropagation(); handler(); }));\n return btn;\n }\n\n // ---------------------------------------------------------------------------\n // Show / Hide logic\n // ---------------------------------------------------------------------------\n\n _scheduleShow(anchor) {\n if (this._activeAnchor === anchor && this._el.style.display !== 'none') return;\n clearTimeout(this._hideTimer);\n this._hideTimer = null;\n clearTimeout(this._showTimer);\n this._showTimer = setTimeout(() => {\n this._activeAnchor = anchor;\n this._show(anchor);\n }, SHOW_DELAY);\n }\n\n _scheduleHide() {\n clearTimeout(this._showTimer);\n this._showTimer = null;\n if (this._hideTimer) return;\n this._hideTimer = setTimeout(() => {\n this._hide();\n }, HIDE_DELAY);\n }\n\n _show(anchor) {\n const url = anchor.getAttribute('href') || '';\n this._urlLabel.textContent = this._truncateUrl(url);\n this._urlLabel.title = url;\n this._el.style.display = 'flex';\n this._positionNear(anchor);\n }\n\n _hide() {\n this._el.style.display = 'none';\n this._activeAnchor = null;\n this._clearTimers();\n }\n\n _clearTimers() {\n clearTimeout(this._showTimer);\n clearTimeout(this._hideTimer);\n this._showTimer = null;\n this._hideTimer = null;\n }\n\n _positionNear(anchor) {\n const rect = anchor.getBoundingClientRect();\n const tipW = this._el.offsetWidth || 260;\n const tipH = this._el.offsetHeight || 34;\n const margin = 6;\n\n // Prefer below the link; if no room, put above\n let top = rect.bottom + margin;\n let left = rect.left;\n\n if (top + tipH > window.innerHeight - margin) {\n top = rect.top - tipH - margin;\n }\n if (left + tipW > window.innerWidth - margin) {\n left = window.innerWidth - tipW - margin;\n }\n if (left < margin) left = margin;\n\n this._el.style.top = `${top}px`;\n this._el.style.left = `${left}px`;\n }\n\n _truncateUrl(url) {\n try {\n const u = new URL(url);\n const display = u.host + (u.pathname !== '/' ? u.pathname : '');\n return display.length > 48 ? display.slice(0, 48) + '…' : display;\n } catch {\n return url.length > 48 ? url.slice(0, 48) + '…' : url;\n }\n }\n\n // ---------------------------------------------------------------------------\n // Actions\n // ---------------------------------------------------------------------------\n\n _openLink() {\n const url = this._activeAnchor && this._activeAnchor.getAttribute('href');\n if (url) window.open(url, '_blank', 'noopener,noreferrer');\n this._hide();\n }\n\n _copyLink() {\n const url = this._activeAnchor && this._activeAnchor.getAttribute('href');\n if (url) {\n navigator.clipboard.writeText(url).catch(() => {\n // Fallback for environments where clipboard API is unavailable\n const ta = document.createElement('textarea');\n ta.value = url;\n ta.style.position = 'fixed';\n ta.style.opacity = '0';\n document.body.appendChild(ta);\n ta.select();\n document.execCommand('copy');\n document.body.removeChild(ta);\n });\n }\n // Brief visual feedback \n if (this._copyBtn) {\n this._copyBtn.classList.add('an-link-tooltip-btn--copied');\n setTimeout(() => this._copyBtn && this._copyBtn.classList.remove('an-link-tooltip-btn--copied'), 1000);\n }\n }\n\n _editLink() {\n const anchor = this._activeAnchor;\n if (!anchor) return;\n this._hide();\n\n // Place cursor inside the anchor, then open the link dialog (which pre-fills from selection)\n const sel = window.getSelection();\n const range = document.createRange();\n range.selectNodeContents(anchor);\n sel.removeAllRanges();\n sel.addRange(range);\n\n this.context.invoke('linkDialog.show');\n }\n\n _unlink() {\n const anchor = this._activeAnchor;\n if (!anchor) return;\n this._hide();\n\n // Select the anchor text, then remove the link\n const sel = window.getSelection();\n const range = document.createRange();\n range.selectNode(anchor);\n sel.removeAllRanges();\n sel.addRange(range);\n\n document.execCommand('unlink');\n this.context.invoke('editor.afterCommand');\n }\n}\n","// ImageTooltip.js - Hover tooltip for images inside the editor\n// Displays a horizontal action bar below (or above) the selected image,\n// similar in appearance and interaction to LinkTooltip.\nimport { createElement, on } from '../core/dom.js';\n\nconst ICONS = {\n floatLeft: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"2\" y=\"4\" width=\"8\" height=\"8\" rx=\"1\"/><line x1=\"12\" y1=\"6\" x2=\"22\" y2=\"6\"/><line x1=\"12\" y1=\"9\" x2=\"22\" y2=\"9\"/><line x1=\"12\" y1=\"12\" x2=\"22\" y2=\"12\"/><line x1=\"2\" y1=\"16\" x2=\"22\" y2=\"16\"/><line x1=\"2\" y1=\"20\" x2=\"18\" y2=\"20\"/></svg>`,\n floatRight: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"14\" y=\"4\" width=\"8\" height=\"8\" rx=\"1\"/><line x1=\"2\" y1=\"6\" x2=\"12\" y2=\"6\"/><line x1=\"2\" y1=\"9\" x2=\"12\" y2=\"9\"/><line x1=\"2\" y1=\"12\" x2=\"12\" y2=\"12\"/><line x1=\"2\" y1=\"16\" x2=\"22\" y2=\"16\"/><line x1=\"2\" y1=\"20\" x2=\"18\" y2=\"20\"/></svg>`,\n floatNone: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"3\" width=\"8\" height=\"8\" rx=\"1\"/><line x1=\"3\" y1=\"15\" x2=\"21\" y2=\"15\"/><line x1=\"3\" y1=\"19\" x2=\"17\" y2=\"19\"/></svg>`,\n alignCenter: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"7\" y=\"4\" width=\"10\" height=\"8\" rx=\"1\"/><line x1=\"3\" y1=\"16\" x2=\"21\" y2=\"16\"/><line x1=\"6\" y1=\"20\" x2=\"18\" y2=\"20\"/></svg>`,\n originalSize:`<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"15 3 21 3 21 9\"/><polyline points=\"9 21 3 21 3 15\"/><line x1=\"21\" y1=\"3\" x2=\"14\" y2=\"10\"/><line x1=\"3\" y1=\"21\" x2=\"10\" y2=\"14\"/></svg>`,\n deleteImg: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"3 6 5 6 21 6\"/><path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2\"/></svg>`,\n caption: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"3\" width=\"18\" height=\"11\" rx=\"2\"/><line x1=\"6\" y1=\"18\" x2=\"18\" y2=\"18\"/><line x1=\"9\" y1=\"21\" x2=\"15\" y2=\"21\"/></svg>`,\n};\n\nconst SHOW_DELAY = 100;\nconst HIDE_DELAY = 180;\n\nexport class ImageTooltip {\n /** @param {import('../Context.js').Context} context */\n constructor(context) {\n this.context = context;\n this._el = null;\n this._activeImg = null;\n this._showTimer = null;\n this._hideTimer = null;\n this._disposers = [];\n }\n\n initialize() {\n this._el = this._buildTooltip();\n document.body.appendChild(this._el);\n\n const editable = this.context.layoutInfo.editable;\n\n this._disposers.push(\n on(editable, 'mouseover', (e) => {\n const img = e.target.closest('img');\n // Skip when the image is inside a link — LinkTooltip takes priority there\n if (img && editable.contains(img) && !img.closest('a[href]')) {\n this._scheduleShow(img);\n }\n }),\n on(editable, 'mouseout', (e) => {\n const to = e.relatedTarget;\n if (!to || (!editable.contains(to) && !this._el.contains(to))) {\n this._scheduleHide();\n }\n }),\n // Hide when image is deselected by clicking elsewhere\n on(document, 'click', (e) => {\n if (this._activeImg && !this._activeImg.contains(e.target) && !this._el.contains(e.target)) {\n this._hide();\n }\n }),\n );\n\n return this;\n }\n\n destroy() {\n this._clearTimers();\n this._disposers.forEach((d) => d());\n this._disposers = [];\n if (this._el && this._el.parentNode) this._el.parentNode.removeChild(this._el);\n this._el = null;\n }\n\n // ---------------------------------------------------------------------------\n // Build\n // ---------------------------------------------------------------------------\n\n _buildTooltip() {\n const el = createElement('div', {\n class: 'an-link-tooltip an-image-tooltip',\n role: 'toolbar',\n 'aria-label': 'Image actions',\n });\n el.style.display = 'none';\n\n // Label showing \"Image\"\n this._label = createElement('span', { class: 'an-link-tooltip-url' });\n this._label.textContent = 'Image';\n el.appendChild(this._label);\n\n el.appendChild(createElement('div', { class: 'an-link-tooltip-sep' }));\n\n this._floatLeftBtn = this._makeBtn(ICONS.floatLeft, 'Float Left', () => this._setFloat('left'));\n this._floatNoneBtn = this._makeBtn(ICONS.floatNone, 'No Float', () => this._setFloat(''));\n this._alignCenterBtn = this._makeBtn(ICONS.alignCenter, 'Align Center', () => this._setCenter());\n this._floatRightBtn = this._makeBtn(ICONS.floatRight, 'Float Right', () => this._setFloat('right'));\n\n el.appendChild(this._floatLeftBtn);\n el.appendChild(this._floatNoneBtn);\n el.appendChild(this._alignCenterBtn);\n el.appendChild(this._floatRightBtn);\n\n el.appendChild(createElement('div', { class: 'an-link-tooltip-sep' }));\n\n this._originalBtn = this._makeBtn(ICONS.originalSize, 'Original Size', () => this._resetSize());\n\n el.appendChild(this._originalBtn);\n\n el.appendChild(createElement('div', { class: 'an-link-tooltip-sep' }));\n\n this._captionBtn = this._makeBtn(ICONS.caption, 'Add / Edit Caption', () => this._toggleCaption());\n el.appendChild(this._captionBtn);\n\n el.appendChild(createElement('div', { class: 'an-link-tooltip-sep' }));\n\n this._deleteBtn = this._makeBtn(ICONS.deleteImg, 'Delete Image', () => this._delete(), true);\n\n el.appendChild(this._deleteBtn);\n\n // Keep tooltip alive while hovering it\n this._disposers.push(\n on(el, 'mouseenter', () => this._clearTimers()),\n on(el, 'mouseleave', () => this._scheduleHide()),\n );\n\n return el;\n }\n\n /**\n * @param {string} icon\n * @param {string} title\n * @param {Function} handler\n * @param {boolean} [isDanger]\n */\n _makeBtn(icon, title, handler, isDanger = false) {\n const btn = createElement('button', {\n type: 'button',\n class: isDanger ? 'an-link-tooltip-btn an-link-tooltip-btn--danger' : 'an-link-tooltip-btn',\n title,\n });\n btn.innerHTML = icon;\n this._disposers.push(on(btn, 'click', (e) => {\n e.preventDefault();\n e.stopPropagation();\n handler();\n }));\n return btn;\n }\n\n // ---------------------------------------------------------------------------\n // Show / Hide\n // ---------------------------------------------------------------------------\n\n _scheduleShow(img) {\n if (this._activeImg === img && this._el.style.display !== 'none') return;\n clearTimeout(this._hideTimer);\n this._hideTimer = null;\n clearTimeout(this._showTimer);\n this._showTimer = setTimeout(() => {\n this._activeImg = img;\n this._show(img);\n }, SHOW_DELAY);\n }\n\n _scheduleHide() {\n clearTimeout(this._showTimer);\n this._showTimer = null;\n if (this._hideTimer) return;\n this._hideTimer = setTimeout(() => this._hide(), HIDE_DELAY);\n }\n\n _show(img) {\n this._el.style.display = 'flex';\n this._positionNear(img);\n }\n\n _hide() {\n this._el.style.display = 'none';\n this._activeImg = null;\n this._clearTimers();\n }\n\n _clearTimers() {\n clearTimeout(this._showTimer);\n clearTimeout(this._hideTimer);\n this._showTimer = null;\n this._hideTimer = null;\n }\n\n _positionNear(img) {\n const rect = img.getBoundingClientRect();\n const tipW = this._el.offsetWidth || 220;\n const tipH = this._el.offsetHeight || 32;\n const margin = 6;\n\n let top = rect.bottom + margin;\n let left = rect.left + (rect.width - tipW) / 2;\n\n if (top + tipH > window.innerHeight - margin) top = rect.top - tipH - margin;\n if (left + tipW > window.innerWidth - margin) left = window.innerWidth - tipW - margin;\n if (left < margin) left = margin;\n\n this._el.style.top = `${top}px`;\n this._el.style.left = `${left}px`;\n }\n\n // ---------------------------------------------------------------------------\n // Actions\n // ---------------------------------------------------------------------------\n\n _setFloat(value) {\n const img = this._activeImg;\n if (!img) return;\n const target = img.closest('figure.an-figure') || img;\n target.style.float = value;\n target.style.display = '';\n target.style.marginLeft = value === 'right' ? '12px' : '';\n target.style.marginRight = value === 'left' ? '12px' : '';\n this.context.invoke('editor.afterCommand');\n this.context.invoke('imageResizer.updateOverlay');\n this._positionNear(img);\n }\n\n _setCenter() {\n const img = this._activeImg;\n if (!img) return;\n const target = img.closest('figure.an-figure') || img;\n target.style.float = '';\n target.style.display = 'block';\n target.style.marginLeft = 'auto';\n target.style.marginRight = 'auto';\n this.context.invoke('editor.afterCommand');\n this.context.invoke('imageResizer.updateOverlay');\n this._positionNear(img);\n }\n\n _resetSize() {\n const img = this._activeImg;\n if (!img) return;\n img.style.width = '';\n img.style.height = '';\n this.context.invoke('editor.afterCommand');\n this.context.invoke('imageResizer.updateOverlay');\n this._positionNear(img);\n }\n\n _delete() {\n const img = this._activeImg;\n if (!img) return;\n this._hide();\n this.context.invoke('imageResizer.deselect');\n const figure = img.closest('figure.an-figure');\n if (figure && figure.parentNode) {\n figure.parentNode.removeChild(figure);\n } else if (img.parentNode) {\n img.parentNode.removeChild(img);\n }\n this.context.invoke('editor.afterCommand');\n }\n\n _toggleCaption() {\n const img = this._activeImg;\n if (!img) return;\n\n // If already inside a figure, move focus to the figcaption\n const existing = img.closest('figure.an-figure');\n if (existing) {\n const cap = existing.querySelector('figcaption.an-figcaption');\n if (cap) {\n this._hide();\n const range = document.createRange();\n range.selectNodeContents(cap);\n const sel = window.getSelection();\n if (sel) { sel.removeAllRanges(); sel.addRange(range); }\n }\n return;\n }\n\n // Wrap image in <figure><figcaption>\n const figure = document.createElement('figure');\n figure.className = 'an-figure';\n\n // Transfer existing alignment from <img> to <figure> (C4 fix)\n if (img.style.float) {\n figure.style.float = img.style.float;\n figure.style.marginLeft = img.style.marginLeft;\n figure.style.marginRight = img.style.marginRight;\n img.style.float = '';\n img.style.marginLeft = '';\n img.style.marginRight = '';\n } else if (img.style.display === 'block' && img.style.marginLeft === 'auto') {\n figure.style.display = 'block';\n figure.style.marginLeft = 'auto';\n figure.style.marginRight = 'auto';\n img.style.display = '';\n img.style.marginLeft = '';\n img.style.marginRight = '';\n }\n const figcaption = document.createElement('figcaption');\n figcaption.className = 'an-figcaption';\n figcaption.textContent = 'Caption';\n\n img.parentNode.insertBefore(figure, img);\n figure.appendChild(img);\n figure.appendChild(figcaption);\n\n // Select caption text immediately\n const range = document.createRange();\n range.selectNodeContents(figcaption);\n const sel = window.getSelection();\n if (sel) { sel.removeAllRanges(); sel.addRange(range); }\n\n this.context.invoke('editor.afterCommand');\n // Re-sync the resize overlay: wrapping img in <figure> changes its layout position.\n this.context.invoke('imageResizer.updateOverlay');\n this._hide();\n }\n}\n","// VideoTooltip.js - Hover tooltip for video wrappers inside the editor\n// Displays a horizontal action bar below (or above) the selected video,\n// similar in appearance and interaction to LinkTooltip.\nimport { createElement, on } from '../core/dom.js';\n\nconst ICONS = {\n floatLeft: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"2\" y=\"4\" width=\"8\" height=\"8\" rx=\"1\"/><line x1=\"12\" y1=\"6\" x2=\"22\" y2=\"6\"/><line x1=\"12\" y1=\"9\" x2=\"22\" y2=\"9\"/><line x1=\"12\" y1=\"12\" x2=\"22\" y2=\"12\"/><line x1=\"2\" y1=\"16\" x2=\"22\" y2=\"16\"/><line x1=\"2\" y1=\"20\" x2=\"18\" y2=\"20\"/></svg>`,\n floatRight: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"14\" y=\"4\" width=\"8\" height=\"8\" rx=\"1\"/><line x1=\"2\" y1=\"6\" x2=\"12\" y2=\"6\"/><line x1=\"2\" y1=\"9\" x2=\"12\" y2=\"9\"/><line x1=\"2\" y1=\"12\" x2=\"12\" y2=\"12\"/><line x1=\"2\" y1=\"16\" x2=\"22\" y2=\"16\"/><line x1=\"2\" y1=\"20\" x2=\"18\" y2=\"20\"/></svg>`,\n floatNone: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"3\" width=\"8\" height=\"8\" rx=\"1\"/><line x1=\"3\" y1=\"15\" x2=\"21\" y2=\"15\"/><line x1=\"3\" y1=\"19\" x2=\"17\" y2=\"19\"/></svg>`,\n alignCenter: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"7\" y=\"4\" width=\"10\" height=\"8\" rx=\"1\"/><line x1=\"3\" y1=\"16\" x2=\"21\" y2=\"16\"/><line x1=\"6\" y1=\"20\" x2=\"18\" y2=\"20\"/></svg>`,\n originalSize:`<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"15 3 21 3 21 9\"/><polyline points=\"9 21 3 21 3 15\"/><line x1=\"21\" y1=\"3\" x2=\"14\" y2=\"10\"/><line x1=\"3\" y1=\"21\" x2=\"10\" y2=\"14\"/></svg>`,\n deleteVideo: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"3 6 5 6 21 6\"/><path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2\"/></svg>`,\n preview: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polygon points=\"5 3 19 12 5 21 5 3\"/></svg>`,\n};\n\nconst SHOW_DELAY = 100;\nconst HIDE_DELAY = 180;\n\nexport class VideoTooltip {\n /** @param {import('../Context.js').Context} context */\n constructor(context) {\n this.context = context;\n this._el = null;\n this._activeWrapper = null;\n this._showTimer = null;\n this._hideTimer = null;\n this._disposers = [];\n this._previewMode = false;\n this._previewClickOff = null;\n }\n\n initialize() {\n this._el = this._buildTooltip();\n document.body.appendChild(this._el);\n\n const editable = this.context.layoutInfo.editable;\n\n this._disposers.push(\n on(editable, 'mouseover', (e) => {\n // The shield div sits on top of iframes — we detect hover via it or the wrapper\n const wrapper = e.target.closest('.an-video-wrapper');\n if (wrapper && editable.contains(wrapper)) {\n this._scheduleShow(wrapper);\n }\n }),\n on(editable, 'mouseout', (e) => {\n const to = e.relatedTarget;\n if (!to || (!editable.contains(to) && !this._el.contains(to))) {\n this._scheduleHide();\n }\n }),\n on(document, 'click', (e) => {\n if (\n this._activeWrapper &&\n !this._activeWrapper.contains(e.target) &&\n !this._el.contains(e.target)\n ) {\n this._hide();\n }\n }),\n );\n\n return this;\n }\n\n destroy() {\n if (this._previewMode) this._exitPreview();\n this._clearTimers();\n this._disposers.forEach((d) => d());\n this._disposers = [];\n if (this._el && this._el.parentNode) this._el.parentNode.removeChild(this._el);\n this._el = null;\n }\n\n // ---------------------------------------------------------------------------\n // Build\n // ---------------------------------------------------------------------------\n\n _buildTooltip() {\n const el = createElement('div', {\n class: 'an-link-tooltip an-video-tooltip',\n role: 'toolbar',\n 'aria-label': 'Video actions',\n });\n el.style.display = 'none';\n\n // Label\n this._label = createElement('span', { class: 'an-link-tooltip-url' });\n this._label.textContent = 'Video';\n el.appendChild(this._label);\n\n el.appendChild(createElement('div', { class: 'an-link-tooltip-sep' }));\n\n this._floatLeftBtn = this._makeBtn(ICONS.floatLeft, 'Float Left', () => this._setFloat('left'));\n this._floatNoneBtn = this._makeBtn(ICONS.floatNone, 'No Float', () => this._setFloat(''));\n this._alignCenterBtn = this._makeBtn(ICONS.alignCenter, 'Align Center', () => this._setCenter());\n this._floatRightBtn = this._makeBtn(ICONS.floatRight, 'Float Right', () => this._setFloat('right'));\n\n el.appendChild(this._floatLeftBtn);\n el.appendChild(this._floatNoneBtn);\n el.appendChild(this._alignCenterBtn);\n el.appendChild(this._floatRightBtn);\n\n el.appendChild(createElement('div', { class: 'an-link-tooltip-sep' }));\n\n this._originalBtn = this._makeBtn(ICONS.originalSize, 'Original Size', () => this._resetSize());\n\n el.appendChild(this._originalBtn);\n\n el.appendChild(createElement('div', { class: 'an-link-tooltip-sep' }));\n\n this._previewBtn = this._makeBtn(ICONS.preview, 'Preview Video', () => this._togglePreview());\n el.appendChild(this._previewBtn);\n\n el.appendChild(createElement('div', { class: 'an-link-tooltip-sep' }));\n\n this._deleteBtn = this._makeBtn(ICONS.deleteVideo, 'Delete Video', () => this._delete(), true);\n\n el.appendChild(this._deleteBtn);\n\n // Keep tooltip alive while hovering it\n this._disposers.push(\n on(el, 'mouseenter', () => this._clearTimers()),\n on(el, 'mouseleave', () => this._scheduleHide()),\n );\n\n return el;\n }\n\n /**\n * @param {string} icon\n * @param {string} title\n * @param {Function} handler\n * @param {boolean} [isDanger]\n */\n _makeBtn(icon, title, handler, isDanger = false) {\n const btn = createElement('button', {\n type: 'button',\n class: isDanger ? 'an-link-tooltip-btn an-link-tooltip-btn--danger' : 'an-link-tooltip-btn',\n title,\n });\n btn.innerHTML = icon;\n this._disposers.push(on(btn, 'click', (e) => {\n e.preventDefault();\n e.stopPropagation();\n handler();\n }));\n return btn;\n }\n\n // ---------------------------------------------------------------------------\n // Show / Hide\n // ---------------------------------------------------------------------------\n\n _scheduleShow(wrapper) {\n if (this._activeWrapper === wrapper && this._el.style.display !== 'none') return;\n clearTimeout(this._hideTimer);\n this._hideTimer = null;\n clearTimeout(this._showTimer);\n this._showTimer = setTimeout(() => {\n this._activeWrapper = wrapper;\n this._show(wrapper);\n }, SHOW_DELAY);\n }\n\n _scheduleHide() {\n // Keep tooltip alive while preview mode is active\n if (this._previewMode) return;\n clearTimeout(this._showTimer);\n this._showTimer = null;\n if (this._hideTimer) return;\n this._hideTimer = setTimeout(() => this._hide(), HIDE_DELAY);\n }\n\n _show(wrapper) {\n this._el.style.display = 'flex';\n this._positionNear(wrapper);\n }\n\n _hide() {\n if (this._previewMode) this._exitPreview();\n this._el.style.display = 'none';\n this._activeWrapper = null;\n this._clearTimers();\n }\n\n _clearTimers() {\n clearTimeout(this._showTimer);\n clearTimeout(this._hideTimer);\n this._showTimer = null;\n this._hideTimer = null;\n }\n\n _positionNear(wrapper) {\n const rect = wrapper.getBoundingClientRect();\n const tipW = this._el.offsetWidth || 220;\n const tipH = this._el.offsetHeight || 32;\n const margin = 6;\n\n let top = rect.bottom + margin;\n let left = rect.left + (rect.width - tipW) / 2;\n\n if (top + tipH > window.innerHeight - margin) top = rect.top - tipH - margin;\n if (left + tipW > window.innerWidth - margin) left = window.innerWidth - tipW - margin;\n if (left < margin) left = margin;\n\n this._el.style.top = `${top}px`;\n this._el.style.left = `${left}px`;\n }\n\n // ---------------------------------------------------------------------------\n // Actions\n // ---------------------------------------------------------------------------\n\n _setFloat(value) {\n const wrapper = this._activeWrapper;\n if (!wrapper) return;\n wrapper.style.float = value;\n wrapper.style.display = value ? 'inline-block' : '';\n wrapper.style.marginLeft = value === 'right' ? '12px' : '';\n wrapper.style.marginRight = value === 'left' ? '12px' : '';\n this.context.invoke('editor.afterCommand');\n this.context.invoke('videoResizer.updateOverlay');\n this._positionNear(wrapper);\n }\n\n _setCenter() {\n const wrapper = this._activeWrapper;\n if (!wrapper) return;\n wrapper.style.float = '';\n wrapper.style.display = 'block';\n wrapper.style.marginLeft = 'auto';\n wrapper.style.marginRight = 'auto';\n this.context.invoke('editor.afterCommand');\n this.context.invoke('videoResizer.updateOverlay');\n this._positionNear(wrapper);\n }\n\n _resetSize() {\n const wrapper = this._activeWrapper;\n if (!wrapper) return;\n const embed = wrapper.querySelector('iframe, video');\n wrapper.style.width = '';\n wrapper.style.height = '';\n if (embed) {\n embed.removeAttribute('width');\n embed.removeAttribute('height');\n embed.style.width = '';\n embed.style.height = '';\n }\n this.context.invoke('editor.afterCommand');\n this.context.invoke('videoResizer.updateOverlay');\n this._positionNear(wrapper);\n }\n\n _delete() {\n const wrapper = this._activeWrapper;\n if (!wrapper) return;\n this._hide();\n this.context.invoke('videoResizer.deselect');\n if (wrapper.parentNode) wrapper.parentNode.removeChild(wrapper);\n this.context.invoke('editor.afterCommand');\n }\n\n // ---------------------------------------------------------------------------\n // Preview mode — temporarily disables the shield so the video is interactive\n // ---------------------------------------------------------------------------\n\n _togglePreview() {\n if (this._previewMode) {\n this._exitPreview();\n } else {\n this._enterPreview();\n }\n }\n\n _enterPreview() {\n const wrapper = this._activeWrapper;\n if (!wrapper) return;\n this._previewMode = true;\n\n // Hide the shield so the iframe / video receives pointer events directly\n const shield = wrapper.querySelector('.an-video-shield');\n if (shield) shield.style.display = 'none';\n\n // Hide the resize overlay — it would block interaction with the embed\n this.context.invoke('videoResizer.deselect');\n\n // Visual feedback: button turns primary-coloured\n this._previewBtn.classList.add('an-link-tooltip-btn--copied');\n this._previewBtn.title = 'Exit Preview';\n\n // Exit preview on mousedown outside the wrapper.\n // Using 'mousedown' (not 'click') so clicks inside an iframe\n // — which never bubble to the outer document — don't accidentally\n // leave preview mode stuck. For <video> elements, mousedown on the\n // video is inside the wrapper so contains() returns true → no exit.\n this._previewClickOff = (e) => {\n if (!wrapper.contains(e.target) && !this._el.contains(e.target)) {\n this._exitPreview();\n }\n };\n document.addEventListener('mousedown', this._previewClickOff, true);\n }\n\n _exitPreview() {\n this._previewMode = false;\n\n const wrapper = this._activeWrapper;\n if (wrapper) {\n // Restore the shield\n const shield = wrapper.querySelector('.an-video-shield');\n if (shield) shield.style.display = '';\n }\n\n // Reset button appearance\n this._previewBtn.classList.remove('an-link-tooltip-btn--copied');\n this._previewBtn.title = 'Preview Video';\n\n if (this._previewClickOff) {\n document.removeEventListener('mousedown', this._previewClickOff, true);\n this._previewClickOff = null;\n }\n }\n}\n","// TableTooltip.js - Hover tooltip for tables inside the editor\n// Shows a horizontal action bar above (or below) the hovered table,\n// similar in appearance and interaction to ImageTooltip / VideoTooltip.\nimport { createElement, on } from '../core/dom.js';\n\nconst SHOW_DELAY = 120;\nconst HIDE_DELAY = 200;\n\n// ---------------------------------------------------------------------------\n// Table helpers — visual column index (accounts for colspan)\n// ---------------------------------------------------------------------------\n\n/**\n * Returns the visual (logical) column index of a cell, taking colspan into\n * account for all preceding cells in the same row.\n * @param {HTMLTableCellElement} cell\n * @returns {number} 0-based visual column index, or -1 on failure\n */\nfunction getVisualColIndex(cell) {\n const row = cell.closest('tr');\n if (!row) return -1;\n let visualIdx = 0;\n for (const c of row.cells) {\n if (c === cell) return visualIdx;\n visualIdx += c.colSpan || 1;\n }\n return -1;\n}\n\n/**\n * Finds the first cell in a row whose visual start column equals visualIdx.\n * Returns null if no exact match (e.g. the column is spanned by a merged cell).\n * @param {HTMLTableRowElement} row\n * @param {number} visualIdx\n * @returns {HTMLTableCellElement|null}\n */\nfunction getCellAtVisualCol(row, visualIdx) {\n let vIdx = 0;\n for (const c of row.cells) {\n if (vIdx === visualIdx) return c;\n if (vIdx > visualIdx) break;\n vIdx += c.colSpan || 1;\n }\n return null;\n}\n\n/**\n * Finds the first cell whose visual range ends after visualIdx\n * (used for inserting a new column to the right of visualIdx).\n * @param {HTMLTableRowElement} row\n * @param {number} visualIdx\n * @returns {HTMLTableCellElement|null} reference cell for insertBefore, or null = append\n */\nfunction getCellAfterVisualCol(row, visualIdx) {\n let vIdx = 0;\n for (const c of row.cells) {\n vIdx += c.colSpan || 1;\n if (vIdx > visualIdx) {\n // next cell after the one that starts at / spans visualIdx\n const next = c.nextElementSibling;\n return (next && next.tagName === 'TD' || next && next.tagName === 'TH') ? next : null;\n }\n }\n return null;\n}\n\nconst ICONS = {\n rowAbove: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"1\"/><line x1=\"3\" y1=\"12\" x2=\"21\" y2=\"12\"/><path d=\"M12 3v7\"/><path d=\"M9 7l3-4 3 4\"/></svg>`,\n rowBelow: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"1\"/><line x1=\"3\" y1=\"12\" x2=\"21\" y2=\"12\"/><path d=\"M12 12v7\"/><path d=\"M9 17l3 4 3-4\"/></svg>`,\n deleteRow: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"1\"/><line x1=\"3\" y1=\"12\" x2=\"21\" y2=\"12\"/><line x1=\"15\" y1=\"15\" x2=\"21\" y2=\"21\"/><line x1=\"21\" y1=\"15\" x2=\"15\" y2=\"21\"/></svg>`,\n colLeft: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"1\"/><line x1=\"12\" y1=\"3\" x2=\"12\" y2=\"21\"/><path d=\"M3 12h7\"/><path d=\"M7 8l-4 4 4 4\"/></svg>`,\n colRight: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"1\"/><line x1=\"12\" y1=\"3\" x2=\"12\" y2=\"21\"/><path d=\"M12 12h9\"/><path d=\"M17 8l4 4-4 4\"/></svg>`,\n deleteCol: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"1\"/><line x1=\"12\" y1=\"3\" x2=\"12\" y2=\"21\"/><line x1=\"15\" y1=\"6\" x2=\"21\" y2=\"12\"/><line x1=\"21\" y1=\"6\" x2=\"15\" y2=\"12\"/></svg>`,\n mergeCells: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"2\" y=\"7\" width=\"8\" height=\"10\" rx=\"1\"/><rect x=\"14\" y=\"7\" width=\"8\" height=\"10\" rx=\"1\"/><path d=\"M10 12h4\"/><path d=\"M12 10l2 2-2 2\"/></svg>`,\n colWidth: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"7\" y1=\"4\" x2=\"7\" y2=\"20\"/><line x1=\"17\" y1=\"4\" x2=\"17\" y2=\"20\"/><line x1=\"7\" y1=\"12\" x2=\"17\" y2=\"12\"/><path d=\"M10 9l-3 3 3 3\"/><path d=\"M14 9l3 3-3 3\"/></svg>`,\n rowHeight: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"4\" y1=\"7\" x2=\"20\" y2=\"7\"/><line x1=\"4\" y1=\"17\" x2=\"20\" y2=\"17\"/><line x1=\"12\" y1=\"7\" x2=\"12\" y2=\"17\"/><path d=\"M9 10l3-3 3 3\"/><path d=\"M9 14l3 3 3-3\"/></svg>`,\n deleteTable: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"1\"/><line x1=\"3\" y1=\"9\" x2=\"21\" y2=\"9\"/><line x1=\"3\" y1=\"15\" x2=\"21\" y2=\"15\"/><line x1=\"9\" y1=\"3\" x2=\"9\" y2=\"21\"/><line x1=\"15\" y1=\"3\" x2=\"15\" y2=\"21\"/><line x1=\"16\" y1=\"16\" x2=\"22\" y2=\"22\" stroke=\"#ef4444\"/><line x1=\"22\" y1=\"16\" x2=\"16\" y2=\"22\" stroke=\"#ef4444\"/></svg>`,\n};\n\nexport class TableTooltip {\n /** @param {import('../Context.js').Context} context */\n constructor(context) {\n this.context = context;\n this._el = null;\n this._activeTable = null;\n this._activeCell = null; // last hovered td/th\n this._showTimer = null;\n this._hideTimer = null;\n this._disposers = [];\n this._sizePopover = null;\n this._sizeApply = null;\n this._sizeTitleEl = null;\n this._sizeInputEl = null;\n }\n\n initialize() {\n this._el = this._buildTooltip();\n document.body.appendChild(this._el);\n\n this._sizePopover = this._buildSizePopover();\n document.body.appendChild(this._sizePopover);\n\n const editable = this.context.layoutInfo.editable;\n\n this._disposers.push(\n on(editable, 'mouseover', (e) => {\n const table = e.target.closest('table');\n if (table && editable.contains(table)) {\n const cell = e.target.closest('td, th');\n if (cell) this._activeCell = cell;\n this._scheduleShow(table);\n }\n }),\n on(editable, 'mouseout', (e) => {\n const to = e.relatedTarget;\n if (!to || (\n !editable.contains(to) &&\n !this._el.contains(to) &&\n !(this._sizePopover && this._sizePopover.contains(to))\n )) {\n this._scheduleHide();\n }\n }),\n on(document, 'click', (e) => {\n if (this._activeTable &&\n !this._activeTable.contains(e.target) &&\n !this._el.contains(e.target) &&\n !(this._sizePopover && this._sizePopover.contains(e.target))) {\n this._hide();\n }\n }),\n );\n\n this._initResize();\n return this;\n }\n\n // ---------------------------------------------------------------------------\n // Column & row drag-resize\n // ---------------------------------------------------------------------------\n\n _initResize() {\n const editable = this.context.layoutInfo.editable;\n const HIT = 6; // px proximity threshold\n\n // Shared hover state\n let _nearCell = null;\n let _nearEdge = null; // 'col' | 'row' | null\n\n // Active drag state\n let _resizing = false;\n let _edge = null; // 'col' | 'row'\n let _startX = 0;\n let _startY = 0;\n let _startW = 0;\n let _startH = 0;\n let _colIdx = -1;\n let _row = null;\n let _table = null;\n\n const clearHover = () => {\n if (_nearCell) { _nearCell.style.cursor = ''; _nearCell = null; }\n _nearEdge = null;\n };\n\n const onEditorMove = (e) => {\n if (_resizing) return;\n const cell = e.target.closest('td, th');\n if (!cell || !editable.contains(cell)) { clearHover(); return; }\n if (_nearCell && _nearCell !== cell) {\n _nearCell.style.cursor = '';\n }\n const rect = cell.getBoundingClientRect();\n const onRight = Math.abs(e.clientX - rect.right) < HIT;\n const onBottom = Math.abs(e.clientY - rect.bottom) < HIT;\n if (onRight && onBottom) {\n // Corner — prefer col-resize\n cell.style.cursor = 'col-resize';\n _nearCell = cell; _nearEdge = 'col';\n } else if (onRight) {\n cell.style.cursor = 'col-resize';\n _nearCell = cell; _nearEdge = 'col';\n } else if (onBottom) {\n cell.style.cursor = 'row-resize';\n _nearCell = cell; _nearEdge = 'row';\n } else {\n clearHover();\n }\n };\n\n const onEditorDown = (e) => {\n if (!_nearCell || !_nearEdge) return;\n _resizing = true;\n _edge = _nearEdge;\n _startX = e.clientX;\n _startY = e.clientY;\n _table = _nearCell.closest('table');\n if (_edge === 'col') {\n _startW = _nearCell.offsetWidth;\n _colIdx = getVisualColIndex(_nearCell);\n document.body.style.cursor = 'col-resize';\n } else {\n _row = _nearCell.closest('tr');\n _startH = _row ? _row.offsetHeight : 40;\n document.body.style.cursor = 'row-resize';\n }\n document.body.style.userSelect = 'none';\n e.preventDefault();\n e.stopPropagation();\n };\n\n const onDocMove = (e) => {\n if (!_resizing) return;\n if (_edge === 'col') {\n const newW = Math.max(30, _startW + (e.clientX - _startX));\n if (_table && _colIdx >= 0) {\n Array.from(_table.querySelectorAll('tr')).forEach((r) => {\n const c = getCellAtVisualCol(r, _colIdx);\n if (c) { c.style.width = `${newW}px`; c.style.minWidth = `${newW}px`; }\n });\n }\n } else {\n const newH = Math.max(20, _startH + (e.clientY - _startY));\n if (_row) {\n Array.from(_row.cells).forEach((c) => {\n c.style.height = `${newH}px`;\n c.style.minHeight = `${newH}px`;\n });\n }\n }\n };\n\n const onDocUp = () => {\n if (!_resizing) return;\n _resizing = false;\n document.body.style.userSelect = '';\n document.body.style.cursor = '';\n _edge = null;\n _table = null;\n _row = null;\n _colIdx = -1;\n this.context.invoke('editor.afterCommand');\n };\n\n this._disposers.push(\n on(editable, 'mousemove', onEditorMove),\n on(editable, 'mousedown', onEditorDown),\n on(document, 'mousemove', onDocMove),\n on(document, 'mouseup', onDocUp),\n );\n }\n\n destroy() {\n this._clearTimers();\n this._disposers.forEach((d) => d());\n this._disposers = [];\n if (this._el && this._el.parentNode) this._el.parentNode.removeChild(this._el);\n this._el = null;\n if (this._sizePopover && this._sizePopover.parentNode) {\n this._sizePopover.parentNode.removeChild(this._sizePopover);\n }\n this._sizePopover = null;\n }\n\n // ---------------------------------------------------------------------------\n // Build tooltip bar\n // ---------------------------------------------------------------------------\n\n _buildTooltip() {\n const el = createElement('div', {\n class: 'an-link-tooltip an-table-tooltip',\n role: 'toolbar',\n 'aria-label': 'Table actions',\n });\n el.style.display = 'none';\n\n // Label\n this._label = createElement('span', { class: 'an-link-tooltip-url' });\n this._label.textContent = 'Table';\n el.appendChild(this._label);\n\n el.appendChild(this._sep());\n\n // Row operations\n el.appendChild(this._makeBtn(ICONS.rowAbove, 'Add Row Above', () => this._addRow('above')));\n el.appendChild(this._makeBtn(ICONS.rowBelow, 'Add Row Below', () => this._addRow('below')));\n el.appendChild(this._makeBtn(ICONS.deleteRow, 'Delete Row', () => this._deleteRow()));\n\n el.appendChild(this._sep());\n\n // Column operations\n el.appendChild(this._makeBtn(ICONS.colLeft, 'Add Column Left', () => this._addColumn('left')));\n el.appendChild(this._makeBtn(ICONS.colRight, 'Add Column Right', () => this._addColumn('right')));\n el.appendChild(this._makeBtn(ICONS.deleteCol, 'Delete Column', () => this._deleteColumn()));\n\n el.appendChild(this._sep());\n\n // Merge cells\n el.appendChild(this._makeBtn(ICONS.mergeCells, 'Merge Cells', () => this._mergeCells()));\n\n el.appendChild(this._sep());\n\n // Resize\n el.appendChild(this._makeBtn(ICONS.colWidth, 'Column Width', () => this._openSizePopover('col')));\n el.appendChild(this._makeBtn(ICONS.rowHeight, 'Row Height', () => this._openSizePopover('row')));\n\n el.appendChild(this._sep());\n\n // Delete table (danger)\n el.appendChild(this._makeBtn(ICONS.deleteTable, 'Delete Table', () => this._deleteTable(), true));\n\n // Keep tooltip alive while hovering.\n // Don't schedule hide on mouseleave when the size popover is open —\n // the user is moving the mouse toward it.\n this._disposers.push(\n on(el, 'mouseenter', () => this._clearTimers()),\n on(el, 'mouseleave', () => {\n if (this._sizePopover && this._sizePopover.style.display !== 'none') return;\n this._scheduleHide();\n }),\n );\n\n return el;\n }\n\n _sep() {\n return createElement('div', { class: 'an-link-tooltip-sep' });\n }\n\n /**\n * @param {string} icon\n * @param {string} title\n * @param {Function} handler\n * @param {boolean} [isDanger]\n */\n _makeBtn(icon, title, handler, isDanger = false) {\n const btn = createElement('button', {\n type: 'button',\n class: isDanger\n ? 'an-link-tooltip-btn an-link-tooltip-btn--danger'\n : 'an-link-tooltip-btn',\n title,\n });\n btn.innerHTML = icon;\n this._disposers.push(on(btn, 'click', (e) => {\n e.preventDefault();\n e.stopPropagation();\n handler();\n }));\n return btn;\n }\n\n // ---------------------------------------------------------------------------\n // Show / Hide\n // ---------------------------------------------------------------------------\n\n _scheduleShow(table) {\n if (this._activeTable === table && this._el.style.display !== 'none') return;\n clearTimeout(this._hideTimer);\n this._hideTimer = null;\n clearTimeout(this._showTimer);\n this._showTimer = setTimeout(() => {\n this._activeTable = table;\n this._show();\n }, SHOW_DELAY);\n }\n\n _scheduleHide() {\n clearTimeout(this._showTimer);\n this._showTimer = null;\n if (this._hideTimer) return;\n this._hideTimer = setTimeout(() => this._hide(), HIDE_DELAY);\n }\n\n _show() {\n if (!this._activeTable) return;\n this._el.style.display = 'flex';\n this._positionNear(this._activeTable);\n }\n\n _hide() {\n this._el.style.display = 'none';\n this._activeTable = null;\n this._activeCell = null;\n this._clearTimers();\n this._hideSizePopover();\n }\n\n _clearTimers() {\n clearTimeout(this._showTimer);\n clearTimeout(this._hideTimer);\n this._showTimer = null;\n this._hideTimer = null;\n }\n\n _positionNear(table) {\n if (!table) return;\n const rect = table.getBoundingClientRect();\n const tipW = this._el.offsetWidth || 400;\n const tipH = this._el.offsetHeight || 30;\n const margin = 6;\n\n // Center horizontally over the table; prefer above it\n let left = rect.left + (rect.width - tipW) / 2;\n let top = rect.top - tipH - margin;\n\n if (top < margin) top = rect.bottom + margin;\n if (left + tipW > window.innerWidth - margin) left = window.innerWidth - tipW - margin;\n if (left < margin) left = margin;\n\n this._el.style.left = `${left}px`;\n this._el.style.top = `${top}px`;\n }\n\n // ---------------------------------------------------------------------------\n // Helper: get active cell (fallback to first td/th in table)\n // ---------------------------------------------------------------------------\n\n _getCell() {\n // Prefer the cell under the current text cursor (most intuitive for operations)\n const sel = window.getSelection();\n if (sel && sel.rangeCount) {\n let container = sel.getRangeAt(0).commonAncestorContainer;\n if (container.nodeType === 3) container = container.parentElement;\n const cellFromSel = container && container.closest && container.closest('td, th');\n if (cellFromSel && this._activeTable && this._activeTable.contains(cellFromSel)) {\n return cellFromSel;\n }\n }\n return this._activeCell\n || (this._activeTable && this._activeTable.querySelector('td, th'));\n }\n\n // ---------------------------------------------------------------------------\n // Table operations\n // ---------------------------------------------------------------------------\n\n _addRow(position) {\n const cell = this._getCell();\n if (!cell) return;\n const row = cell.closest('tr');\n if (!row) return;\n const colCount = Array.from(row.cells).reduce((sum, c) => sum + (c.colSpan || 1), 0);\n const newRow = document.createElement('tr');\n const refCells = Array.from(row.cells);\n for (let i = 0; i < colCount; i++) {\n const td = createElement('td', {}, ['\\u00a0']);\n const ref = refCells[i];\n if (ref && ref.style.width) td.style.width = ref.style.width;\n if (ref && ref.style.minWidth) td.style.minWidth = ref.style.minWidth;\n newRow.appendChild(td);\n }\n if (position === 'above') row.parentElement?.insertBefore(newRow, row);\n else row.insertAdjacentElement('afterend', newRow);\n this._positionNear(this._activeTable);\n this.context.invoke('editor.afterCommand');\n }\n\n _addColumn(position) {\n const cell = this._getCell();\n if (!cell) return;\n const table = cell.closest('table');\n if (!table) return;\n const visualColIdx = getVisualColIndex(cell);\n Array.from(table.querySelectorAll('tr')).forEach((r) => {\n const isHeader = r.closest('thead') !== null;\n const newCell = createElement(isHeader ? 'th' : 'td', {}, ['\\u00a0']);\n if (position === 'left') {\n const ref = getCellAtVisualCol(r, visualColIdx);\n r.insertBefore(newCell, ref);\n } else {\n const ref = getCellAfterVisualCol(r, visualColIdx);\n r.insertBefore(newCell, ref);\n }\n });\n this._positionNear(this._activeTable);\n this.context.invoke('editor.afterCommand');\n }\n\n _deleteRow() {\n const cell = this._getCell();\n if (!cell) return;\n const row = cell.closest('tr');\n const table = cell.closest('table');\n if (!row || !table) return;\n // Guard: do not delete the last body row (thead rows are not counted)\n const tbody = table.querySelector('tbody');\n const bodyRows = tbody ? tbody.querySelectorAll('tr').length : table.querySelectorAll('tr').length;\n if (bodyRows <= 1 && row.closest('tbody')) return;\n this._activeCell = null;\n row.parentElement?.removeChild(row);\n this._positionNear(this._activeTable);\n this.context.invoke('editor.afterCommand');\n }\n\n _deleteColumn() {\n const cell = this._getCell();\n if (!cell) return;\n const table = cell.closest('table');\n if (!table) return;\n const row = cell.closest('tr');\n if (row && row.cells.length <= 1) return;\n const visualColIdx = getVisualColIndex(cell);\n this._activeCell = null;\n Array.from(table.querySelectorAll('tr')).forEach((r) => {\n const c = getCellAtVisualCol(r, visualColIdx);\n if (c) r.removeChild(c);\n });\n this._positionNear(this._activeTable);\n this.context.invoke('editor.afterCommand');\n }\n\n _mergeCells() {\n const cell = this._getCell();\n if (!cell) return;\n const sel = window.getSelection();\n if (!sel || sel.rangeCount === 0) return;\n const range = sel.getRangeAt(0);\n const table = cell.closest('table');\n if (!table) return;\n\n // Collect all cells (in any row) that intersect the selection\n const allCells = Array.from(table.querySelectorAll('td, th'));\n const selected = allCells.filter((c) => {\n try { return range.intersectsNode(c); } catch { return false; }\n });\n if (selected.length < 2) return;\n\n // Determine if all selected cells are in the same row (horizontal merge)\n const rows = [...new Set(selected.map((c) => c.closest('tr')))];\n if (rows.length === 1) {\n // Horizontal merge within a single row\n const row = rows[0];\n const rowSelected = Array.from(row.cells).filter((c) => selected.includes(c));\n if (rowSelected.length < 2) return;\n const first = rowSelected[0];\n first.colSpan = rowSelected.reduce((sum, c) => sum + (c.colSpan || 1), 0);\n first.innerHTML = rowSelected.map((c) => c.innerHTML).join('');\n rowSelected.slice(1).forEach((c) => row.removeChild(c));\n } else {\n // Vertical merge across rows — merge into first selected cell (rowspan)\n const visualCols = [...new Set(selected.map((c) => getVisualColIndex(c)))];\n if (visualCols.length !== 1) return; // only support single-column vertical merge\n const first = selected[0];\n first.rowSpan = selected.reduce((sum, c) => sum + (c.rowSpan || 1), 0);\n first.innerHTML = selected.map((c) => c.innerHTML).join('');\n selected.slice(1).forEach((c) => {\n if (c.closest('tr')) c.closest('tr').removeChild(c);\n });\n }\n this.context.invoke('editor.afterCommand');\n }\n\n _deleteTable() {\n const table = this._activeTable;\n if (!table) return;\n this._hide();\n if (table.parentNode) table.parentNode.removeChild(table);\n this.context.invoke('editor.afterCommand');\n }\n\n // ---------------------------------------------------------------------------\n // Size popover (column width / row height)\n // ---------------------------------------------------------------------------\n\n _buildSizePopover() {\n const popover = createElement('div', { class: 'an-size-popover' });\n popover.style.display = 'none';\n\n const titleEl = createElement('div', { class: 'an-size-popover-title' });\n const body = createElement('div', { class: 'an-size-popover-body' });\n const inputEl = createElement('input', {\n type: 'number', class: 'an-size-input', min: '1', max: '2000', step: '1',\n });\n const unitEl = createElement('span', { class: 'an-size-unit' }, ['px']);\n body.appendChild(inputEl);\n body.appendChild(unitEl);\n\n const actionsEl = createElement('div', { class: 'an-size-popover-actions' });\n const cancelBtn = createElement('button', { type: 'button', class: 'an-btn' });\n cancelBtn.textContent = 'Cancel';\n const applyBtn = createElement('button', { type: 'button', class: 'an-btn an-btn-primary' });\n applyBtn.textContent = 'Apply';\n actionsEl.appendChild(cancelBtn);\n actionsEl.appendChild(applyBtn);\n\n popover.appendChild(titleEl);\n popover.appendChild(body);\n popover.appendChild(actionsEl);\n\n this._sizeTitleEl = titleEl;\n this._sizeInputEl = inputEl;\n this._sizeApply = null;\n\n const d1 = on(applyBtn, 'click', () => {\n const val = parseInt(this._sizeInputEl.value, 10);\n if (val > 0 && typeof this._sizeApply === 'function') this._sizeApply(val);\n this._hideSizePopover();\n });\n const d2 = on(cancelBtn, 'click', () => this._hideSizePopover());\n const d3 = on(inputEl, 'keydown', (e) => {\n if (e.key === 'Enter') { e.preventDefault(); applyBtn.click(); }\n if (e.key === 'Escape') this._hideSizePopover();\n });\n const d4 = on(document, 'click', (e) => {\n if (this._sizePopover &&\n this._sizePopover.style.display !== 'none' &&\n !this._sizePopover.contains(e.target) &&\n !this._el.contains(e.target)) {\n this._hideSizePopover();\n }\n });\n // Keep the tooltip/popover alive while the mouse is over the popover.\n const d5 = on(popover, 'mouseenter', () => this._clearTimers());\n const d6 = on(popover, 'mouseleave', () => this._scheduleHide());\n this._disposers.push(d1, d2, d3, d4, d5, d6);\n return popover;\n }\n\n _openSizePopover(type) {\n const cell = this._getCell();\n if (!cell || !this._sizePopover) return;\n const isCol = type === 'col';\n this._sizeTitleEl.textContent = isCol ? 'Column Width (px)' : 'Row Height (px)';\n this._sizeInputEl.value = isCol\n ? (cell.offsetWidth || 120)\n : (cell.closest('tr') ? (cell.closest('tr').offsetHeight || 40) : 40);\n\n this._sizeApply = (val) => {\n if (isCol) {\n const table = cell.closest('table');\n const visualColIdx = getVisualColIndex(cell);\n Array.from(table.querySelectorAll('tr')).forEach((r) => {\n const c = getCellAtVisualCol(r, visualColIdx);\n if (c) { c.style.width = `${val}px`; c.style.minWidth = `${val}px`; }\n });\n } else {\n const row = cell.closest('tr');\n if (row) Array.from(row.cells).forEach((c) => { c.style.height = `${val}px`; c.style.minHeight = `${val}px`; });\n }\n this.context.invoke('editor.afterCommand');\n };\n\n this._sizePopover.style.display = 'block';\n requestAnimationFrame(() => {\n if (!this._sizePopover || !this._el) return;\n const tipRect = this._el.getBoundingClientRect();\n const pw = this._sizePopover.offsetWidth || 220;\n const ph = this._sizePopover.offsetHeight || 110;\n let left = tipRect.left;\n let top = tipRect.bottom + 6;\n if (left + pw > window.innerWidth - 8) left = window.innerWidth - pw - 8;\n if (top + ph > window.innerHeight - 8) top = tipRect.top - ph - 6;\n this._sizePopover.style.left = `${left}px`;\n this._sizePopover.style.top = `${top}px`;\n if (this._sizeInputEl) { this._sizeInputEl.focus(); this._sizeInputEl.select(); }\n });\n }\n\n _hideSizePopover() {\n if (this._sizePopover) this._sizePopover.style.display = 'none';\n this._sizeApply = null;\n }\n}\n","// CodeTooltip.js - Hover tooltip for <pre> code blocks inside the editor\n// Shows a horizontal action bar above (or below) the hovered code block,\n// consistent in appearance and interaction with ImageTooltip / TableTooltip.\nimport { createElement, on } from '../core/dom.js';\n\nconst SHOW_DELAY = 100;\nconst HIDE_DELAY = 180;\n\nconst ICONS = {\n copy: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\"/><path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\"/></svg>`,\n wrapOn: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\"/><path d=\"M3 12h15a3 3 0 0 1 0 6H3\"/><polyline points=\"6 15 3 18 6 21\"/></svg>`,\n toParagraph:`<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M13 4v16\"/><path d=\"M17 4v16\"/><path d=\"M9 4h8a4 4 0 0 1 0 8H9V4z\"/></svg>`,\n deleteCode: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"3 6 5 6 21 6\"/><path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2\"/></svg>`,\n};\n\nexport class CodeTooltip {\n /** @param {import('../Context.js').Context} context */\n constructor(context) {\n this.context = context;\n this._el = null;\n this._activePre = null;\n this._showTimer = null;\n this._hideTimer = null;\n this._disposers = [];\n this._copyBtn = null;\n this._langSelect = null;\n this._prismScript = null; // script element while Prism is loading\n }\n\n initialize() {\n this._el = this._buildTooltip();\n document.body.appendChild(this._el);\n this._ensurePrism();\n\n const editable = this.context.layoutInfo.editable;\n\n this._disposers.push(\n on(editable, 'mouseover', (e) => {\n const pre = e.target.closest('pre');\n if (pre && editable.contains(pre)) {\n this._scheduleShow(pre);\n }\n }),\n on(editable, 'mouseout', (e) => {\n const to = e.relatedTarget;\n if (!to || (!editable.contains(to) && !this._el.contains(to))) {\n this._scheduleHide();\n }\n }),\n on(document, 'click', (e) => {\n if (this._activePre &&\n !this._activePre.contains(e.target) &&\n !this._el.contains(e.target)) {\n this._hide();\n }\n }),\n );\n\n return this;\n }\n\n destroy() {\n this._clearTimers();\n this._disposers.forEach((d) => d());\n this._disposers = [];\n if (this._el && this._el.parentNode) this._el.parentNode.removeChild(this._el);\n this._el = null;\n }\n\n // ---------------------------------------------------------------------------\n // Build\n // ---------------------------------------------------------------------------\n\n _buildTooltip() {\n const el = createElement('div', {\n class: 'an-link-tooltip an-code-tooltip',\n role: 'toolbar',\n 'aria-label': 'Code block actions',\n });\n el.style.display = 'none';\n\n // Label\n this._label = createElement('span', { class: 'an-link-tooltip-url' });\n this._label.textContent = 'Code';\n el.appendChild(this._label);\n\n el.appendChild(this._sep());\n\n // Language selector\n this._langSelect = createElement('select', {\n class: 'an-code-lang-select',\n title: 'Syntax Language',\n 'aria-label': 'Syntax language',\n });\n const LANGUAGES = [\n ['', 'Plain text'], ['javascript', 'JavaScript'], ['typescript', 'TypeScript'],\n ['python', 'Python'], ['html', 'HTML'], ['css', 'CSS'], ['json', 'JSON'],\n ['xml', 'XML'], ['bash', 'Bash / Shell'], ['sql', 'SQL'],\n ['java', 'Java'], ['csharp', 'C#'], ['php', 'PHP'], ['ruby', 'Ruby'],\n ['go', 'Go'], ['rust', 'Rust'], ['cpp', 'C++'], ['c', 'C'],\n ['kotlin', 'Kotlin'], ['swift', 'Swift'],\n ];\n LANGUAGES.forEach(([value, label]) => {\n const opt = createElement('option', { value });\n opt.textContent = label;\n this._langSelect.appendChild(opt);\n });\n this._disposers.push(on(this._langSelect, 'change', () => this._onLangChange()));\n el.appendChild(this._langSelect);\n\n el.appendChild(this._sep());\n\n // Copy code\n this._copyBtn = this._makeBtn(ICONS.copy, 'Copy Code', () => this._copyCode());\n\n el.appendChild(this._copyBtn);\n\n el.appendChild(this._sep());\n\n // Toggle word-wrap\n this._wrapBtn = this._makeBtn(ICONS.wrapOn, 'Toggle Word Wrap', () => this._toggleWrap());\n el.appendChild(this._wrapBtn);\n\n el.appendChild(this._sep());\n\n // Convert to normal paragraph\n el.appendChild(this._makeBtn(ICONS.toParagraph, 'Convert to Paragraph', () => this._toParagraph()));\n\n el.appendChild(this._sep());\n\n // Delete block\n el.appendChild(this._makeBtn(ICONS.deleteCode, 'Delete Code Block', () => this._delete(), true));\n\n // Keep tooltip alive while hovering it\n this._disposers.push(\n on(el, 'mouseenter', () => this._clearTimers()),\n on(el, 'mouseleave', () => this._scheduleHide()),\n );\n\n return el;\n }\n\n _sep() {\n return createElement('div', { class: 'an-link-tooltip-sep' });\n }\n\n /**\n * @param {string} icon\n * @param {string} title\n * @param {Function} handler\n * @param {boolean} [isDanger]\n */\n _makeBtn(icon, title, handler, isDanger = false) {\n const btn = createElement('button', {\n type: 'button',\n class: isDanger ? 'an-link-tooltip-btn an-link-tooltip-btn--danger' : 'an-link-tooltip-btn',\n title,\n });\n btn.innerHTML = icon;\n this._disposers.push(on(btn, 'click', (e) => {\n e.preventDefault();\n e.stopPropagation();\n handler();\n }));\n return btn;\n }\n\n // ---------------------------------------------------------------------------\n // Show / Hide\n // ---------------------------------------------------------------------------\n\n _scheduleShow(pre) {\n if (this._activePre === pre && this._el.style.display !== 'none') return;\n clearTimeout(this._hideTimer);\n this._hideTimer = null;\n clearTimeout(this._showTimer);\n this._showTimer = setTimeout(() => {\n this._activePre = pre;\n this._syncWrapBtn();\n this._syncLangSelect();\n this._show(pre);\n }, SHOW_DELAY);\n }\n\n _scheduleHide() {\n clearTimeout(this._showTimer);\n this._showTimer = null;\n if (this._hideTimer) return;\n this._hideTimer = setTimeout(() => this._hide(), HIDE_DELAY);\n }\n\n _show(pre) {\n this._el.style.display = 'flex';\n this._positionNear(pre);\n }\n\n _hide() {\n this._el.style.display = 'none';\n this._activePre = null;\n this._clearTimers();\n }\n\n _clearTimers() {\n clearTimeout(this._showTimer);\n clearTimeout(this._hideTimer);\n this._showTimer = null;\n this._hideTimer = null;\n }\n\n _positionNear(pre) {\n const rect = pre.getBoundingClientRect();\n const tipW = this._el.offsetWidth || 260;\n const tipH = this._el.offsetHeight || 32;\n const margin = 6;\n\n // Prefer above the block; fall back to below\n let top = rect.top - tipH - margin;\n let left = rect.left + (rect.width - tipW) / 2;\n\n if (top < margin) top = rect.bottom + margin;\n if (left + tipW > window.innerWidth - margin) left = window.innerWidth - tipW - margin;\n if (left < margin) left = margin;\n\n // Tooltip uses position:fixed, so viewport coordinates are used directly.\n this._el.style.top = `${top}px`;\n this._el.style.left = `${left}px`;\n }\n\n // ---------------------------------------------------------------------------\n // Sync wrap-button active state\n // ---------------------------------------------------------------------------\n\n _syncWrapBtn() {\n if (!this._activePre || !this._wrapBtn) return;\n const wrapped = (this._activePre.style.whiteSpace || '').includes('pre-wrap')\n || window.getComputedStyle(this._activePre).whiteSpace === 'pre-wrap';\n this._wrapBtn.classList.toggle('active', wrapped);\n this._wrapBtn.title = wrapped ? 'Disable Word Wrap' : 'Enable Word Wrap';\n }\n\n _syncLangSelect() {\n if (!this._activePre || !this._langSelect) return;\n const codeEl = this._activePre.querySelector('code');\n const fromAttr = this._activePre.getAttribute('data-language') || '';\n const fromClass = codeEl ? (codeEl.className.match(/language-(\\S+)/) || [])[1] || '' : '';\n this._langSelect.value = fromAttr || fromClass || '';\n }\n\n // ---------------------------------------------------------------------------\n // Actions\n // ---------------------------------------------------------------------------\n\n _copyCode() {\n const pre = this._activePre;\n if (!pre) return;\n const text = pre.textContent || '';\n if (navigator.clipboard) {\n navigator.clipboard.writeText(text).then(() => this._flashCopied()).catch(() => {});\n } else {\n // Fallback for older browsers\n const ta = document.createElement('textarea');\n ta.value = text;\n ta.style.cssText = 'position:fixed;opacity:0;top:0;left:0';\n document.body.appendChild(ta);\n ta.select();\n try { document.execCommand('copy'); this._flashCopied(); } catch (_) {}\n document.body.removeChild(ta);\n }\n }\n\n _flashCopied() {\n if (!this._copyBtn) return;\n const original = this._copyBtn.innerHTML;\n this._copyBtn.innerHTML = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"/></svg>`;\n this._copyBtn.classList.add('an-link-tooltip-btn--copied');\n setTimeout(() => {\n if (this._copyBtn) {\n this._copyBtn.innerHTML = original;\n this._copyBtn.classList.remove('an-link-tooltip-btn--copied');\n }\n }, 1400);\n }\n\n _toggleWrap() {\n const pre = this._activePre;\n if (!pre) return;\n const isWrapped = pre.style.whiteSpace === 'pre-wrap';\n pre.style.whiteSpace = isWrapped ? 'pre' : 'pre-wrap';\n this._syncWrapBtn();\n this.context.invoke('editor.afterCommand');\n this._positionNear(pre);\n }\n\n _onLangChange() {\n const pre = this._activePre;\n if (!pre) return;\n const lang = this._langSelect.value;\n\n // Ensure a <code> child exists (Prism targets <pre><code class=\"language-xxx\">)\n let codeEl = pre.querySelector('code');\n if (!codeEl) {\n codeEl = document.createElement('code');\n codeEl.innerHTML = pre.innerHTML;\n pre.innerHTML = '';\n pre.appendChild(codeEl);\n }\n\n codeEl.className = lang ? `language-${lang}` : '';\n // Mirror language class on <pre> so Prism CSS theme targets it (pre[class*='language-'])\n pre.className = lang ? `language-${lang}` : '';\n if (lang) {\n pre.setAttribute('data-language', lang);\n } else {\n pre.removeAttribute('data-language');\n }\n\n // Trigger Prism if available.\n // contenteditable stores line breaks as <br> elements; Prism reads textContent\n // which drops <br> entirely, collapsing all lines into one. Convert first.\n const applyPrism = () => {\n codeEl.querySelectorAll('br').forEach((br) => br.replaceWith('\\n'));\n window.Prism.highlightElement(codeEl);\n this.context.invoke('editor.afterCommand');\n };\n\n if (lang) {\n if (typeof window.Prism !== 'undefined') {\n // Grammar already loaded — highlight immediately\n if (window.Prism.languages[lang]) {\n applyPrism();\n return;\n }\n // Grammar not in core bundle — load the component script first\n this._loadPrismComponent(lang, applyPrism);\n return;\n } else if (this._prismScript) {\n // Prism core is still loading — highlight once it arrives, then load grammar if needed\n this._prismScript.addEventListener('load', () => {\n if (window.Prism.languages[lang]) {\n applyPrism();\n } else {\n this._loadPrismComponent(lang, applyPrism);\n }\n }, { once: true });\n return;\n }\n }\n\n this.context.invoke('editor.afterCommand');\n }\n\n /**\n * Loads Prism.js + CSS from CDN when options.codeHighlight is true.\n * Called once at initialize time. Fire-and-forget; errors are silent.\n */\n _ensurePrism() {\n if (!this.context.options.codeHighlight || window.Prism) return;\n const cdn = this.context.options.codeHighlightCDN\n || 'https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0';\n const themeHref = `${cdn}/themes/prism-tomorrow.min.css`;\n const scriptSrc = `${cdn}/prism.min.js`;\n\n if (!document.querySelector(`link[href=\"${themeHref}\"]`)) {\n const link = document.createElement('link');\n link.rel = 'stylesheet';\n link.href = themeHref;\n document.head.appendChild(link);\n }\n\n const existingScript = document.querySelector(`script[src=\"${scriptSrc}\"]`);\n if (existingScript) {\n this._prismScript = window.Prism ? null : existingScript;\n return;\n }\n\n const script = document.createElement('script');\n script.dataset.manual = ''; // prevent auto-highlight on load\n script.src = scriptSrc;\n this._prismScript = script;\n script.addEventListener('load', () => { this._prismScript = null; }, { once: true });\n document.head.appendChild(script);\n }\n\n /**\n * Dynamically loads a Prism language component script if not already available.\n * Prism core only bundles: markup, css, clike, javascript.\n * All other grammars (bash, python, etc.) need a component file.\n * @param {string} lang – Prism language slug (e.g. 'bash', 'python')\n * @param {Function} cb – called once the grammar is ready\n */\n _loadPrismComponent(lang, cb) {\n const cdn = this.context.options.codeHighlightCDN\n || 'https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0';\n const src = `${cdn}/components/prism-${lang}.min.js`;\n // Avoid loading the same component twice\n if (document.querySelector(`script[src=\"${src}\"]`)) {\n // Already in DOM — might still be loading; poll briefly then call cb\n const poll = setInterval(() => {\n if (window.Prism && window.Prism.languages[lang]) {\n clearInterval(poll);\n cb();\n }\n }, 50);\n setTimeout(() => clearInterval(poll), 3000); // give up after 3s\n return;\n }\n const s = document.createElement('script');\n s.src = src;\n s.addEventListener('load', cb, { once: true });\n document.head.appendChild(s);\n }\n\n _toParagraph() {\n const pre = this._activePre;\n if (!pre) return;\n const editable = this.context.layoutInfo.editable;\n if (!editable) return;\n\n // Replace <pre> with <p> preserving lines as <br>\n const lines = (pre.textContent || '').split('\\n');\n const p = document.createElement('p');\n lines.forEach((line, i) => {\n if (i > 0) p.appendChild(document.createElement('br'));\n p.appendChild(document.createTextNode(line));\n });\n\n pre.parentNode.replaceChild(p, pre);\n this._hide();\n this.context.invoke('editor.afterCommand');\n }\n\n _delete() {\n const pre = this._activePre;\n if (!pre) return;\n this._hide();\n if (pre.parentNode) pre.parentNode.removeChild(pre);\n this.context.invoke('editor.afterCommand');\n }\n}\n","/**\n * EmojiDialog.js - Browse and insert Unicode emoji / symbols (UTF-8 / utf8mb4)\n * Click an emoji to insert it directly at the caret — no extra \"Insert\" step.\n */\n\nimport { createElement, on, trapFocus } from '../core/dom.js';\nimport { withSavedRange } from '../core/range.js';\n\n// ---------------------------------------------------------------------------\n// Emoji catalogue\n// ---------------------------------------------------------------------------\n\nconst EMOJI_CATS = [\n { id: 'smileys', label: 'Smileys' },\n { id: 'people', label: 'People' },\n { id: 'animals', label: 'Animals' },\n { id: 'food', label: 'Food' },\n { id: 'travel', label: 'Travel' },\n { id: 'objects', label: 'Objects' },\n { id: 'symbols', label: 'Symbols' },\n];\n\n// [emoji_char, search_keywords, category]\nconst EMOJI_LIST = [\n // Smileys & Emotions\n ['😀', 'grin smile happy face', 'smileys'],\n ['😃', 'happy smile big eyes', 'smileys'],\n ['😄', 'grinning smile laugh', 'smileys'],\n ['😁', 'beaming smile grin', 'smileys'],\n ['😆', 'laughing lol', 'smileys'],\n ['😅', 'sweat grin awkward', 'smileys'],\n ['🤣', 'rolling laugh rofl', 'smileys'],\n ['😂', 'tears laugh cry joy', 'smileys'],\n ['🙂', 'slight smile', 'smileys'],\n ['🙃', 'upside down smile', 'smileys'],\n ['😉', 'wink', 'smileys'],\n ['😊', 'blush smile happy', 'smileys'],\n ['😇', 'innocent halo angel', 'smileys'],\n ['🥰', 'hearts love adore', 'smileys'],\n ['😍', 'heart eyes love', 'smileys'],\n ['🤩', 'star eyes excited wow', 'smileys'],\n ['😘', 'kiss blow love', 'smileys'],\n ['😋', 'yum delicious tongue', 'smileys'],\n ['😛', 'tongue stuck out', 'smileys'],\n ['😜', 'wink tongue crazy', 'smileys'],\n ['🤪', 'zany crazy wild', 'smileys'],\n ['😝', 'squint tongue', 'smileys'],\n ['🤑', 'money mouth', 'smileys'],\n ['🤗', 'hugging hug', 'smileys'],\n ['🤔', 'thinking hmm', 'smileys'],\n ['🤨', 'raised eyebrow', 'smileys'],\n ['😐', 'neutral face', 'smileys'],\n ['😶', 'no mouth', 'smileys'],\n ['😏', 'smirk', 'smileys'],\n ['😒', 'unamused', 'smileys'],\n ['🙄', 'roll eyes', 'smileys'],\n ['😬', 'grimace', 'smileys'],\n ['😔', 'pensive sad', 'smileys'],\n ['😪', 'sleepy tired', 'smileys'],\n ['😴', 'sleeping zzz', 'smileys'],\n ['🤤', 'drool', 'smileys'],\n ['😷', 'mask sick', 'smileys'],\n ['🤒', 'sick thermometer', 'smileys'],\n ['🤕', 'hurt bandage', 'smileys'],\n ['🤢', 'nausea sick', 'smileys'],\n ['🤮', 'vomit sick', 'smileys'],\n ['🤧', 'sneeze cold', 'smileys'],\n ['🥵', 'hot sweat', 'smileys'],\n ['🥶', 'cold freeze', 'smileys'],\n ['😵', 'dizzy dead', 'smileys'],\n ['🤯', 'mind blown', 'smileys'],\n ['🤠', 'cowboy hat', 'smileys'],\n ['🥳', 'party celebrate', 'smileys'],\n ['😎', 'cool sunglasses', 'smileys'],\n ['🤓', 'nerd glasses', 'smileys'],\n ['🧐', 'monocle curious', 'smileys'],\n ['😕', 'confused', 'smileys'],\n ['😟', 'worried', 'smileys'],\n ['🙁', 'frown sad', 'smileys'],\n ['☹️', 'sad frown', 'smileys'],\n ['😮', 'surprised open mouth', 'smileys'],\n ['😲', 'astonished', 'smileys'],\n ['🥺', 'pleading begging puppy eyes', 'smileys'],\n ['😢', 'cry sad tear', 'smileys'],\n ['😭', 'sob cry loudly', 'smileys'],\n ['😱', 'scream horror fear', 'smileys'],\n ['😡', 'angry red pouting', 'smileys'],\n ['😠', 'angry mad', 'smileys'],\n ['🤬', 'cursing swear', 'smileys'],\n ['😈', 'devil evil smile', 'smileys'],\n ['👿', 'devil angry evil', 'smileys'],\n ['💀', 'skull death', 'smileys'],\n ['☠️', 'skull crossbones', 'smileys'],\n ['💩', 'poop', 'smileys'],\n ['🤡', 'clown', 'smileys'],\n ['👻', 'ghost boo', 'smileys'],\n ['👽', 'alien ufo', 'smileys'],\n ['🤖', 'robot', 'smileys'],\n\n // People & Body\n ['👋', 'wave hello hi hand', 'people'],\n ['🤚', 'raised back hand', 'people'],\n ['✋', 'raised hand stop', 'people'],\n ['🖖', 'vulcan salute spock', 'people'],\n ['👌', 'ok perfect fine', 'people'],\n ['✌️', 'peace victory fingers', 'people'],\n ['🤞', 'fingers crossed luck', 'people'],\n ['🤟', 'love you gesture', 'people'],\n ['🤘', 'sign of horns rock', 'people'],\n ['🤙', 'call me hand', 'people'],\n ['👈', 'point left', 'people'],\n ['👉', 'point right', 'people'],\n ['👆', 'point up', 'people'],\n ['👇', 'point down', 'people'],\n ['☝️', 'index pointing up', 'people'],\n ['👍', 'thumbs up like good', 'people'],\n ['👎', 'thumbs down dislike bad', 'people'],\n ['✊', 'raised fist punch', 'people'],\n ['👊', 'oncoming fist punch', 'people'],\n ['👏', 'clap applause', 'people'],\n ['🙌', 'celebrate raise hands', 'people'],\n ['🤝', 'handshake deal', 'people'],\n ['🙏', 'pray hope please thanks', 'people'],\n ['💅', 'nail polish', 'people'],\n ['💪', 'flexed bicep strong muscle', 'people'],\n ['👀', 'eyes look see', 'people'],\n ['👁️', 'eye', 'people'],\n ['👅', 'tongue', 'people'],\n ['👶', 'baby', 'people'],\n ['🧒', 'child', 'people'],\n ['👦', 'boy', 'people'],\n ['👧', 'girl', 'people'],\n ['🧑', 'person adult', 'people'],\n ['👨', 'man', 'people'],\n ['👩', 'woman', 'people'],\n ['🧔', 'beard man', 'people'],\n ['🧓', 'older person', 'people'],\n ['👴', 'old man', 'people'],\n ['👵', 'old woman', 'people'],\n ['❤️', 'heart love red', 'people'],\n ['🧡', 'orange heart love', 'people'],\n ['💛', 'yellow heart love', 'people'],\n ['💚', 'green heart love', 'people'],\n ['💙', 'blue heart love', 'people'],\n ['💜', 'purple heart love', 'people'],\n ['🖤', 'black heart', 'people'],\n ['🤍', 'white heart', 'people'],\n ['🤎', 'brown heart', 'people'],\n ['💔', 'broken heart', 'people'],\n ['❣️', 'exclamation heart', 'people'],\n ['💕', 'two hearts love', 'people'],\n ['💞', 'revolving hearts', 'people'],\n ['💓', 'beating heart', 'people'],\n ['💗', 'growing heart', 'people'],\n ['💖', 'sparkling heart', 'people'],\n ['💘', 'heart arrow', 'people'],\n ['💝', 'heart ribbon', 'people'],\n ['💬', 'speech bubble comment chat', 'people'],\n ['💭', 'thought bubble', 'people'],\n ['💯', '100 hundred percent perfect', 'people'],\n ['💢', 'anger symbol mad', 'people'],\n ['💤', 'zzz sleep', 'people'],\n\n // Animals & Nature\n ['🐶', 'dog puppy', 'animals'],\n ['🐱', 'cat kitten', 'animals'],\n ['🐭', 'mouse', 'animals'],\n ['🐹', 'hamster', 'animals'],\n ['🐰', 'rabbit bunny', 'animals'],\n ['🦊', 'fox', 'animals'],\n ['🐻', 'bear', 'animals'],\n ['🐼', 'panda', 'animals'],\n ['🐨', 'koala', 'animals'],\n ['🐯', 'tiger', 'animals'],\n ['🦁', 'lion', 'animals'],\n ['🐮', 'cow', 'animals'],\n ['🐷', 'pig', 'animals'],\n ['🐸', 'frog', 'animals'],\n ['🐵', 'monkey', 'animals'],\n ['🙈', 'see no evil monkey', 'animals'],\n ['🙉', 'hear no evil monkey', 'animals'],\n ['🙊', 'speak no evil monkey', 'animals'],\n ['🐔', 'chicken hen', 'animals'],\n ['🐧', 'penguin', 'animals'],\n ['🐦', 'bird', 'animals'],\n ['🦆', 'duck', 'animals'],\n ['🦅', 'eagle', 'animals'],\n ['🦉', 'owl', 'animals'],\n ['🦇', 'bat', 'animals'],\n ['🐺', 'wolf', 'animals'],\n ['🐴', 'horse', 'animals'],\n ['🦄', 'unicorn', 'animals'],\n ['🐝', 'bee', 'animals'],\n ['🦋', 'butterfly', 'animals'],\n ['🐌', 'snail', 'animals'],\n ['🐞', 'ladybug', 'animals'],\n ['🐢', 'turtle', 'animals'],\n ['🐍', 'snake', 'animals'],\n ['🦎', 'lizard', 'animals'],\n ['🐊', 'crocodile', 'animals'],\n ['🐟', 'fish', 'animals'],\n ['🐠', 'tropical fish', 'animals'],\n ['🦈', 'shark', 'animals'],\n ['🐬', 'dolphin', 'animals'],\n ['🐳', 'whale', 'animals'],\n ['🐙', 'octopus', 'animals'],\n ['🦑', 'squid', 'animals'],\n ['🦀', 'crab', 'animals'],\n ['🌸', 'cherry blossom flower', 'animals'],\n ['🌺', 'hibiscus flower', 'animals'],\n ['🌻', 'sunflower', 'animals'],\n ['🌹', 'rose flower', 'animals'],\n ['🌷', 'tulip flower', 'animals'],\n ['🍀', 'four leaf clover luck', 'animals'],\n ['🌿', 'herb leaf green', 'animals'],\n ['🌱', 'seedling sprout', 'animals'],\n ['🌲', 'evergreen tree pine', 'animals'],\n ['🌳', 'deciduous tree', 'animals'],\n ['🌴', 'palm tree', 'animals'],\n ['🍄', 'mushroom', 'animals'],\n ['🌾', 'sheaf wheat', 'animals'],\n ['🐾', 'paw prints animal', 'animals'],\n\n // Food & Drink\n ['🍎', 'apple red', 'food'],\n ['🍊', 'orange tangerine', 'food'],\n ['🍋', 'lemon yellow', 'food'],\n ['🍇', 'grapes', 'food'],\n ['🍓', 'strawberry', 'food'],\n ['🫐', 'blueberry', 'food'],\n ['🍒', 'cherry', 'food'],\n ['🍑', 'peach', 'food'],\n ['🥭', 'mango', 'food'],\n ['🍍', 'pineapple', 'food'],\n ['🥥', 'coconut', 'food'],\n ['🥝', 'kiwi', 'food'],\n ['🍅', 'tomato', 'food'],\n ['🥑', 'avocado', 'food'],\n ['🍆', 'eggplant aubergine', 'food'],\n ['🥕', 'carrot', 'food'],\n ['🌽', 'corn', 'food'],\n ['🥦', 'broccoli', 'food'],\n ['🥬', 'leafy green', 'food'],\n ['🧄', 'garlic', 'food'],\n ['🥜', 'peanut nut', 'food'],\n ['🍞', 'bread loaf', 'food'],\n ['🥐', 'croissant', 'food'],\n ['🧀', 'cheese', 'food'],\n ['🍳', 'egg fry cooking', 'food'],\n ['🥚', 'egg', 'food'],\n ['🥞', 'pancake', 'food'],\n ['🧇', 'waffle', 'food'],\n ['🥓', 'bacon', 'food'],\n ['🥩', 'meat steak', 'food'],\n ['🍗', 'chicken leg', 'food'],\n ['🌭', 'hotdog', 'food'],\n ['🍔', 'burger hamburger', 'food'],\n ['🍟', 'fries french', 'food'],\n ['🍕', 'pizza', 'food'],\n ['🌮', 'taco', 'food'],\n ['🌯', 'burrito wrap', 'food'],\n ['🍜', 'noodles ramen', 'food'],\n ['🍝', 'spaghetti pasta', 'food'],\n ['🍣', 'sushi', 'food'],\n ['🍱', 'bento box', 'food'],\n ['🍦', 'ice cream soft serve', 'food'],\n ['🍩', 'donut', 'food'],\n ['🍪', 'cookie', 'food'],\n ['🎂', 'birthday cake', 'food'],\n ['🍰', 'cake slice', 'food'],\n ['🧁', 'cupcake', 'food'],\n ['🍫', 'chocolate', 'food'],\n ['🍬', 'candy', 'food'],\n ['🍭', 'lollipop', 'food'],\n ['☕', 'coffee hot', 'food'],\n ['🍵', 'tea hot', 'food'],\n ['🧋', 'bubble tea boba', 'food'],\n ['🥤', 'cup straw drink', 'food'],\n ['🍷', 'wine red', 'food'],\n ['🍸', 'cocktail martini', 'food'],\n ['🍺', 'beer mug', 'food'],\n ['🍻', 'clinking beer mugs', 'food'],\n ['🥂', 'champagne toast celebrate', 'food'],\n ['🧃', 'juice box', 'food'],\n ['🧊', 'ice cube', 'food'],\n\n // Travel & Places\n ['🚀', 'rocket space', 'travel'],\n ['🛸', 'ufo flying saucer', 'travel'],\n ['✈️', 'airplane plane fly', 'travel'],\n ['🚁', 'helicopter', 'travel'],\n ['🚂', 'train locomotive', 'travel'],\n ['🚄', 'bullet train fast', 'travel'],\n ['🚇', 'subway metro', 'travel'],\n ['🚌', 'bus', 'travel'],\n ['🚑', 'ambulance', 'travel'],\n ['🚒', 'fire truck', 'travel'],\n ['🚓', 'police car', 'travel'],\n ['🚕', 'taxi cab', 'travel'],\n ['🚗', 'car automobile red', 'travel'],\n ['🚙', 'suv car', 'travel'],\n ['🚚', 'truck delivery', 'travel'],\n ['🚜', 'tractor farm', 'travel'],\n ['🏎️', 'racing car fast', 'travel'],\n ['🏍️', 'motorcycle', 'travel'],\n ['🚲', 'bicycle bike', 'travel'],\n ['🛴', 'scooter kick', 'travel'],\n ['⛵', 'sailboat boat', 'travel'],\n ['🚢', 'ship cruise', 'travel'],\n ['🏠', 'house home', 'travel'],\n ['🏢', 'office building', 'travel'],\n ['🏥', 'hospital', 'travel'],\n ['🏦', 'bank', 'travel'],\n ['🏪', 'store shop convenience', 'travel'],\n ['🏫', 'school', 'travel'],\n ['🏰', 'castle european', 'travel'],\n ['🏯', 'japanese castle', 'travel'],\n ['🗼', 'tokyo tower', 'travel'],\n ['🗽', 'statue liberty new york', 'travel'],\n ['⛪', 'church', 'travel'],\n ['🕌', 'mosque', 'travel'],\n ['⛩️', 'shinto shrine', 'travel'],\n ['⛲', 'fountain', 'travel'],\n ['⛺', 'tent camping', 'travel'],\n ['🌁', 'fog foggy bridge', 'travel'],\n ['🌃', 'night city stars', 'travel'],\n ['🏙️', 'cityscape city buildings', 'travel'],\n ['🌅', 'sunrise morning', 'travel'],\n ['🌈', 'rainbow colorful', 'travel'],\n ['⛰️', 'mountain', 'travel'],\n ['🏔️', 'snow mountain', 'travel'],\n ['🗻', 'mount fuji', 'travel'],\n ['🏕️', 'camping tent', 'travel'],\n ['🗺️', 'world map', 'travel'],\n ['🧭', 'compass navigation', 'travel'],\n ['🌍', 'earth europe africa globe', 'travel'],\n ['🌎', 'earth americas globe', 'travel'],\n ['🌏', 'earth asia globe', 'travel'],\n ['🌐', 'globe internet web', 'travel'],\n\n // Objects\n ['💎', 'diamond gem jewel', 'objects'],\n ['💍', 'ring engagement', 'objects'],\n ['👑', 'crown royal king queen', 'objects'],\n ['🎩', 'top hat magic', 'objects'],\n ['💼', 'briefcase work business', 'objects'],\n ['👜', 'handbag purse', 'objects'],\n ['🎒', 'backpack bag school', 'objects'],\n ['👓', 'glasses eyewear', 'objects'],\n ['🕶️', 'sunglasses cool', 'objects'],\n ['💡', 'light bulb idea', 'objects'],\n ['🔦', 'flashlight torch', 'objects'],\n ['🕯️', 'candle light', 'objects'],\n ['🔋', 'battery charge', 'objects'],\n ['💻', 'laptop computer', 'objects'],\n ['🖥️', 'desktop monitor computer', 'objects'],\n ['📱', 'phone mobile cell', 'objects'],\n ['⌨️', 'keyboard type', 'objects'],\n ['🖱️', 'mouse computer click', 'objects'],\n ['📺', 'television tv', 'objects'],\n ['📷', 'camera photo', 'objects'],\n ['📹', 'video camera', 'objects'],\n ['🎥', 'movie camera film', 'objects'],\n ['☎️', 'telephone phone', 'objects'],\n ['⏰', 'alarm clock wake', 'objects'],\n ['⌚', 'watch time', 'objects'],\n ['🔑', 'key', 'objects'],\n ['🗝️', 'old key', 'objects'],\n ['🔒', 'lock closed', 'objects'],\n ['🔓', 'unlock open', 'objects'],\n ['🔨', 'hammer tool', 'objects'],\n ['🔧', 'wrench tool', 'objects'],\n ['🔩', 'bolt nut', 'objects'],\n ['⚙️', 'gear setting', 'objects'],\n ['🧲', 'magnet attract', 'objects'],\n ['📚', 'books stack library', 'objects'],\n ['📖', 'book open read', 'objects'],\n ['📝', 'memo write note', 'objects'],\n ['✏️', 'pencil write edit', 'objects'],\n ['📌', 'pushpin tack', 'objects'],\n ['📎', 'paperclip attach', 'objects'],\n ['📊', 'bar chart graph', 'objects'],\n ['📈', 'chart up growth trend', 'objects'],\n ['📉', 'chart down loss decline', 'objects'],\n ['📅', 'calendar date', 'objects'],\n ['📦', 'package box', 'objects'],\n ['📫', 'mailbox closed', 'objects'],\n ['📧', 'email envelope', 'objects'],\n ['🎁', 'gift present', 'objects'],\n ['🎀', 'ribbon bow', 'objects'],\n ['🎉', 'party celebrate confetti', 'objects'],\n ['🎊', 'confetti celebrate', 'objects'],\n ['🔮', 'crystal ball magic fortune', 'objects'],\n ['🪄', 'magic wand', 'objects'],\n ['🎯', 'target bullseye dart', 'objects'],\n ['🎲', 'dice game board', 'objects'],\n ['🎮', 'video game controller', 'objects'],\n ['🎭', 'theater masks drama', 'objects'],\n ['🎨', 'art palette paint', 'objects'],\n ['🎬', 'clapper film movie', 'objects'],\n ['🎤', 'microphone sing karaoke', 'objects'],\n ['🎧', 'headphones music listen', 'objects'],\n ['🎵', 'music note', 'objects'],\n ['🎶', 'music notes', 'objects'],\n ['🎸', 'guitar electric', 'objects'],\n ['🎹', 'piano keyboard music', 'objects'],\n ['🥁', 'drum percussion', 'objects'],\n ['🎷', 'saxophone jazz', 'objects'],\n ['🎺', 'trumpet', 'objects'],\n ['🎻', 'violin', 'objects'],\n ['⚽', 'soccer ball football', 'objects'],\n ['🏀', 'basketball', 'objects'],\n ['🏈', 'american football', 'objects'],\n ['⚾', 'baseball', 'objects'],\n ['🎾', 'tennis', 'objects'],\n ['🏐', 'volleyball', 'objects'],\n ['🏆', 'trophy winner award', 'objects'],\n ['🥇', 'gold medal first', 'objects'],\n ['🏅', 'sports medal', 'objects'],\n\n // Symbols\n ['✅', 'check green done success', 'symbols'],\n ['❌', 'cross x no cancel', 'symbols'],\n ['⭕', 'circle red', 'symbols'],\n ['⛔', 'no entry stop', 'symbols'],\n ['🚫', 'prohibited no banned', 'symbols'],\n ['⚠️', 'warning caution danger', 'symbols'],\n ['❗', 'exclamation red important', 'symbols'],\n ['❓', 'question mark', 'symbols'],\n ['‼️', 'double exclamation', 'symbols'],\n ['💯', '100 hundred percent perfect', 'symbols'],\n ['🔴', 'red circle dot', 'symbols'],\n ['🟠', 'orange circle', 'symbols'],\n ['🟡', 'yellow circle', 'symbols'],\n ['🟢', 'green circle', 'symbols'],\n ['🔵', 'blue circle', 'symbols'],\n ['🟣', 'purple circle', 'symbols'],\n ['⚫', 'black circle', 'symbols'],\n ['⚪', 'white circle', 'symbols'],\n ['🟤', 'brown circle', 'symbols'],\n ['🔺', 'red triangle up', 'symbols'],\n ['🔻', 'red triangle down', 'symbols'],\n ['🔷', 'blue diamond large', 'symbols'],\n ['🔶', 'orange diamond large', 'symbols'],\n ['🔹', 'blue diamond small', 'symbols'],\n ['🔸', 'orange diamond small', 'symbols'],\n ['⭐', 'star yellow', 'symbols'],\n ['🌟', 'glowing star shine', 'symbols'],\n ['✨', 'sparkles shine', 'symbols'],\n ['💫', 'dizzy star spin', 'symbols'],\n ['⚡', 'lightning bolt energy power', 'symbols'],\n ['🔥', 'fire hot flame', 'symbols'],\n ['💥', 'explosion boom', 'symbols'],\n ['❄️', 'snowflake cold ice winter', 'symbols'],\n ['🌊', 'wave water ocean sea', 'symbols'],\n ['💨', 'wind blow dash', 'symbols'],\n ['🌀', 'cyclone tornado spiral', 'symbols'],\n ['♻️', 'recycle loop green', 'symbols'],\n ['✔️', 'check tick done', 'symbols'],\n ['➕', 'plus add', 'symbols'],\n ['➖', 'minus subtract', 'symbols'],\n ['➗', 'divide division', 'symbols'],\n ['✖️', 'multiply times cross', 'symbols'],\n ['▶️', 'play button right', 'symbols'],\n ['⏸️', 'pause', 'symbols'],\n ['⏹️', 'stop square', 'symbols'],\n ['⏩', 'fast forward', 'symbols'],\n ['⏪', 'rewind fast backward', 'symbols'],\n ['🔔', 'bell notification', 'symbols'],\n ['🔕', 'bell slash mute', 'symbols'],\n ['🔊', 'speaker volume high', 'symbols'],\n ['🔇', 'mute silent no sound', 'symbols'],\n ['📢', 'loudspeaker announcement', 'symbols'],\n ['📣', 'megaphone cheer', 'symbols'],\n ['🏳️', 'white flag', 'symbols'],\n ['🏴', 'black flag', 'symbols'],\n ['🚩', 'red flag', 'symbols'],\n ['🏁', 'checkered flag finish race', 'symbols'],\n ['🆕', 'new badge', 'symbols'],\n ['🆓', 'free badge', 'symbols'],\n ['🆒', 'cool badge', 'symbols'],\n ['🔝', 'top arrow', 'symbols'],\n ['🔙', 'back arrow', 'symbols'],\n ['ℹ️', 'information info', 'symbols'],\n ['📍', 'pin location map', 'symbols'],\n ['🔗', 'link chain', 'symbols'],\n ['©️', 'copyright', 'symbols'],\n ['®️', 'registered trademark', 'symbols'],\n ['™️', 'trademark', 'symbols'],\n ['#️⃣', 'hash number', 'symbols'],\n ['0️⃣', 'zero number', 'symbols'],\n ['1️⃣', 'one number', 'symbols'],\n ['2️⃣', 'two number', 'symbols'],\n ['3️⃣', 'three number', 'symbols'],\n ['4️⃣', 'four number', 'symbols'],\n ['5️⃣', 'five number', 'symbols'],\n];\n\n// ---------------------------------------------------------------------------\n// Dialog class\n// ---------------------------------------------------------------------------\n\nexport class EmojiDialog {\n /**\n * @param {import('../Context.js').Context} context\n */\n constructor(context) {\n this.context = context;\n /** @type {HTMLElement|null} */\n this._dialog = null;\n this._disposers = [];\n this._savedRange = null;\n this._activeCat = 'all';\n }\n\n // ---------------------------------------------------------------------------\n // Lifecycle\n // ---------------------------------------------------------------------------\n\n initialize() {\n // Dialog grid is built lazily on first show() to avoid rendering ~500 DOM nodes at load time.\n return this;\n }\n\n destroy() {\n this._disposers.forEach((d) => d());\n this._disposers = [];\n if (this._dialog && this._dialog.parentNode) {\n this._dialog.parentNode.removeChild(this._dialog);\n }\n this._dialog = null;\n }\n\n // ---------------------------------------------------------------------------\n // Public API\n // ---------------------------------------------------------------------------\n\n show() {\n if (!this._dialog) {\n this._dialog = this._buildDialog();\n document.body.appendChild(this._dialog);\n }\n withSavedRange((range) => {\n this._savedRange = range;\n });\n this._activeCat = 'all';\n this._searchInput.value = '';\n this._updateCatTabs();\n this._filterEmojis('', 'all');\n this._open();\n }\n\n // ---------------------------------------------------------------------------\n // Build dialog\n // ---------------------------------------------------------------------------\n\n _buildDialog() {\n const overlay = createElement('div', {\n class: 'an-dialog-overlay',\n role: 'dialog',\n 'aria-modal': 'true',\n 'aria-label': 'Insert emoji',\n });\n const box = createElement('div', { class: 'an-dialog-box an-emoji-box' });\n\n // Title row\n const titleRow = createElement('div', { class: 'an-icon-title-row' });\n const title = createElement('h3', { class: 'an-dialog-title' });\n title.textContent = 'Insert Emoji';\n const closeBtn = createElement('button', { type: 'button', class: 'an-icon-close', 'aria-label': 'Close' });\n closeBtn.innerHTML = '×';\n titleRow.append(title, closeBtn);\n\n // Search\n const searchInput = createElement('input', {\n type: 'search',\n class: 'an-input an-icon-search',\n placeholder: 'Search emojis…',\n autocomplete: 'off',\n });\n this._searchInput = searchInput;\n\n // Category tabs\n const catBar = createElement('div', { class: 'an-icon-cats' });\n const allTab = createElement('button', { type: 'button', class: 'an-icon-cat active', 'data-cat': 'all' });\n allTab.textContent = 'All';\n catBar.appendChild(allTab);\n EMOJI_CATS.forEach(({ id, label }) => {\n const tab = createElement('button', { type: 'button', class: 'an-icon-cat', 'data-cat': id });\n tab.textContent = label;\n catBar.appendChild(tab);\n });\n this._catBar = catBar;\n\n // Emoji grid — one button per emoji, click = immediate insert\n const grid = createElement('div', { class: 'an-emoji-grid' });\n EMOJI_LIST.forEach(([char, keywords, cat]) => {\n const cell = createElement('button', {\n type: 'button',\n class: 'an-emoji-cell',\n 'data-char': char,\n 'data-keywords': keywords,\n 'data-cat': cat,\n title: keywords.split(' ').slice(0, 2).join(' '),\n });\n cell.textContent = char;\n grid.appendChild(cell);\n });\n this._grid = grid;\n\n // Cancel only — clicking an emoji inserts immediately\n const btnRow = createElement('div', { class: 'an-dialog-actions' });\n const cancelBtn = createElement('button', { type: 'button', class: 'an-btn' });\n cancelBtn.textContent = 'Cancel';\n btnRow.appendChild(cancelBtn);\n\n box.append(titleRow, searchInput, catBar, grid, btnRow);\n overlay.appendChild(box);\n\n // Events\n const d1 = on(closeBtn, 'click', () => this._close());\n const d2 = on(cancelBtn, 'click', () => this._close());\n const d3 = on(overlay, 'click', (e) => { if (e.target === overlay) this._close(); });\n const d4 = on(searchInput, 'input', () => this._filterEmojis(searchInput.value, this._activeCat));\n const d5 = on(catBar, 'click', (e) => {\n const tab = e.target.closest('[data-cat]');\n if (tab) {\n this._activeCat = tab.dataset.cat;\n this._updateCatTabs();\n this._filterEmojis(this._searchInput.value, this._activeCat);\n }\n });\n const d6 = on(grid, 'click', (e) => {\n const cell = e.target.closest('.an-emoji-cell');\n if (cell) this._onEmojiClick(cell.dataset.char);\n });\n this._disposers.push(d1, d2, d3, d4, d5, d6);\n return overlay;\n }\n\n // ---------------------------------------------------------------------------\n // Filter\n // ---------------------------------------------------------------------------\n\n _updateCatTabs() {\n this._catBar.querySelectorAll('.an-icon-cat').forEach((tab) => {\n tab.classList.toggle('active', tab.dataset.cat === this._activeCat);\n });\n }\n\n _filterEmojis(query, cat) {\n const q = (query || '').trim().toLowerCase();\n let count = 0;\n this._grid.querySelectorAll('.an-emoji-cell').forEach((cell) => {\n const matchCat = !cat || cat === 'all' || cell.dataset.cat === cat;\n const matchQuery = !q || cell.dataset.keywords.includes(q) || cell.dataset.char === q;\n const visible = matchCat && matchQuery;\n cell.style.display = visible ? '' : 'none';\n if (visible) count++;\n });\n let empty = this._grid.querySelector('.an-icon-empty');\n if (!empty) {\n empty = createElement('div', { class: 'an-icon-empty' });\n empty.textContent = 'No emojis found';\n this._grid.appendChild(empty);\n }\n empty.style.display = count > 0 ? 'none' : '';\n }\n\n // ---------------------------------------------------------------------------\n // Insert\n // ---------------------------------------------------------------------------\n\n _onEmojiClick(char) {\n const savedRange = this._savedRange;\n const editable = this.context.layoutInfo.editable;\n\n // 1. Restore selection while dialog is still mounted (same pattern as ImageDialog)\n if (savedRange) savedRange.select();\n\n const sel = window.getSelection();\n let range = sel && sel.rangeCount > 0 ? sel.getRangeAt(0) : null;\n if (!range) {\n range = document.createRange();\n range.selectNodeContents(editable);\n range.collapse(false);\n }\n\n // 2. Insert emoji as a plain text node — no ZWS or execCommand needed.\n // Text nodes are natively navigable so the caret lands cleanly after.\n range.deleteContents();\n const textNode = document.createTextNode(char);\n range.insertNode(textNode);\n\n // 3. Place caret immediately after the emoji character\n range.setStartAfter(textNode);\n range.collapse(true);\n if (sel) {\n sel.removeAllRanges();\n sel.addRange(range);\n }\n\n // 4. Close and restore editor focus\n this._close();\n editable.focus();\n this.context.invoke('editor.afterCommand');\n }\n\n // ---------------------------------------------------------------------------\n // Open / Close\n // ---------------------------------------------------------------------------\n\n _open() {\n if (this._dialog) {\n this._dialog.style.display = 'flex';\n this._removeTrap = trapFocus(this._dialog, () => this._close());\n setTimeout(() => this._searchInput && this._searchInput.focus(), 50);\n }\n }\n\n _close() {\n if (this._dialog) this._dialog.style.display = 'none';\n if (this._removeTrap) { this._removeTrap(); this._removeTrap = null; }\n this._savedRange = null;\n }\n}\n","/**\n * IconDialog.js - Browse and insert FontAwesome Free icons\n */\n\nimport { createElement, on, trapFocus } from '../core/dom.js';\nimport { withSavedRange } from '../core/range.js';\n\n// ---------------------------------------------------------------------------\n// Icon catalogue — FA 6 Free Solid slug names, grouped by category\n// ---------------------------------------------------------------------------\n\nconst ICON_CATEGORIES = [\n { id: 'popular', label: 'Popular' },\n { id: 'interface', label: 'Interface' },\n { id: 'navigation', label: 'Navigation' },\n { id: 'media', label: 'Media' },\n { id: 'communication', label: 'Communication' },\n { id: 'files', label: 'Files' },\n { id: 'people', label: 'People' },\n { id: 'objects', label: 'Objects' },\n];\n\n// Each entry: [slug, category]\nconst ICON_LIST = [\n // Popular\n ['house', 'popular'],\n ['star', 'popular'],\n ['heart', 'popular'],\n ['check', 'popular'],\n ['xmark', 'popular'],\n ['plus', 'popular'],\n ['minus', 'popular'],\n ['magnifying-glass', 'popular'],\n ['gear', 'popular'],\n ['bell', 'popular'],\n ['user', 'popular'],\n ['envelope', 'popular'],\n ['phone', 'popular'],\n ['calendar', 'popular'],\n ['clock', 'popular'],\n ['lock', 'popular'],\n ['eye', 'popular'],\n ['eye-slash', 'popular'],\n ['trash', 'popular'],\n ['pen', 'popular'],\n ['bookmark', 'popular'],\n ['flag', 'popular'],\n ['thumbs-up', 'popular'],\n ['thumbs-down', 'popular'],\n ['circle-info', 'popular'],\n ['triangle-exclamation', 'popular'],\n ['circle-check', 'popular'],\n ['circle-xmark', 'popular'],\n ['share', 'popular'],\n ['download', 'popular'],\n ['upload', 'popular'],\n ['tag', 'popular'],\n // Interface\n ['bars', 'interface'],\n ['ellipsis', 'interface'],\n ['ellipsis-vertical', 'interface'],\n ['list', 'interface'],\n ['table-cells', 'interface'],\n ['table-list', 'interface'],\n ['grip', 'interface'],\n ['filter', 'interface'],\n ['sort', 'interface'],\n ['arrows-rotate', 'interface'],\n ['rotate', 'interface'],\n ['rotate-left', 'interface'],\n ['rotate-right', 'interface'],\n ['copy', 'interface'],\n ['floppy-disk', 'interface'],\n ['print', 'interface'],\n ['link', 'interface'],\n ['code', 'interface'],\n ['expand', 'interface'],\n ['compress', 'interface'],\n ['cloud', 'interface'],\n ['lock-open', 'interface'],\n ['key', 'interface'],\n ['shield', 'interface'],\n ['shield-halved', 'interface'],\n ['sliders', 'interface'],\n ['toggle-on', 'interface'],\n ['square-check', 'interface'],\n ['circle-plus', 'interface'],\n ['circle-minus', 'interface'],\n // Navigation\n ['arrow-right', 'navigation'],\n ['arrow-left', 'navigation'],\n ['arrow-up', 'navigation'],\n ['arrow-down', 'navigation'],\n ['chevron-right', 'navigation'],\n ['chevron-left', 'navigation'],\n ['chevron-up', 'navigation'],\n ['chevron-down', 'navigation'],\n ['angle-right', 'navigation'],\n ['angle-left', 'navigation'],\n ['angle-up', 'navigation'],\n ['angle-down', 'navigation'],\n ['angles-right', 'navigation'],\n ['angles-left', 'navigation'],\n ['location-dot', 'navigation'],\n ['compass', 'navigation'],\n ['map', 'navigation'],\n ['map-pin', 'navigation'],\n ['route', 'navigation'],\n ['circle-arrow-right', 'navigation'],\n ['circle-arrow-left', 'navigation'],\n ['arrow-trend-up', 'navigation'],\n ['arrow-trend-down', 'navigation'],\n ['right-from-bracket', 'navigation'],\n ['right-to-bracket', 'navigation'],\n // Media\n ['play', 'media'],\n ['pause', 'media'],\n ['stop', 'media'],\n ['forward', 'media'],\n ['backward', 'media'],\n ['forward-step', 'media'],\n ['backward-step', 'media'],\n ['volume-high', 'media'],\n ['volume-low', 'media'],\n ['volume-xmark', 'media'],\n ['volume-off', 'media'],\n ['music', 'media'],\n ['headphones', 'media'],\n ['microphone', 'media'],\n ['microphone-slash', 'media'],\n ['film', 'media'],\n ['camera', 'media'],\n ['camera-rotate', 'media'],\n ['video', 'media'],\n ['image', 'media'],\n ['images', 'media'],\n ['photo-film', 'media'],\n ['podcast', 'media'],\n ['radio', 'media'],\n // Communication\n ['comment', 'communication'],\n ['comments', 'communication'],\n ['comment-dots', 'communication'],\n ['message', 'communication'],\n ['paper-plane', 'communication'],\n ['reply', 'communication'],\n ['reply-all', 'communication'],\n ['at', 'communication'],\n ['hashtag', 'communication'],\n ['wifi', 'communication'],\n ['signal', 'communication'],\n ['rss', 'communication'],\n ['share-nodes', 'communication'],\n ['inbox', 'communication'],\n ['phone-volume', 'communication'],\n ['mobile', 'communication'],\n ['mobile-screen', 'communication'],\n ['laptop', 'communication'],\n ['desktop', 'communication'],\n ['tower-broadcast', 'communication'],\n // Files\n ['file', 'files'],\n ['file-lines', 'files'],\n ['folder', 'files'],\n ['folder-open', 'files'],\n ['folder-plus', 'files'],\n ['folder-minus', 'files'],\n ['file-image', 'files'],\n ['file-pdf', 'files'],\n ['file-code', 'files'],\n ['file-zipper', 'files'],\n ['file-audio', 'files'],\n ['file-video', 'files'],\n ['file-arrow-up', 'files'],\n ['file-arrow-down', 'files'],\n ['database', 'files'],\n ['box', 'files'],\n ['box-open', 'files'],\n ['hard-drive', 'files'],\n ['server', 'files'],\n // People\n ['user', 'people'],\n ['users', 'people'],\n ['user-group', 'people'],\n ['user-plus', 'people'],\n ['user-minus', 'people'],\n ['user-check', 'people'],\n ['user-xmark', 'people'],\n ['user-tie', 'people'],\n ['user-shield', 'people'],\n ['user-secret', 'people'],\n ['person', 'people'],\n ['person-running', 'people'],\n ['person-walking', 'people'],\n ['child', 'people'],\n ['handshake', 'people'],\n ['hand', 'people'],\n ['hands-holding', 'people'],\n ['people-group', 'people'],\n // Objects\n ['pencil', 'objects'],\n ['paintbrush', 'objects'],\n ['eraser', 'objects'],\n ['scissors', 'objects'],\n ['wrench', 'objects'],\n ['screwdriver', 'objects'],\n ['hammer', 'objects'],\n ['toolbox', 'objects'],\n ['graduation-cap', 'objects'],\n ['book', 'objects'],\n ['book-open', 'objects'],\n ['glasses', 'objects'],\n ['microscope', 'objects'],\n ['flask', 'objects'],\n ['stethoscope', 'objects'],\n ['hospital', 'objects'],\n ['building', 'objects'],\n ['city', 'objects'],\n ['car', 'objects'],\n ['truck', 'objects'],\n ['plane', 'objects'],\n ['train', 'objects'],\n ['bicycle', 'objects'],\n ['bus', 'objects'],\n ['rocket', 'objects'],\n ['briefcase', 'objects'],\n ['cart-shopping', 'objects'],\n ['bag-shopping', 'objects'],\n ['credit-card', 'objects'],\n ['money-bill', 'objects'],\n ['chart-bar', 'objects'],\n ['chart-line', 'objects'],\n ['chart-pie', 'objects'],\n ['bolt', 'objects'],\n ['sun', 'objects'],\n ['moon', 'objects'],\n ['snowflake', 'objects'],\n ['fire', 'objects'],\n ['droplet', 'objects'],\n ['leaf', 'objects'],\n ['tree', 'objects'],\n ['earth-americas', 'objects'],\n ['globe', 'objects'],\n ['award', 'objects'],\n ['trophy', 'objects'],\n ['gift', 'objects'],\n ['puzzle-piece', 'objects'],\n];\n\nexport class IconDialog {\n /**\n * @param {import('../Context.js').Context} context\n */\n constructor(context) {\n this.context = context;\n /** @type {HTMLElement|null} */\n this._dialog = null;\n this._disposers = [];\n this._savedRange = null;\n this._selectedIcon = null;\n this._activeCat = 'all';\n }\n\n // ---------------------------------------------------------------------------\n // Lifecycle\n // ---------------------------------------------------------------------------\n\n initialize() {\n this._ensureFontAwesome();\n // Dialog grid is built lazily on first show() to avoid rendering ~250 icon cells at load time.\n return this;\n }\n\n /**\n * Injects FA 6 Free CSS from CDN if it is not already on the page.\n * This guarantees icon glyphs render in the grid, preview, and in the\n * editor content after insertion — regardless of whether the host page\n * loaded FA itself.\n */\n _ensureFontAwesome() {\n // Already present (icon element or stylesheet link)?\n if (document.getElementById('an-fontawesome-css')) return;\n const links = Array.from(document.querySelectorAll('link[rel=\"stylesheet\"]'))\n .map((l) => l.href || '').join(' ');\n if (/fontawesome|font-awesome/.test(links)) return;\n if (document.querySelector('.fa-solid, .fas, .far, .fab')) return;\n\n const link = document.createElement('link');\n link.id = 'an-fontawesome-css';\n link.rel = 'stylesheet';\n link.href = 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css';\n link.crossOrigin = 'anonymous';\n link.referrerPolicy = 'no-referrer';\n document.head.appendChild(link);\n }\n\n destroy() {\n this._disposers.forEach((d) => d());\n this._disposers = [];\n if (this._dialog && this._dialog.parentNode) {\n this._dialog.parentNode.removeChild(this._dialog);\n }\n this._dialog = null;\n }\n\n // ---------------------------------------------------------------------------\n // Public API\n // ---------------------------------------------------------------------------\n\n show() {\n if (!this._dialog) {\n this._dialog = this._buildDialog();\n document.body.appendChild(this._dialog);\n }\n withSavedRange((range) => {\n this._savedRange = range;\n });\n this._selectedIcon = null;\n this._activeCat = 'all';\n this._searchInput.value = '';\n // Clear previously selected icon highlight and disable Insert button\n this._grid.querySelectorAll('.an-icon-cell.active').forEach((c) => c.classList.remove('active'));\n this._insertBtn.setAttribute('disabled', '');\n this._updateCatTabs();\n this._filterIcons('', 'all');\n this._updatePreview(null);\n this._open();\n }\n\n // ---------------------------------------------------------------------------\n // Build dialog\n // ---------------------------------------------------------------------------\n\n _buildDialog() {\n const overlay = createElement('div', {\n class: 'an-dialog-overlay',\n role: 'dialog',\n 'aria-modal': 'true',\n 'aria-label': 'Insert FA icon',\n });\n\n const box = createElement('div', { class: 'an-dialog-box an-icon-box' });\n\n // Title row\n const titleRow = createElement('div', { class: 'an-icon-title-row' });\n const title = createElement('h3', { class: 'an-dialog-title' });\n title.textContent = 'Insert FA Icon';\n const closeBtn = createElement('button', { type: 'button', class: 'an-icon-close', 'aria-label': 'Close' });\n closeBtn.innerHTML = '×';\n titleRow.append(title, closeBtn);\n\n // Search\n const searchInput = createElement('input', {\n type: 'search',\n class: 'an-input an-icon-search',\n placeholder: 'Search icons…',\n autocomplete: 'off',\n });\n this._searchInput = searchInput;\n\n // Category tabs\n const catBar = createElement('div', { class: 'an-icon-cats' });\n const allTab = createElement('button', { type: 'button', class: 'an-icon-cat active', 'data-cat': 'all' });\n allTab.textContent = 'All';\n catBar.appendChild(allTab);\n ICON_CATEGORIES.forEach(({ id, label }) => {\n const tab = createElement('button', { type: 'button', class: 'an-icon-cat', 'data-cat': id });\n tab.textContent = label;\n catBar.appendChild(tab);\n });\n this._catBar = catBar;\n\n // Icon grid\n const grid = createElement('div', { class: 'an-icon-grid' });\n ICON_LIST.forEach(([name, cat]) => {\n const cell = createElement('button', { type: 'button', class: 'an-icon-cell', 'data-name': name, 'data-cat': cat, title: name });\n const icon = createElement('i', { class: 'fa-solid fa-' + name, 'aria-hidden': 'true' });\n const label = createElement('span');\n label.textContent = name;\n cell.append(icon, label);\n grid.appendChild(cell);\n });\n this._grid = grid;\n\n // Options row: style + size + color\n const optRow = createElement('div', { class: 'an-icon-options' });\n\n const styleLabel = createElement('label', { class: 'an-label' });\n styleLabel.textContent = 'Style';\n const styleSelect = createElement('select', { class: 'an-input an-icon-option-select' });\n [['fa-solid', 'Solid'], ['fa-regular', 'Regular'], ['fa-light', 'Light (Pro)']].forEach(([v, t]) => {\n const opt = createElement('option', { value: v });\n opt.textContent = t;\n styleSelect.appendChild(opt);\n });\n styleSelect.value = 'fa-solid';\n this._styleSelect = styleSelect;\n\n const sizeLabel = createElement('label', { class: 'an-label' });\n sizeLabel.textContent = 'Size';\n const sizeSelect = createElement('select', { class: 'an-input an-icon-option-select' });\n [['', 'Inherit'], ['0.75em', '0.75em'], ['1em', '1em'], ['1.25em', '1.25em'], ['1.5em', '1.5em'], ['2em', '2em'], ['3em', '3em']].forEach(([v, t]) => {\n const opt = createElement('option', { value: v });\n if (v === '1em') opt.selected = true;\n opt.textContent = t;\n sizeSelect.appendChild(opt);\n });\n this._sizeSelect = sizeSelect;\n\n const colorLabel = createElement('label', { class: 'an-label' });\n colorLabel.textContent = 'Color';\n const colorInput = createElement('input', { type: 'color', class: 'an-icon-color', value: '#000000' });\n this._colorInput = colorInput;\n\n const useColorLabel = createElement('label', { class: 'an-label an-label-inline an-icon-use-color' });\n const useColorCb = createElement('input', { type: 'checkbox', checked: '' });\n this._useColorCb = useColorCb;\n useColorLabel.append(useColorCb, document.createTextNode(' Use color'));\n\n optRow.append(styleLabel, styleSelect, sizeLabel, sizeSelect, colorLabel, colorInput, useColorLabel);\n\n // Preview\n const preview = createElement('div', { class: 'an-icon-preview' });\n const previewHint = createElement('span', { class: 'an-icon-preview-hint' });\n previewHint.textContent = 'Select an icon';\n preview.appendChild(previewHint);\n this._preview = preview;\n\n // Actions\n const btnRow = createElement('div', { class: 'an-dialog-actions' });\n const insertBtn = createElement('button', { type: 'button', class: 'an-btn an-btn-primary', disabled: '' });\n insertBtn.textContent = 'Insert FA Icon';\n const cancelBtn = createElement('button', { type: 'button', class: 'an-btn' });\n cancelBtn.textContent = 'Cancel';\n btnRow.append(insertBtn, cancelBtn);\n this._insertBtn = insertBtn;\n\n box.append(titleRow, searchInput, catBar, grid, optRow, preview, btnRow);\n overlay.appendChild(box);\n\n // -------------------------------------------------------------------------\n // Events\n // -------------------------------------------------------------------------\n\n const d1 = on(closeBtn, 'click', () => this._close());\n const d2 = on(cancelBtn, 'click', () => this._close());\n const d3 = on(insertBtn, 'click', () => this._onInsert());\n const d4 = on(overlay, 'click', (e) => { if (e.target === overlay) this._close(); });\n const d5 = on(searchInput, 'input', () => this._filterIcons(searchInput.value, this._activeCat));\n const d6 = on(catBar, 'click', (e) => {\n const tab = e.target.closest('[data-cat]');\n if (tab) {\n this._activeCat = tab.dataset.cat;\n this._updateCatTabs();\n this._filterIcons(this._searchInput.value, this._activeCat);\n }\n });\n const d7 = on(grid, 'click', (e) => {\n const cell = e.target.closest('.an-icon-cell');\n if (cell) this._selectIcon(cell.dataset.name);\n });\n const d8 = on(styleSelect, 'change', () => this._updatePreview(this._selectedIcon));\n const d9 = on(sizeSelect, 'change', () => this._updatePreview(this._selectedIcon));\n const d10 = on(colorInput, 'input', () => this._updatePreview(this._selectedIcon));\n const d11 = on(useColorCb, 'change', () => this._updatePreview(this._selectedIcon));\n\n this._disposers.push(d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11);\n\n return overlay;\n }\n\n // ---------------------------------------------------------------------------\n // Filter / select\n // ---------------------------------------------------------------------------\n\n _updateCatTabs() {\n this._catBar.querySelectorAll('.an-icon-cat').forEach((tab) => {\n tab.classList.toggle('active', tab.dataset.cat === this._activeCat);\n });\n }\n\n _filterIcons(query, cat) {\n const q = (query || '').trim().toLowerCase();\n let visibleCount = 0;\n this._grid.querySelectorAll('.an-icon-cell').forEach((cell) => {\n const name = cell.dataset.name;\n const cellCat = cell.dataset.cat;\n const matchesCat = !cat || cat === 'all' || cellCat === cat;\n const matchesQuery = !q || name.includes(q);\n const visible = matchesCat && matchesQuery;\n cell.style.display = visible ? '' : 'none';\n if (visible) visibleCount++;\n });\n // Show empty state if needed\n let empty = this._grid.querySelector('.an-icon-empty');\n if (!empty) {\n empty = createElement('div', { class: 'an-icon-empty' });\n empty.textContent = 'No icons found';\n this._grid.appendChild(empty);\n }\n empty.style.display = visibleCount > 0 ? 'none' : '';\n }\n\n _selectIcon(name) {\n this._selectedIcon = name;\n // Highlight selected cell\n this._grid.querySelectorAll('.an-icon-cell').forEach((cell) => {\n cell.classList.toggle('active', cell.dataset.name === name);\n });\n // Enable insert button\n this._insertBtn.removeAttribute('disabled');\n // Update preview\n this._updatePreview(name);\n }\n\n _updatePreview(name) {\n if (!this._preview) return;\n if (!name) {\n this._preview.innerHTML = '<span class=\"an-icon-preview-hint\">Select an icon</span>';\n return;\n }\n const cls = (this._styleSelect && this._styleSelect.value) || 'fa-solid';\n const size = (this._sizeSelect && this._sizeSelect.value) || '1em';\n const useColor = this._useColorCb ? this._useColorCb.checked : false;\n const color = (useColor && this._colorInput) ? this._colorInput.value : '';\n const styleAttr = [\n size ? `font-size:${size}` : '',\n color ? `color:${color}` : '',\n ].filter(Boolean).join(';');\n // Use innerHTML — atomic, no partial-update risk\n this._preview.innerHTML =\n `<i class=\"${cls} fa-${name}\" aria-hidden=\"true\"${\n styleAttr ? ` style=\"${styleAttr}\"` : ''\n }></i>` +\n `<div class=\"an-icon-preview-name\">${cls} fa-${name}</div>`;\n }\n\n // ---------------------------------------------------------------------------\n // Insert\n // ---------------------------------------------------------------------------\n\n _onInsert() {\n if (!this._selectedIcon) return;\n\n const cls = (this._styleSelect && this._styleSelect.value) || 'fa-solid';\n const size = (this._sizeSelect && this._sizeSelect.value) || '';\n const useColor = this._useColorCb ? this._useColorCb.checked : false;\n const color = (useColor && this._colorInput) ? this._colorInput.value : '';\n const styleParts = [\n size ? `font-size:${size}` : '',\n color ? `color:${color}` : '',\n ].filter(Boolean);\n\n const iconEl = document.createElement('i');\n iconEl.className = `${cls} fa-${this._selectedIcon}`;\n iconEl.setAttribute('aria-hidden', 'true');\n iconEl.setAttribute('contenteditable', 'false');\n if (styleParts.length) iconEl.setAttribute('style', styleParts.join(';'));\n\n const savedRange = this._savedRange;\n const editable = this.context.layoutInfo.editable;\n\n // ---- Same ordering as ImageDialog (the proven pattern) ----\n // 1. Restore the selection while the dialog is still mounted\n if (savedRange) savedRange.select();\n\n // 2. Get the now-live range from the selection\n const sel = window.getSelection();\n let range = sel && sel.rangeCount > 0 ? sel.getRangeAt(0) : null;\n if (!range) {\n range = document.createRange();\n range.selectNodeContents(editable);\n range.collapse(false);\n }\n\n // 3. Insert the <i> node directly — never via execCommand/insertHTML\n // (execCommand leaves the caret inside the inserted element)\n range.deleteContents();\n range.insertNode(iconEl);\n\n // 4. Place cursor after the icon.\n // Keep a text anchor (\\u200B) after the icon so ArrowLeft/ArrowRight and\n // caret placement at end-of-line stay stable across browsers.\n let caretTextNode = iconEl.nextSibling;\n if (!caretTextNode || caretTextNode.nodeType !== Node.TEXT_NODE) {\n caretTextNode = document.createTextNode('\\u200B');\n iconEl.parentNode.insertBefore(caretTextNode, iconEl.nextSibling);\n } else if (!caretTextNode.textContent) {\n // Split text-node insertions can leave an empty text node after icon.\n // Fill it with ZWS so caret-after-icon remains stable at end-of-line.\n caretTextNode.textContent = '\\u200B';\n }\n\n const caretOffset = ((caretTextNode.textContent || '').startsWith('\\u200B')) ? 1 : 0;\n const caretRange = document.createRange();\n caretRange.setStart(caretTextNode, Math.min(caretOffset, caretTextNode.textContent.length));\n caretRange.collapse(true);\n if (sel) {\n sel.removeAllRanges();\n sel.addRange(caretRange);\n }\n\n // 5. Close dialog last — same as ImageDialog\n this._close();\n\n // 6. Restore editor focus (needed for toolbar refresh via afterCommand)\n editable.focus();\n if (sel) {\n // Some browsers reset selection when refocusing editable after closing dialog.\n sel.removeAllRanges();\n sel.addRange(caretRange);\n }\n this.context.invoke('editor.afterCommand');\n }\n\n // ---------------------------------------------------------------------------\n // Open / Close\n // ---------------------------------------------------------------------------\n\n _open() {\n if (this._dialog) {\n this._dialog.style.display = 'flex';\n this._removeTrap = trapFocus(this._dialog, () => this._close());\n setTimeout(() => this._searchInput && this._searchInput.focus(), 50);\n }\n }\n\n _close() {\n if (this._dialog) this._dialog.style.display = 'none';\n if (this._removeTrap) { this._removeTrap(); this._removeTrap = null; }\n this._savedRange = null;\n this._selectedIcon = null;\n }\n}\n","// ContextMenu.js - Right-click context menu for editor actions\nimport { createElement, on } from '../core/dom.js';\nimport { sanitiseHTML } from '../core/sanitise.js';\n\n// SVG icon map — 16×16 Heroicons-style paths\nconst ICONS = {\n undo: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M3 7v6h6\"/><path d=\"M21 17a9 9 0 0 0-9-9 9 9 0 0 0-6 2.3L3 13\"/></svg>`,\n redo: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M21 7v6h-6\"/><path d=\"M3 17a9 9 0 0 1 9-9 9 9 0 0 1 6 2.3L21 13\"/></svg>`,\n cut: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"6\" cy=\"20\" r=\"3\"/><circle cx=\"6\" cy=\"4\" r=\"3\"/><line x1=\"19\" y1=\"5\" x2=\"6\" y2=\"19\"/><line x1=\"19\" y1=\"19\" x2=\"13.5\" y2=\"13.5\"/></svg>`,\n copy: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\"/><path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\"/></svg>`,\n paste: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2\"/><rect x=\"8\" y=\"2\" width=\"8\" height=\"4\" rx=\"1\"/></svg>`,\n bold: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M6 4h8a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z\"/><path d=\"M6 12h9a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z\"/></svg>`,\n italic: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"19\" y1=\"4\" x2=\"10\" y2=\"4\"/><line x1=\"14\" y1=\"20\" x2=\"5\" y2=\"20\"/><line x1=\"15\" y1=\"4\" x2=\"9\" y2=\"20\"/></svg>`,\n underline: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M6 3v7a6 6 0 0 0 6 6 6 6 0 0 0 6-6V3\"/><line x1=\"4\" y1=\"21\" x2=\"20\" y2=\"21\"/></svg>`,\n link: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71\"/><path d=\"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71\"/></svg>`,\n image: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\"/><circle cx=\"8.5\" cy=\"8.5\" r=\"1.5\"/><polyline points=\"21 15 16 10 5 21\"/></svg>`,\n video: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polygon points=\"23 7 16 12 23 17 23 7\"/><rect x=\"1\" y=\"5\" width=\"15\" height=\"14\" rx=\"2\"/></svg>`,\n // Image format operations\n floatLeft: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"2\" y=\"4\" width=\"8\" height=\"8\" rx=\"1\"/><line x1=\"12\" y1=\"6\" x2=\"22\" y2=\"6\"/><line x1=\"12\" y1=\"9\" x2=\"22\" y2=\"9\"/><line x1=\"12\" y1=\"12\" x2=\"22\" y2=\"12\"/><line x1=\"2\" y1=\"16\" x2=\"22\" y2=\"16\"/><line x1=\"2\" y1=\"20\" x2=\"18\" y2=\"20\"/></svg>`,\n floatRight: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"14\" y=\"4\" width=\"8\" height=\"8\" rx=\"1\"/><line x1=\"2\" y1=\"6\" x2=\"12\" y2=\"6\"/><line x1=\"2\" y1=\"9\" x2=\"12\" y2=\"9\"/><line x1=\"2\" y1=\"12\" x2=\"12\" y2=\"12\"/><line x1=\"2\" y1=\"16\" x2=\"22\" y2=\"16\"/><line x1=\"2\" y1=\"20\" x2=\"18\" y2=\"20\"/></svg>`,\n floatNone: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"3\" width=\"8\" height=\"8\" rx=\"1\"/><line x1=\"3\" y1=\"15\" x2=\"21\" y2=\"15\"/><line x1=\"3\" y1=\"19\" x2=\"17\" y2=\"19\"/></svg>`,\n originalSize:`<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"15 3 21 3 21 9\"/><polyline points=\"9 21 3 21 3 15\"/><line x1=\"21\" y1=\"3\" x2=\"14\" y2=\"10\"/><line x1=\"3\" y1=\"21\" x2=\"10\" y2=\"14\"/></svg>`,\n deleteImg: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"3 6 5 6 21 6\"/><path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2\"/></svg>`,\n // Video format operations\n videoAlign: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polygon points=\"23 7 16 12 23 17 23 7\"/><rect x=\"1\" y=\"5\" width=\"15\" height=\"14\" rx=\"2\"/></svg>`,\n deleteVideo: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"3 6 5 6 21 6\"/><path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2\"/></svg>`,\n // Format painter operations\n copyFormat: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7\"/><path d=\"M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z\"/></svg>`,\n pasteFormat: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2\"/><rect x=\"8\" y=\"2\" width=\"8\" height=\"4\" rx=\"1\"/><path d=\"m9 14 2 2 4-4\"/></svg>`,\n removeFormat:`<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"m7 21-4.3-4.3c-1-1-1-2.5 0-3.4l9.6-9.6c1-1 2.5-1 3.4 0l5.6 5.6c1 1 1 2.5 0 3.4L13 21\"/><path d=\"M22 21H7\"/><path d=\"m5 11 9 9\"/></svg>`,\n // Table\n table: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"1\"/><line x1=\"3\" y1=\"9\" x2=\"21\" y2=\"9\"/><line x1=\"3\" y1=\"15\" x2=\"21\" y2=\"15\"/><line x1=\"9\" y1=\"3\" x2=\"9\" y2=\"21\"/><line x1=\"15\" y1=\"3\" x2=\"15\" y2=\"21\"/></svg>`,\n};\n\nconst defaultItems = [\n { name: 'undo', label: 'Undo', icon: ICONS.undo, action: (ctx) => ctx.invoke('editor.undo') },\n { name: 'redo', label: 'Redo', icon: ICONS.redo, action: (ctx) => ctx.invoke('editor.redo') },\n { separator: true },\n { name: 'cut', label: 'Cut', icon: ICONS.cut, action: () => document.execCommand('cut') },\n { name: 'copy', label: 'Copy', icon: ICONS.copy, action: () => document.execCommand('copy') },\n { name: 'paste', label: 'Paste', icon: ICONS.paste, action: (ctx) => {\n if (!navigator.clipboard) return;\n const editable = ctx.layoutInfo && ctx.layoutInfo.editable;\n if (!editable) return;\n // Prefer read() to get rich HTML; fall back to readText() for plain text\n const doInsert = (html, text) => {\n editable.focus();\n if (html) {\n const clean = sanitiseHTML(html);\n document.execCommand('insertHTML', false, clean);\n } else if (text) {\n document.execCommand('insertText', false, text);\n }\n ctx.invoke('editor.afterCommand');\n };\n if (typeof navigator.clipboard.read === 'function') {\n navigator.clipboard.read().then((items) => {\n for (const item of items) {\n if (item.types.includes('text/html')) {\n item.getType('text/html').then((blob) => blob.text()).then((html) => doInsert(html, null));\n return;\n }\n }\n // No HTML item — fall through to plain text\n navigator.clipboard.readText().then((text) => doInsert(null, text)).catch(() => {});\n }).catch(() => {\n // read() denied → try readText() as fallback\n navigator.clipboard.readText().then((text) => doInsert(null, text)).catch(() => {});\n });\n } else if (typeof navigator.clipboard.readText === 'function') {\n navigator.clipboard.readText().then((text) => doInsert(null, text)).catch(() => {});\n }\n } },\n { separator: true },\n { name: 'bold', label: 'Bold', icon: ICONS.bold, action: (ctx) => ctx.invoke('editor.bold') },\n { name: 'italic', label: 'Italic', icon: ICONS.italic, action: (ctx) => ctx.invoke('editor.italic') },\n { name: 'underline', label: 'Underline', icon: ICONS.underline, action: (ctx) => ctx.invoke('editor.underline') },\n { separator: true },\n { name: 'copyFormat', label: 'Copy Format', icon: ICONS.copyFormat, action: (ctx) => ctx.invoke('contextMenu.copyFormat') },\n { name: 'pasteFormat', label: 'Paste Format', icon: ICONS.pasteFormat, action: (ctx) => ctx.invoke('contextMenu.pasteFormat'), disabled: (ctx) => !ctx.invoke('contextMenu.hasCopiedFormat') },\n { name: 'removeFormat', label: 'Remove Format', icon: ICONS.removeFormat, action: (ctx) => ctx.invoke('contextMenu.removeFormat') },\n { separator: true },\n { name: 'link', label: 'Insert Link', icon: ICONS.link, action: (ctx) => ctx.invoke('linkDialog.show') },\n { name: 'image', label: 'Insert Image', icon: ICONS.image, action: (ctx) => ctx.invoke('imageDialog.show') },\n { name: 'video', label: 'Insert Video', icon: ICONS.video, action: (ctx) => ctx.invoke('videoDialog.show') },\n { name: 'table', label: 'Insert Table', icon: ICONS.table, tableGrid: true },\n];\n\nexport class ContextMenu {\n /** @param {import('../Context.js').Context} context */\n constructor(context) {\n this.context = context;\n this.options = context.options || {};\n this._items = (this.options.contextMenu && this.options.contextMenu.items) || defaultItems;\n this.el = null;\n this._disposers = [];\n this._menuDisposers = []; // disposers for dynamically-rendered menu buttons\n this._lastX = 0;\n this._lastY = 0;\n this._copiedFormat = null;\n this._savedRange = null;\n }\n\n initialize() {\n this.el = createElement('div', { class: 'an-contextmenu', role: 'menu', 'aria-hidden': 'true' });\n this.el.style.display = 'none';\n document.body.appendChild(this.el);\n\n this._renderItems(this._items);\n\n const editable = this.context.layoutInfo && this.context.layoutInfo.editable;\n if (editable) {\n this._disposers.push(on(editable, 'contextmenu', (e) => this._onContextMenu(e)));\n }\n\n this._disposers.push(on(document, 'click', (e) => this._maybeHide(e)));\n this._disposers.push(on(document, 'keydown', (e) => { if (e.key === 'Escape') this.hide(); }));\n this._disposers.push(on(window, 'scroll', () => this.hide(), { passive: true }));\n\n return this;\n }\n\n destroy() {\n this._menuDisposers.forEach((d) => { try { d(); } catch (e) {} });\n this._menuDisposers = [];\n this._disposers.forEach((d) => { try { d(); } catch (e) {} });\n this._disposers = [];\n if (this.el && this.el.parentNode) this.el.parentNode.removeChild(this.el);\n this.el = null;\n }\n\n _renderItems(items) {\n // Clean up previously registered per-item listeners\n this._menuDisposers.forEach((d) => d());\n this._menuDisposers = [];\n\n if (!this.el) return;\n this.el.innerHTML = '';\n\n items.forEach((it) => {\n if (it.separator || it.sep) {\n this.el.appendChild(createElement('div', { class: 'an-context-sep' }));\n return;\n }\n\n // Back-navigation header\n if (it.back) {\n const backBtn = createElement('button', { type: 'button', class: 'an-context-back' });\n const iconSpan = createElement('span', { class: 'an-context-icon', 'aria-hidden': 'true' });\n iconSpan.innerHTML = ICONS.back;\n backBtn.appendChild(iconSpan);\n backBtn.appendChild(createElement('span', { class: 'an-context-label' }, [it.label || 'Back']));\n const off = on(backBtn, 'click', (e) => {\n e.stopPropagation();\n this._renderItems(it.navigate());\n this._reposition();\n });\n this._menuDisposers.push(off);\n this.el.appendChild(backBtn);\n return;\n }\n\n // Submenu-navigate item (shows ▶ chevron, re-renders without closing)\n if (it.navigate) {\n const btn = createElement('button', { type: 'button', class: 'an-context-item an-context-submenu', 'data-name': it.name || '' });\n if (it.icon) {\n const iconSpan = createElement('span', { class: 'an-context-icon', 'aria-hidden': 'true' });\n iconSpan.innerHTML = it.icon;\n btn.appendChild(iconSpan);\n }\n btn.appendChild(createElement('span', { class: 'an-context-label' }, [it.label || it.name]));\n const chevron = createElement('span', { class: 'an-context-chevron', 'aria-hidden': 'true' });\n chevron.innerHTML = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"9 18 15 12 9 6\"/></svg>`;\n btn.appendChild(chevron);\n const off = on(btn, 'click', (e) => {\n e.stopPropagation();\n this._renderItems(it.navigate());\n this._reposition();\n });\n this._menuDisposers.push(off);\n this.el.appendChild(btn);\n return;\n }\n\n // Table grid picker item — expands an inline grid panel when clicked\n if (it.tableGrid) {\n const GRID_ROWS = 8, GRID_COLS = 8;\n const wrapper = createElement('div', { class: 'an-context-table-wrap' });\n\n const headerBtn = createElement('button', { type: 'button', class: 'an-context-item an-context-submenu', 'data-name': it.name || 'table' });\n if (it.icon) {\n const iconSpan = createElement('span', { class: 'an-context-icon', 'aria-hidden': 'true' });\n iconSpan.innerHTML = it.icon;\n headerBtn.appendChild(iconSpan);\n }\n headerBtn.appendChild(createElement('span', { class: 'an-context-label' }, [it.label || 'Insert Table']));\n const chevron = createElement('span', { class: 'an-context-chevron', 'aria-hidden': 'true' });\n chevron.innerHTML = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"9 18 15 12 9 6\"/></svg>`;\n headerBtn.appendChild(chevron);\n\n const panel = createElement('div', { class: 'an-context-table-grid-panel' });\n panel.style.display = 'none';\n\n const gridEl = createElement('div', { class: 'an-table-grid' });\n gridEl.style.gridTemplateColumns = `repeat(${GRID_COLS}, 16px)`;\n const labelEl = createElement('div', { class: 'an-table-label' });\n labelEl.textContent = 'Insert Table';\n\n const cells = [];\n for (let r = 1; r <= GRID_ROWS; r++) {\n for (let c = 1; c <= GRID_COLS; c++) {\n const cell = createElement('div', { class: 'an-table-cell', 'data-row': String(r), 'data-col': String(c) });\n cell.style.width = '16px';\n cell.style.height = '16px';\n cells.push(cell);\n gridEl.appendChild(cell);\n }\n }\n\n const setHighlight = (rows, cols) => {\n cells.forEach((cell) => {\n cell.classList.toggle('active', +cell.dataset.row <= rows && +cell.dataset.col <= cols);\n });\n labelEl.textContent = (rows && cols) ? `${cols} × ${rows}` : 'Insert Table';\n };\n\n panel.appendChild(gridEl);\n panel.appendChild(labelEl);\n\n let expanded = false;\n const offHeader = on(headerBtn, 'click', (e) => {\n e.stopPropagation();\n expanded = !expanded;\n panel.style.display = expanded ? '' : 'none';\n chevron.style.transform = expanded ? 'rotate(90deg)' : '';\n this._reposition();\n });\n this._menuDisposers.push(offHeader);\n\n const offMove = on(gridEl, 'mousemove', (e) => {\n const cell = e.target.closest('[data-row]');\n if (!cell) return;\n setHighlight(+cell.dataset.row, +cell.dataset.col);\n });\n const offLeave = on(gridEl, 'mouseleave', () => setHighlight(0, 0));\n const offClick = on(gridEl, 'click', (e) => {\n const cell = e.target.closest('[data-row]');\n if (!cell) return;\n const rows = +cell.dataset.row;\n const cols = +cell.dataset.col;\n const editable = this.context.layoutInfo && this.context.layoutInfo.editable;\n if (editable && this._savedRange) {\n editable.focus();\n const sel = window.getSelection();\n sel.removeAllRanges();\n sel.addRange(this._savedRange.cloneRange());\n }\n this.hide();\n this.context.invoke('editor.insertTable', cols, rows);\n });\n this._menuDisposers.push(offMove, offLeave, offClick);\n\n wrapper.appendChild(headerBtn);\n wrapper.appendChild(panel);\n this.el.appendChild(wrapper);\n return;\n }\n\n // Regular item\n const btn = createElement('button', { type: 'button', class: 'an-context-item', 'data-name': it.name || '' });\n if (typeof it.disabled === 'function' ? it.disabled(this.context) : !!it.disabled) btn.disabled = true;\n if (it.icon) {\n const iconSpan = createElement('span', { class: 'an-context-icon', 'aria-hidden': 'true' });\n iconSpan.innerHTML = it.icon;\n btn.appendChild(iconSpan);\n }\n btn.appendChild(createElement('span', { class: 'an-context-label' }, [it.label || it.name]));\n const off = on(btn, 'click', (e) => {\n e.stopPropagation();\n this.hide();\n try { it.action(this.context); } catch (err) { console.error(err); }\n });\n this._menuDisposers.push(off);\n this.el.appendChild(btn);\n });\n }\n\n _onContextMenu(event) {\n const editable = this.context.layoutInfo && this.context.layoutInfo.editable;\n if (!editable) return;\n if (!editable.contains(event.target)) return;\n event.preventDefault();\n this._lastX = event.clientX;\n this._lastY = event.clientY;\n const winSel = window.getSelection();\n this._savedRange = (winSel && winSel.rangeCount > 0) ? winSel.getRangeAt(0).cloneRange() : null;\n this._renderItems(this._items);\n this.showAt(event.clientX, event.clientY);\n }\n\n _maybeHide(event) {\n if (!this.el) return;\n if (!this.el.contains(event.target)) this.hide();\n }\n\n showAt(x, y) {\n if (!this.el) return;\n this.el.style.display = 'block';\n this._reposition(x, y);\n this.el.setAttribute('aria-hidden', 'false');\n }\n\n _reposition(x, y) {\n if (!this.el) return;\n const rx = x !== undefined ? x : this._lastX;\n const ry = y !== undefined ? y : this._lastY;\n const rect = this.el.getBoundingClientRect();\n let left = rx;\n let top = ry;\n if (left + rect.width > window.innerWidth) left = window.innerWidth - rect.width - 8;\n if (top + rect.height > window.innerHeight) top = window.innerHeight - rect.height - 8;\n this.el.style.left = `${left}px`;\n this.el.style.top = `${top}px`;\n }\n\n hide() {\n if (!this.el) return;\n this.el.style.display = 'none';\n this.el.setAttribute('aria-hidden', 'true');\n }\n\n // ---------------------------------------------------------------------------\n // Format operations (Copy Format / Paste Format / Remove Format)\n // ---------------------------------------------------------------------------\n\n /** Returns true if a format has been copied — used to disable Paste Format. */\n hasCopiedFormat() { return !!this._copiedFormat; }\n\n /** Snapshot inline styles at the selection anchor node. */\n copyFormat() {\n const range = this._savedRange;\n if (!range) return;\n const editable = this.context.layoutInfo && this.context.layoutInfo.editable;\n let node = range.startContainer;\n if (node.nodeType === Node.TEXT_NODE) node = node.parentElement;\n if (!node || !editable || !editable.contains(node)) return;\n\n // Walk up to collect explicitly-set inline properties from the nearest styled ancestor\n const cs = window.getComputedStyle(node);\n\n // Detect if an explicit font-family / font-size is set on an element (not just inherited)\n const explicitFontFamily = this._findExplicitStyle(node, editable, 'fontFamily');\n const explicitFontSize = this._findExplicitStyle(node, editable, 'fontSize');\n\n this._copiedFormat = {\n bold: parseInt(cs.fontWeight, 10) >= 700,\n italic: cs.fontStyle === 'italic' || cs.fontStyle === 'oblique',\n underline: (cs.textDecorationLine || '').includes('underline'),\n strikethrough: (cs.textDecorationLine || '').includes('line-through'),\n fontFamily: explicitFontFamily,\n fontSize: explicitFontSize,\n color: this._isDefaultColor(cs.color) ? null : cs.color,\n backgroundColor: cs.backgroundColor,\n };\n }\n\n /** Walk up the tree looking for a property explicitly set in inline style. Returns null if only inherited. */\n _findExplicitStyle(node, boundary, prop) {\n let el = node;\n while (el && el !== boundary && el !== document.body) {\n if (el.style && el.style[prop]) return el.style[prop];\n // also check font element attributes\n if (el.nodeName === 'FONT') {\n if (prop === 'fontFamily' && el.getAttribute('face')) return el.getAttribute('face');\n if (prop === 'fontSize' && el.getAttribute('size')) {\n // font size attribute is 1-7; skip these since we need px\n return null;\n }\n }\n el = el.parentElement;\n }\n return null;\n }\n\n /** Checks if a computed color looks like the default browser text color (black). */\n _isDefaultColor(color) {\n return !color || color === 'rgb(0, 0, 0)' || color === 'rgba(0, 0, 0, 0)' || color === 'transparent';\n }\n\n /** Apply the most-recently copied format to the saved selection. */\n pasteFormat() {\n if (!this._copiedFormat || !this._savedRange) return;\n const fmt = this._copiedFormat;\n const editable = this.context.layoutInfo && this.context.layoutInfo.editable;\n if (!editable) return;\n\n // CRITICAL: focus the editable FIRST, then restore selection.\n // Calling focus() after addRange() can wipe the selection in Chrome/Firefox.\n editable.focus();\n const sel = window.getSelection();\n sel.removeAllRanges();\n sel.addRange(this._savedRange.cloneRange());\n\n // Strip existing inline formatting so we start from a clean state.\n // After removeFormat, bold/italic/underline/strikethrough are guaranteed off.\n document.execCommand('removeFormat');\n\n // Apply each format positively — no toggle-check needed after removeFormat.\n if (fmt.bold) document.execCommand('bold');\n if (fmt.italic) document.execCommand('italic');\n if (fmt.underline) document.execCommand('underline');\n if (fmt.strikethrough) document.execCommand('strikeThrough');\n\n if (fmt.color) document.execCommand('foreColor', false, fmt.color);\n\n const isTransparent = (c) => !c || c === 'rgba(0, 0, 0, 0)' || c === 'transparent';\n if (!isTransparent(fmt.backgroundColor)) {\n document.execCommand('hiliteColor', false, fmt.backgroundColor);\n }\n\n // Font family — apply BEFORE font-size DOM manipulation so the selection is still intact.\n if (fmt.fontFamily) {\n document.execCommand('fontName', false, fmt.fontFamily);\n }\n\n // Font size — use a unique data-marker to avoid touching pre-existing font[size=\"7\"] nodes.\n if (fmt.fontSize) {\n const marker = `fs-${Date.now()}`;\n // Snapshot pre-existing font[size=\"7\"] BEFORE execCommand so we don't accidentally\n // replace nodes that were already in the document (the comment below was aspirational\n // but the original code never actually excluded them — this Set approach is the fix).\n const preExisting = new Set(editable.querySelectorAll('font[size=\"7\"]'));\n document.execCommand('fontSize', false, '7');\n // Mark only the NEWLY created font[size=\"7\"] elements.\n editable.querySelectorAll('font[size=\"7\"]').forEach((el) => {\n if (!preExisting.has(el)) el.setAttribute('data-an-tmp', marker);\n });\n editable.querySelectorAll(`[data-an-tmp=\"${marker}\"]`).forEach((el) => {\n const span = document.createElement('span');\n span.style.fontSize = fmt.fontSize;\n el.parentNode.insertBefore(span, el);\n while (el.firstChild) span.appendChild(el.firstChild);\n el.parentNode.removeChild(el);\n });\n }\n\n this.context.invoke('editor.afterCommand');\n }\n\n /** Strip all inline formatting from the saved selection. */\n removeFormat() {\n if (!this._savedRange) return;\n const editable = this.context.layoutInfo && this.context.layoutInfo.editable;\n if (!editable) return;\n\n editable.focus();\n const sel = window.getSelection();\n sel.removeAllRanges();\n sel.addRange(this._savedRange.cloneRange());\n\n document.execCommand('removeFormat');\n\n const range = sel.getRangeAt(0);\n const root = range.commonAncestorContainer;\n const rootEl = root.nodeType === Node.TEXT_NODE ? root.parentElement : root;\n const iter = document.createNodeIterator(rootEl, NodeFilter.SHOW_ELEMENT);\n let el;\n while ((el = iter.nextNode())) {\n if (!editable.contains(el) || el === editable) continue;\n try { if (range.intersectsNode(el)) el.removeAttribute('style'); } catch { /* ignore */ }\n }\n\n this.context.invoke('editor.afterCommand');\n }\n}\n\nexport default ContextMenu;\n","/**\n * ShortcutsDialog.js - Modal dialog listing all keyboard shortcuts.\n * Opened via the toolbar '?' button or Shift+? inside the editor.\n */\n\nimport { createElement, on, trapFocus } from '../core/dom.js';\n\nconst SHORTCUTS = [\n {\n category: 'Text Formatting',\n items: [\n { keys: 'Ctrl + B', action: 'Bold' },\n { keys: 'Ctrl + I', action: 'Italic' },\n { keys: 'Ctrl + U', action: 'Underline' },\n { keys: 'Ctrl + K', action: 'Insert / edit link' },\n ],\n },\n {\n category: 'History',\n items: [\n { keys: 'Ctrl + Z', action: 'Undo' },\n { keys: 'Ctrl + Y / Ctrl + Shift + Z', action: 'Redo' },\n ],\n },\n {\n category: 'Selection & Navigation',\n items: [\n { keys: 'Ctrl + A', action: 'Select all content' },\n { keys: 'Tab', action: 'Indent list item / insert spaces' },\n { keys: 'Shift + Tab', action: 'Outdent list item' },\n ],\n },\n {\n category: 'Clipboard',\n items: [\n { keys: 'Ctrl + Shift + V', action: 'Paste as plain text' },\n ],\n },\n {\n category: 'Find & Replace',\n items: [\n { keys: 'Ctrl + F', action: 'Find in document' },\n { keys: 'Ctrl + H', action: 'Find & Replace' },\n ],\n },\n {\n category: 'Editor',\n items: [\n { keys: 'Shift + ?', action: 'Show this keyboard shortcuts dialog' },\n ],\n },\n];\n\nexport class ShortcutsDialog {\n /** @param {import('../Context.js').Context} context */\n constructor(context) {\n this.context = context;\n this._dialog = null;\n this._closeBtn = null;\n this._disposers = [];\n }\n\n initialize() {\n this._dialog = this._buildDialog();\n document.body.appendChild(this._dialog);\n return this;\n }\n\n destroy() {\n this._disposers.forEach((d) => d());\n this._disposers = [];\n if (this._dialog && this._dialog.parentNode) {\n this._dialog.parentNode.removeChild(this._dialog);\n }\n this._dialog = null;\n }\n\n show() {\n if (this._dialog) {\n this._dialog.style.display = 'flex';\n this._removeTrap = trapFocus(this._dialog, () => this._close());\n setTimeout(() => this._closeBtn && this._closeBtn.focus(), 50);\n }\n }\n\n _close() {\n if (this._dialog) this._dialog.style.display = 'none';\n if (this._removeTrap) { this._removeTrap(); this._removeTrap = null; }\n }\n\n _buildDialog() {\n const overlay = createElement('div', {\n class: 'an-dialog-overlay',\n role: 'dialog',\n 'aria-modal': 'true',\n 'aria-label': 'Keyboard Shortcuts',\n });\n\n const box = createElement('div', { class: 'an-dialog-box an-shortcuts-box' });\n\n // Title row with close button\n const titleRow = createElement('div', { class: 'an-icon-title-row' });\n const title = createElement('h3', { class: 'an-dialog-title' });\n title.textContent = 'Keyboard Shortcuts';\n const closeBtn = createElement('button', {\n type: 'button',\n class: 'an-icon-close',\n 'aria-label': 'Close',\n });\n closeBtn.textContent = '×';\n this._closeBtn = closeBtn;\n titleRow.append(title, closeBtn);\n box.appendChild(titleRow);\n\n SHORTCUTS.forEach(({ category, items }) => {\n const catEl = createElement('div', { class: 'an-shortcuts-cat' });\n catEl.textContent = category;\n box.appendChild(catEl);\n\n const table = createElement('div', { class: 'an-shortcuts-table' });\n items.forEach(({ keys, action }) => {\n const row = createElement('div', { class: 'an-shortcuts-row' });\n const keyEl = createElement('span', { class: 'an-shortcuts-key' });\n keyEl.textContent = keys;\n const actEl = createElement('span', { class: 'an-shortcuts-action' });\n actEl.textContent = action;\n row.append(keyEl, actEl);\n table.appendChild(row);\n });\n box.appendChild(table);\n });\n\n overlay.appendChild(box);\n\n const d1 = on(closeBtn, 'click', () => this._close());\n const d2 = on(overlay, 'click', (e) => { if (e.target === overlay) this._close(); });\n this._disposers.push(d1, d2);\n\n return overlay;\n }\n}\n","/**\n * FindReplace.js - Find & Replace dialog\n *\n * Opens via Ctrl+F (find only) or Ctrl+H (find + replace).\n * Uses TreeWalker to locate text matches and wraps them with <mark> elements\n * for highlighting. Supports case-sensitive search, Prev/Next navigation and\n * single / replace-all replacement.\n */\n\nimport { createElement, on, trapFocus } from '../core/dom.js';\n\nexport class FindReplace {\n /** @param {import('../Context.js').Context} context */\n constructor(context) {\n this.context = context;\n\n /** @type {HTMLElement|null} */\n this._dialog = null;\n /** @type {HTMLInputElement|null} */\n this._findInput = null;\n /** @type {HTMLInputElement|null} */\n this._replaceInput = null;\n /** @type {HTMLInputElement|null} */\n this._caseCheckbox = null;\n /** @type {HTMLElement|null} */\n this._counterEl = null;\n /** @type {HTMLElement|null} */\n this._closeBtn = null;\n\n /** Live matches — each entry is { mark: HTMLElement } after highlighting */\n this._matches = [];\n this._currentIndex = -1;\n this._caseSensitive = false;\n /** @type {'find'|'replace'} */\n this._mode = 'find';\n\n this._disposers = [];\n this._removeTrap = null;\n this._focusTimer = null;\n }\n\n // ---------------------------------------------------------------------------\n // Lifecycle\n // ---------------------------------------------------------------------------\n\n initialize() {\n this._dialog = this._buildDialog();\n document.body.appendChild(this._dialog);\n return this;\n }\n\n destroy() {\n clearTimeout(this._focusTimer);\n this._focusTimer = null;\n this._clearHighlights();\n this._disposers.forEach((d) => d());\n this._disposers = [];\n if (this._dialog && this._dialog.parentNode) {\n this._dialog.parentNode.removeChild(this._dialog);\n }\n this._dialog = null;\n }\n\n // ---------------------------------------------------------------------------\n // Public API\n // ---------------------------------------------------------------------------\n\n /**\n * Opens the dialog in 'find' or 'replace' mode.\n * @param {'find'|'replace'} [mode='find']\n */\n show(mode = 'find') {\n this._mode = mode;\n this._updateMode();\n this._open();\n // Pre-select whatever was previously typed so the user can retype immediately\n clearTimeout(this._focusTimer);\n this._focusTimer = setTimeout(() => {\n if (this._findInput) {\n this._findInput.select();\n this._findInput.focus();\n }\n }, 50);\n }\n\n // ---------------------------------------------------------------------------\n // Open / close\n // ---------------------------------------------------------------------------\n\n _open() {\n if (!this._dialog) return;\n // If already visible, just focus the search input — don't re-trap.\n if (this._dialog.style.display === 'flex') {\n if (this._findInput) this._findInput.focus();\n return;\n }\n this._dialog.style.display = 'flex';\n // Release any previous trap before installing a new one.\n if (this._removeTrap) { this._removeTrap(); this._removeTrap = null; }\n this._removeTrap = trapFocus(this._dialog, () => this._close());\n }\n\n _close() {\n this._clearHighlights();\n if (this._dialog) this._dialog.style.display = 'none';\n if (this._removeTrap) { this._removeTrap(); this._removeTrap = null; }\n // Return focus to the editor\n this.context.invoke('editor.focus');\n }\n\n _updateMode() {\n if (!this._dialog) return;\n const replaceRow = this._dialog.querySelector('.an-fr-replace-row');\n const replaceActions = this._dialog.querySelector('.an-fr-replace-actions');\n const title = this._dialog.querySelector('.an-dialog-title');\n\n const isReplace = this._mode === 'replace';\n if (replaceRow) replaceRow.style.display = isReplace ? '' : 'none';\n if (replaceActions) replaceActions.style.display = isReplace ? '' : 'none';\n if (title) title.textContent = isReplace ? 'Find & Replace' : 'Find';\n }\n\n // ---------------------------------------------------------------------------\n // Build dialog\n // ---------------------------------------------------------------------------\n\n _buildDialog() {\n const overlay = createElement('div', {\n class: 'an-dialog-overlay an-fr-dialog',\n role: 'dialog',\n 'aria-modal': 'true',\n 'aria-label': 'Find and Replace',\n });\n const box = createElement('div', { class: 'an-dialog-box' });\n\n // ---- Title row ----\n const titleRow = createElement('div', { class: 'an-icon-title-row' });\n const title = createElement('h3', { class: 'an-dialog-title' });\n title.textContent = 'Find';\n const closeBtn = createElement('button', {\n type: 'button',\n class: 'an-icon-close',\n 'aria-label': 'Close',\n });\n closeBtn.textContent = '×';\n this._closeBtn = closeBtn;\n titleRow.append(title, closeBtn);\n box.appendChild(titleRow);\n\n // ---- Find row ----\n const findRow = createElement('div', { class: 'an-fr-find-row' });\n const findInput = createElement('input', {\n type: 'text',\n class: 'an-input',\n placeholder: 'Find…',\n 'aria-label': 'Search text',\n });\n this._findInput = findInput;\n findRow.appendChild(findInput);\n box.appendChild(findRow);\n\n // ---- Options row (case-sensitive toggle + match counter) ----\n const optRow = createElement('div', { class: 'an-fr-options-row' });\n const caseLabel = createElement('label', { class: 'an-label an-label-inline' });\n const caseCheckbox = createElement('input', {\n type: 'checkbox',\n 'aria-label': 'Case sensitive',\n });\n this._caseCheckbox = caseCheckbox;\n caseLabel.append(caseCheckbox, document.createTextNode('\\u00a0Case sensitive'));\n const counter = createElement('span', { class: 'an-fr-counter' });\n this._counterEl = counter;\n optRow.append(caseLabel, counter);\n box.appendChild(optRow);\n\n // ---- Find actions ----\n const findActions = createElement('div', { class: 'an-dialog-actions an-fr-find-actions' });\n const prevBtn = createElement('button', { type: 'button', class: 'an-btn' });\n prevBtn.textContent = '\\u2190 Prev';\n const nextBtn = createElement('button', { type: 'button', class: 'an-btn an-btn-primary' });\n nextBtn.textContent = 'Next \\u2192';\n findActions.append(prevBtn, nextBtn);\n box.appendChild(findActions);\n\n // ---- Replace row (hidden by default) ----\n const replaceRow = createElement('div', { class: 'an-fr-replace-row' });\n replaceRow.style.display = 'none';\n const replaceInput = createElement('input', {\n type: 'text',\n class: 'an-input',\n placeholder: 'Replace with\\u2026',\n 'aria-label': 'Replace with',\n });\n this._replaceInput = replaceInput;\n replaceRow.appendChild(replaceInput);\n box.appendChild(replaceRow);\n\n // ---- Replace actions (hidden by default) ----\n const replaceActions = createElement('div', { class: 'an-dialog-actions an-fr-replace-actions' });\n replaceActions.style.display = 'none';\n const replaceBtn = createElement('button', { type: 'button', class: 'an-btn' });\n replaceBtn.textContent = 'Replace';\n const replaceAllBtn = createElement('button', { type: 'button', class: 'an-btn an-btn-primary' });\n replaceAllBtn.textContent = 'Replace All';\n replaceActions.append(replaceBtn, replaceAllBtn);\n box.appendChild(replaceActions);\n\n overlay.appendChild(box);\n\n // ---- Event bindings ----\n const d1 = on(closeBtn, 'click', () => this._close());\n const d2 = on(overlay, 'click', (e) => { if (e.target === overlay) this._close(); });\n const d3 = on(findInput, 'input', () => this._onSearch());\n const d4 = on(caseCheckbox, 'change', () => {\n this._caseSensitive = caseCheckbox.checked;\n this._onSearch();\n });\n const d5 = on(nextBtn, 'click', () => this._next());\n const d6 = on(prevBtn, 'click', () => this._prev());\n const d7 = on(replaceBtn, 'click', () => this._replace());\n const d8 = on(replaceAllBtn, 'click', () => this._replaceAll());\n const d9 = on(findInput, 'keydown', (e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n e.shiftKey ? this._prev() : this._next();\n }\n });\n const d10 = on(replaceInput, 'keydown', (e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n this._replace();\n }\n });\n this._disposers.push(d1, d2, d3, d4, d5, d6, d7, d8, d9, d10);\n\n return overlay;\n }\n\n // ---------------------------------------------------------------------------\n // Search logic\n // ---------------------------------------------------------------------------\n\n _onSearch() {\n this._clearHighlights();\n const query = this._findInput ? this._findInput.value : '';\n if (!query) {\n this._updateCounter();\n return;\n }\n this._findAndHighlight(query);\n this._updateCounter();\n }\n\n /**\n * Finds all occurrences of `query` in the editable area text nodes,\n * then wraps each match in a <mark class=\"an-highlight\"> element.\n * Iterates text nodes in reverse so earlier offsets remain valid.\n * @param {string} query\n */\n _findAndHighlight(query) {\n const editable = this.context.layoutInfo.editable;\n if (!editable) return;\n\n // Collect raw matches: { node, start, end }\n const rawMatches = this._findRawMatches(query, editable);\n if (rawMatches.length === 0) return;\n\n this._currentIndex = 0;\n\n // Wrap in reverse order so earlier offsets in the same text node stay valid\n for (let i = rawMatches.length - 1; i >= 0; i--) {\n const { node, start, end } = rawMatches[i];\n try {\n const range = document.createRange();\n range.setStart(node, start);\n range.setEnd(node, end);\n const mark = document.createElement('mark');\n mark.className = 'an-highlight';\n range.surroundContents(mark);\n this._matches.unshift({ mark });\n } catch (_) {\n // surroundContents fails when the range crosses element boundaries.\n // This can happen with <br> inside matched text — skip safely.\n this._matches.unshift({ mark: null });\n }\n }\n\n // Drop entries where wrapping failed so the counter and navigation are accurate\n this._matches = this._matches.filter((m) => m.mark);\n if (this._matches.length === 0) return;\n\n // Highlight the first (current) match\n if (this._matches[0] && this._matches[0].mark) {\n this._matches[0].mark.className = 'an-highlight an-highlight-current';\n this._matches[0].mark.scrollIntoView({ block: 'center', behavior: 'smooth' });\n }\n }\n\n /**\n * Walks all text nodes under `root` and returns positional match descriptors.\n * @param {string} query\n * @param {HTMLElement} root\n * @returns {{ node: Text, start: number, end: number }[]}\n */\n _findRawMatches(query, root) {\n const results = [];\n const flags = this._caseSensitive ? 'g' : 'gi';\n // Escape regex special characters in the literal query string\n const escaped = query.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const re = new RegExp(escaped, flags);\n\n const walker = document.createTreeWalker(root, 0x4 /* NodeFilter.SHOW_TEXT */);\n let node;\n while ((node = walker.nextNode())) {\n re.lastIndex = 0;\n let m;\n while ((m = re.exec(node.textContent)) !== null) {\n results.push({ node, start: m.index, end: m.index + m[0].length });\n }\n }\n return results;\n }\n\n // ---------------------------------------------------------------------------\n // Navigation\n // ---------------------------------------------------------------------------\n\n _next() {\n if (this._matches.length === 0) return;\n this._currentIndex = (this._currentIndex + 1) % this._matches.length;\n this._scrollToMatch(this._currentIndex);\n this._updateCounter();\n }\n\n _prev() {\n if (this._matches.length === 0) return;\n this._currentIndex = (this._currentIndex - 1 + this._matches.length) % this._matches.length;\n this._scrollToMatch(this._currentIndex);\n this._updateCounter();\n }\n\n _scrollToMatch(index) {\n const match = this._matches[index];\n if (!match || !match.mark) return;\n // Update CSS classes\n this._matches.forEach((m, i) => {\n if (m.mark) {\n m.mark.className = i === index\n ? 'an-highlight an-highlight-current'\n : 'an-highlight';\n }\n });\n match.mark.scrollIntoView({ block: 'center', behavior: 'smooth' });\n }\n\n // ---------------------------------------------------------------------------\n // Replace\n // ---------------------------------------------------------------------------\n\n _replace() {\n if (this._matches.length === 0 || this._currentIndex < 0) return;\n const match = this._matches[this._currentIndex];\n if (!match || !match.mark || !match.mark.parentNode) return;\n\n const replacement = this._replaceInput ? this._replaceInput.value : '';\n const parent = match.mark.parentNode;\n const textNode = document.createTextNode(replacement);\n parent.insertBefore(textNode, match.mark);\n parent.removeChild(match.mark);\n parent.normalize();\n this.context.invoke('editor.afterCommand');\n const savedIndex = this._currentIndex;\n this._onSearch();\n if (this._matches.length > 0) {\n this._currentIndex = Math.min(savedIndex, this._matches.length - 1);\n this._scrollToMatch(this._currentIndex);\n this._updateCounter();\n }\n }\n\n _replaceAll() {\n if (this._matches.length === 0) return;\n const replacement = this._replaceInput ? this._replaceInput.value : '';\n\n this._matches.forEach(({ mark }) => {\n if (!mark || !mark.parentNode) return;\n const textNode = document.createTextNode(replacement);\n mark.parentNode.insertBefore(textNode, mark);\n mark.parentNode.removeChild(mark);\n });\n\n if (this.context.layoutInfo.editable) {\n this.context.layoutInfo.editable.normalize();\n }\n this._matches = [];\n this._currentIndex = -1;\n this.context.invoke('editor.afterCommand');\n this._onSearch();\n }\n\n // ---------------------------------------------------------------------------\n // Highlight management\n // ---------------------------------------------------------------------------\n\n /**\n * Removes all <mark class=\"an-highlight\"> elements from the editable area,\n * restoring the original text nodes via normalization.\n */\n _clearHighlights() {\n const editable = this.context.layoutInfo.editable;\n if (!editable) return;\n\n editable.querySelectorAll('mark.an-highlight').forEach((mark) => {\n const parent = mark.parentNode;\n if (!parent) return;\n while (mark.firstChild) parent.insertBefore(mark.firstChild, mark);\n parent.removeChild(mark);\n });\n // Merge adjacent text nodes after unwrapping\n editable.normalize();\n\n this._matches = [];\n this._currentIndex = -1;\n }\n\n // ---------------------------------------------------------------------------\n // Counter display\n // ---------------------------------------------------------------------------\n\n _updateCounter() {\n if (!this._counterEl) return;\n const total = this._matches.length;\n if (total === 0) {\n const query = this._findInput ? this._findInput.value : '';\n this._counterEl.textContent = query ? 'No results' : '';\n } else {\n this._counterEl.textContent = `${this._currentIndex + 1} / ${total}`;\n }\n }\n}\n","/**\n * Context.js - Central hub for the editor instance\n * Holds references to all sub-modules and manages inter-module communication.\n * Inspired by Summernote's Context.js\n */\n\nimport { mergeDeep } from './core/func.js';\nimport { defaultOptions } from './settings.js';\nimport { renderLayout } from './renderer.js';\nimport { on } from './core/dom.js';\n\n// Modules\nimport { Editor } from './module/Editor.js';\nimport { Toolbar } from './module/Toolbar.js';\nimport { Statusbar } from './module/Statusbar.js';\nimport { Clipboard } from './module/Clipboard.js';\nimport { Placeholder } from './module/Placeholder.js';\nimport { Codeview } from './module/Codeview.js';\nimport { Fullscreen } from './module/Fullscreen.js';\nimport { LinkDialog } from './module/LinkDialog.js';\nimport { ImageDialog } from './module/ImageDialog.js';\nimport { VideoDialog } from './module/VideoDialog.js';\nimport { ImageResizer } from './module/ImageResizer.js';\nimport { VideoResizer } from './module/VideoResizer.js';\nimport { LinkTooltip } from './module/LinkTooltip.js';\nimport { ImageTooltip } from './module/ImageTooltip.js';\nimport { VideoTooltip } from './module/VideoTooltip.js';\nimport { TableTooltip } from './module/TableTooltip.js';\nimport { CodeTooltip } from './module/CodeTooltip.js';\nimport { EmojiDialog } from './module/EmojiDialog.js';\nimport { IconDialog } from './module/IconDialog.js';\nimport { ContextMenu } from './module/ContextMenu.js';\nimport { ShortcutsDialog } from './module/ShortcutsDialog.js';\nimport { FindReplace } from './module/FindReplace.js';\n\n/** Module registry shared across all Context instances (populated via AutumnNote.registerModule). */\nexport const _customModules = new Map();\n\nexport class Context {\n /**\n * @param {HTMLElement} targetEl - The element to replace with the editor\n * @param {import('./settings.js').AsnOptions} [userOptions]\n */\n constructor(targetEl, userOptions = {}) {\n this.targetEl = targetEl;\n this.options = mergeDeep(defaultOptions, userOptions);\n\n /** @type {{ container: HTMLElement, editable: HTMLElement, toolbar?: HTMLElement, statusbar?: HTMLElement }} */\n this.layoutInfo = {};\n\n /** @type {Map<string, Function[]>} */\n this._listeners = new Map();\n\n /** @type {Map<string, object>} */\n this._modules = new Map();\n\n this._disposers = [];\n this._alive = false;\n }\n\n // ---------------------------------------------------------------------------\n // Initialisation\n // ---------------------------------------------------------------------------\n\n initialize() {\n // 1. Render the DOM skeleton\n const { container, editable } = renderLayout(this.targetEl, this.options);\n this.layoutInfo.container = container;\n this.layoutInfo.editable = editable;\n\n // 2. Register core modules\n this._registerModules();\n\n // 3. Attach toolbar/statusbar to container\n const toolbar = this._modules.get('toolbar');\n if (toolbar && toolbar.el) {\n container.insertBefore(toolbar.el, editable);\n this.layoutInfo.toolbar = toolbar.el;\n }\n\n const statusbar = this._modules.get('statusbar');\n if (statusbar && statusbar.el) {\n container.appendChild(statusbar.el);\n this.layoutInfo.statusbar = statusbar.el;\n }\n\n // 4. Bind editor-level events\n this._bindEditorEvents(editable);\n\n // 5. Auto-focus if requested\n if (this.options.focus) {\n editable.focus();\n }\n\n this._alive = true;\n\n // Initial toolbar sync so dropdowns show the correct font on load\n this.invoke('toolbar.refresh');\n\n if (typeof this.options.onInit === 'function') {\n this.options.onInit(this);\n }\n\n return this;\n }\n\n _registerModules() {\n const register = (name, ModuleClass) => {\n const instance = new ModuleClass(this);\n instance.initialize();\n this._modules.set(name, instance);\n };\n\n register('editor', Editor);\n register('toolbar', Toolbar);\n register('statusbar', Statusbar);\n register('clipboard', Clipboard);\n register('contextMenu', ContextMenu);\n register('placeholder', Placeholder);\n register('codeview', Codeview);\n register('fullscreen', Fullscreen);\n register('linkDialog', LinkDialog);\n register('imageDialog', ImageDialog);\n register('videoDialog', VideoDialog);\n register('imageResizer', ImageResizer);\n register('videoResizer', VideoResizer);\n register('linkTooltip', LinkTooltip);\n register('imageTooltip', ImageTooltip);\n register('videoTooltip', VideoTooltip);\n register('tableTooltip', TableTooltip);\n register('codeTooltip', CodeTooltip);\n register('emojiDialog', EmojiDialog);\n register('iconDialog', IconDialog);\n register('shortcutsDialog', ShortcutsDialog);\n register('findReplace', FindReplace);\n\n // Custom modules registered via AutumnNote.registerModule()\n for (const [name, ModuleClass] of _customModules) {\n register(name, ModuleClass);\n }\n }\n\n /**\n * Registers and initialises a custom module on this instance.\n * @param {string} name\n * @param {Function} ModuleClass\n * @returns {this}\n */\n registerModule(name, ModuleClass) {\n if (this._modules.has(name)) return this;\n const instance = new ModuleClass(this);\n instance.initialize();\n this._modules.set(name, instance);\n return this;\n }\n\n _bindEditorEvents(editable) {\n const d1 = on(editable, 'focus', () => {\n this.layoutInfo.container.classList.add('an-focused');\n if (typeof this.options.onFocus === 'function') {\n this.options.onFocus(this);\n }\n });\n const d2 = on(editable, 'blur', () => {\n this.layoutInfo.container.classList.remove('an-focused');\n this._syncToTarget();\n if (typeof this.options.onBlur === 'function') {\n this.options.onBlur(this);\n }\n });\n // Sync textarea/input value on every change so form.submit() always gets fresh content\n const d3 = this.on('change', () => this._syncToTarget());\n this._disposers.push(d1, d2, d3);\n\n // Auto-save to localStorage on every change\n if (this.options.autoSave && this.options.autoSaveKey) {\n const d4 = this.on('change', () => {\n try { localStorage.setItem(this.options.autoSaveKey, this.getHTML()); } catch (_) {}\n });\n this._disposers.push(d4);\n }\n }\n\n // ---------------------------------------------------------------------------\n // Module invocation\n // ---------------------------------------------------------------------------\n\n /**\n * Invokes a method on a registered module.\n * Format: 'moduleName.methodName'\n * @param {string} path - e.g. 'editor.bold'\n * @param {...*} args\n * @returns {*}\n */\n invoke(path, ...args) {\n const [moduleName, methodName] = path.split('.');\n const module = this._modules.get(moduleName);\n if (!module) {\n if (typeof process === 'undefined' || process.env?.NODE_ENV !== 'production') {\n console.warn(`[AutumnNote] invoke: module \"${moduleName}\" not found (path: \"${path}\")`);\n }\n return undefined;\n }\n if (typeof module[methodName] !== 'function') {\n if (typeof process === 'undefined' || process.env?.NODE_ENV !== 'production') {\n console.warn(`[AutumnNote] invoke: method \"${methodName}\" not found on module \"${moduleName}\" (path: \"${path}\")`);\n }\n return undefined;\n }\n return module[methodName](...args);\n }\n\n // ---------------------------------------------------------------------------\n // Event system\n // ---------------------------------------------------------------------------\n\n /**\n * Subscribes to an editor event.\n * @param {string} eventName\n * @param {Function} handler\n * @returns {() => void} unsubscribe\n */\n on(eventName, handler) {\n if (!this._listeners.has(eventName)) {\n this._listeners.set(eventName, []);\n }\n this._listeners.get(eventName).push(handler);\n return () => this.off(eventName, handler);\n }\n\n /**\n * Unsubscribes from an editor event.\n * @param {string} eventName\n * @param {Function} handler\n */\n off(eventName, handler) {\n const handlers = this._listeners.get(eventName);\n if (!handlers) return;\n const idx = handlers.indexOf(handler);\n if (idx !== -1) handlers.splice(idx, 1);\n }\n\n /**\n * Triggers an editor event.\n * @param {string} eventName\n * @param {...*} args\n */\n triggerEvent(eventName, ...args) {\n const handlers = this._listeners.get(eventName) || [];\n handlers.forEach((h) => h(...args));\n\n // Also call options callback if present (e.g. onChange)\n const cbName = 'on' + eventName.charAt(0).toUpperCase() + eventName.slice(1);\n if (typeof this.options[cbName] === 'function') {\n this.options[cbName](...args);\n }\n }\n\n // ---------------------------------------------------------------------------\n // Public editor API\n // ---------------------------------------------------------------------------\n\n /**\n * Returns the current HTML content of the editor.\n * @returns {string}\n */\n getHTML() {\n return this.invoke('editor.getHTML');\n }\n\n /**\n * Sets the HTML content of the editor.\n * @param {string} html\n */\n setHTML(html) {\n this.invoke('editor.setHTML', html);\n }\n\n /**\n * Returns the plain text content of the editor.\n * @returns {string}\n */\n getText() {\n return this.invoke('editor.getText');\n }\n\n /**\n * Sets the editor content as plain text (HTML-escaped).\n * @param {string} text\n */\n setText(text) {\n this.invoke('editor.setText', text);\n }\n\n /**\n * Clears the editor content.\n */\n clear() {\n this.invoke('editor.clear');\n }\n\n /**\n * Resets the undo/redo history stack.\n * Useful after programmatically loading a new document via setHTML() / setMarkdown()\n * so that Ctrl+Z cannot undo back to the previous document.\n */\n clearHistory() {\n this.invoke('editor.clearHistory');\n }\n\n /**\n * Returns true when the editor has no meaningful content.\n * @returns {boolean}\n */\n isEmpty() {\n return this.invoke('editor.isEmpty');\n }\n\n /**\n * Inserts HTML at the current cursor position.\n * @param {string} html\n */\n insertHTML(html) {\n this.invoke('editor.insertHTML', html);\n }\n\n /**\n * Inserts plain text at the current cursor position.\n * @param {string} text\n */\n insertText(text) {\n this.invoke('editor.insertText', text);\n }\n\n /**\n * Sets editor content from a Markdown string.\n * @param {string} md\n */\n setMarkdown(md) {\n this.invoke('editor.setMarkdown', md);\n }\n\n /**\n * Returns the editor content as Markdown.\n * @returns {string}\n */\n getMarkdown() {\n return this.invoke('editor.getMarkdown');\n }\n\n /**\n * Returns the current word count of the editor content.\n * @returns {number}\n */\n getWordCount() {\n return this.invoke('statusbar.getWordCount') ?? 0;\n }\n\n /**\n * Returns the current character count of the editor content.\n * @returns {number}\n */\n getCharCount() {\n return this.invoke('statusbar.getCharCount') ?? 0;\n }\n\n /**\n * Downloads the editor content as an HTML file.\n * @param {string} [filename='document.html']\n */\n downloadHTML(filename = 'document.html') {\n this._download(this.getHTML(), filename, 'text/html');\n }\n\n /**\n * Downloads the editor content as a plain-text file.\n * @param {string} [filename='document.txt']\n */\n downloadText(filename = 'document.txt') {\n this._download(this.getText(), filename, 'text/plain');\n }\n\n /**\n * Downloads the editor content as a Markdown file.\n * @param {string} [filename='document.md']\n */\n downloadMarkdown(filename = 'document.md') {\n this._download(this.getMarkdown(), filename, 'text/markdown');\n }\n\n /**\n * Creates a temporary Blob URL and triggers a browser file download.\n * @param {string} content\n * @param {string} filename\n * @param {string} mimeType\n */\n _download(content, filename, mimeType) {\n const blob = new Blob([content], { type: mimeType });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = filename;\n a.style.display = 'none';\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n URL.revokeObjectURL(url);\n }\n\n /**\n * Opens the editor content in a new window and triggers the browser print dialog.\n * @param {string} [title='']\n */\n print(title = '') {\n const content = this.getHTML();\n const safeTitle = (title || '').replace(/</g, '<').replace(/>/g, '>');\n const w = window.open('', '_blank');\n if (!w) return; // popup blocked by browser\n w.document.write(\n '<!DOCTYPE html><html lang=\"en\"><head><meta charset=\"utf-8\">' +\n `<title>${safeTitle}</title>` +\n '<style>' +\n 'body{font-family:system-ui,-apple-system,\"Segoe UI\",Roboto,Arial,sans-serif;font-size:14px;line-height:1.6;padding:20mm;color:#111827;}' +\n 'ul.an-checklist{list-style:none;padding-left:0;}' +\n 'ul.an-checklist li{padding-left:24px;position:relative;margin:2px 0;}' +\n 'ul.an-checklist li input[type=\"checkbox\"]{position:absolute;left:0;top:3px;}' +\n 'code{background:#f3f4f6;border-radius:3px;padding:.1em .35em;font-family:monospace;}' +\n 'pre{background:#f3f4f6;padding:.75em 1em;border-radius:4px;overflow-x:auto;}' +\n 'table{border-collapse:collapse;}td,th{border:1px solid #d1d5db;padding:4px 8px;}' +\n '</style>' +\n `</head><body>${content}</body></html>`,\n );\n w.document.close();\n w.onload = () => { w.print(); };\n }\n\n /**\n * Sets whether the editor is disabled (readonly).\n * @param {boolean} disabled\n */\n setDisabled(disabled) {\n const editable = this.layoutInfo.editable;\n if (disabled) {\n editable.setAttribute('contenteditable', 'false');\n this.layoutInfo.container.classList.add('an-disabled');\n } else {\n editable.setAttribute('contenteditable', 'true');\n this.layoutInfo.container.classList.remove('an-disabled');\n }\n }\n\n // ---------------------------------------------------------------------------\n // Destroy\n // ---------------------------------------------------------------------------\n\n /**\n * Completely removes the editor and restores the original element.\n */\n destroy() {\n if (!this._alive) return;\n\n this._modules.forEach((module) => {\n if (typeof module.destroy === 'function') module.destroy();\n });\n this._modules.clear();\n\n this._disposers.forEach((d) => d());\n this._disposers = [];\n\n const container = this.layoutInfo.container;\n if (container && container.parentNode) {\n // Restore original element\n this.targetEl.style.display = '';\n container.parentNode.removeChild(container);\n }\n\n if (typeof this.options.onDestroy === 'function') {\n this.options.onDestroy(this);\n }\n\n this._alive = false;\n this._listeners.clear();\n }\n\n // ---------------------------------------------------------------------------\n // Helpers\n // ---------------------------------------------------------------------------\n\n /**\n * Syncs editor HTML back into the original textarea/input for form submission.\n */\n _syncToTarget() {\n if (this.targetEl.tagName === 'TEXTAREA' || this.targetEl.tagName === 'INPUT') {\n this.targetEl.value = this.getHTML();\n }\n }\n}\n","/**\n * lists.js - Array/list utility helpers\n * Inspired by Summernote's lists.js\n */\n\n/**\n * Returns the last element of an array.\n * @template T\n * @param {T[]} arr\n * @returns {T|undefined}\n */\nexport function last(arr) {\n return arr[arr.length - 1];\n}\n\n/**\n * Returns the first element of an array.\n * @template T\n * @param {T[]} arr\n * @returns {T|undefined}\n */\nexport function first(arr) {\n return arr[0];\n}\n\n/**\n * Returns a new array without the last n items.\n * @template T\n * @param {T[]} arr\n * @param {number} [n=1]\n * @returns {T[]}\n */\nexport function initial(arr, n = 1) {\n return arr.slice(0, arr.length - n);\n}\n\n/**\n * Returns a new array without the first n items.\n * @template T\n * @param {T[]} arr\n * @param {number} [n=1]\n * @returns {T[]}\n */\nexport function tail(arr, n = 1) {\n return arr.slice(n);\n}\n\n/**\n * Returns a flattened (one level) array.\n * @template T\n * @param {T[][]} arr\n * @returns {T[]}\n */\nexport function flatten(arr) {\n return arr.reduce((acc, val) => acc.concat(val), []);\n}\n\n/**\n * Returns unique elements of an array (using Set).\n * @template T\n * @param {T[]} arr\n * @returns {T[]}\n */\nexport function unique(arr) {\n return [...new Set(arr)];\n}\n\n/**\n * Splits an array into chunks of size n.\n * @template T\n * @param {T[]} arr\n * @param {number} n\n * @returns {T[][]}\n */\nexport function chunk(arr, n) {\n const result = [];\n for (let i = 0; i < arr.length; i += n) {\n result.push(arr.slice(i, i + n));\n }\n return result;\n}\n\n/**\n * Groups array elements by a key function.\n * @template T\n * @param {T[]} arr\n * @param {(item: T) => string} keyFn\n * @returns {Record<string, T[]>}\n */\nexport function groupBy(arr, keyFn) {\n return arr.reduce((groups, item) => {\n const key = keyFn(item);\n if (!groups[key]) {\n groups[key] = [];\n }\n groups[key].push(item);\n return groups;\n }, {});\n}\n\n/**\n * Returns true if all elements satisfy the predicate.\n * @template T\n * @param {T[]} arr\n * @param {(item: T) => boolean} predicate\n * @returns {boolean}\n */\nexport function all(arr, predicate) {\n return arr.every(predicate);\n}\n\n/**\n * Returns true if any element satisfies the predicate.\n * @template T\n * @param {T[]} arr\n * @param {(item: T) => boolean} predicate\n * @returns {boolean}\n */\nexport function any(arr, predicate) {\n return arr.some(predicate);\n}\n","/**\n * env.js - Environment / browser detection\n * Inspired by Summernote's env.js\n */\n\nconst userAgent = navigator.userAgent;\n\nexport const env = {\n /** True if browser is Chrome */\n isChrome: /Chrome\\//.test(userAgent),\n /** True if browser is Firefox */\n isFF: /Firefox\\//.test(userAgent),\n /** True if browser is Safari (not Chrome) */\n isSafari: /^((?!chrome|android).)*safari/i.test(userAgent),\n /** True if browser is Edge (Chromium) */\n isEdge: /Edg\\//.test(userAgent),\n /** True if running on macOS */\n isMac: /Macintosh/.test(userAgent),\n /** True if running on mobile */\n isMobile: /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(userAgent),\n /** True if touch is supported */\n isTouch: 'ontouchstart' in window || navigator.maxTouchPoints > 0,\n /** Modifier key name depending on platform */\n modifierKey: /Macintosh/.test(userAgent) ? 'metaKey' : 'ctrlKey',\n};\n","/**\n * index.js - Public entry point for AutumnNote\n *\n * Usage (module):\n * import AutumnNote from 'autumnnote';\n * const editor = AutumnNote.create('#my-editor', { placeholder: 'Start typing…' });\n *\n * Usage (UMD / script tag):\n * const editor = AutumnNote.create('#my-editor');\n */\n\nimport '../styles/autumnnote.scss';\nimport { Context, _customModules } from './Context.js';\nimport { defaultOptions } from './settings.js';\n\n// Snapshot of factory defaults taken at module-load time (before any setDefaults() calls)\nconst _originalDefaults = { ...defaultOptions };\n\n// Re-export for tree-shaking / module consumers\nexport { Context } from './Context.js';\nexport { defaultOptions } from './settings.js';\nexport * from './core/dom.js';\nexport * from './core/range.js';\nexport * from './core/func.js';\nexport * from './core/key.js';\nexport * from './core/lists.js';\nexport * from './core/env.js';\nexport * from './core/sanitise.js';\nexport * from './module/Buttons.js';\n\n// ---------------------------------------------------------------------------\n// Main factory\n// ---------------------------------------------------------------------------\n\n/** @type {WeakMap<Element, Context>} */\nconst instances = new WeakMap();\n\nconst AutumnNote = {\n /**\n * Creates (or returns existing) editor instance on one or more elements.\n *\n * @param {string|Element|NodeList|Element[]} selector\n * @param {import('./settings.js').AsnOptions} [options]\n * @returns {Context|Context[]} single Context or array of Contexts\n */\n create(selector, options = {}) {\n const elements = resolveElements(selector);\n const ctxs = elements.map((el) => {\n if (instances.has(el)) return instances.get(el);\n const ctx = new Context(el, options);\n ctx.initialize();\n instances.set(el, ctx);\n return ctx;\n });\n return ctxs.length === 1 ? ctxs[0] : ctxs;\n },\n\n /**\n * Destroys the editor(s) on the given selector.\n * @param {string|Element|NodeList|Element[]} selector\n */\n destroy(selector) {\n resolveElements(selector).forEach((el) => {\n const ctx = instances.get(el);\n if (ctx) {\n ctx.destroy();\n instances.delete(el);\n }\n });\n },\n\n /**\n * Returns the Context instance for a given element (or null).\n * @param {string|Element} selector\n * @returns {Context|null}\n */\n getInstance(selector) {\n const el = typeof selector === 'string' ? document.querySelector(selector) : selector;\n return el ? instances.get(el) || null : null;\n },\n\n /** Returns a shallow copy of the default options (read-only snapshot). */\n get defaults() { return { ...defaultOptions }; },\n\n /** Merges properties into the global defaults, applied to all future instances. */\n setDefaults(overrides) { Object.assign(defaultOptions, overrides); },\n\n /** Restores global defaults to their original factory values. */\n resetDefaults() {\n Object.keys(defaultOptions).forEach((k) => delete defaultOptions[k]);\n Object.assign(defaultOptions, _originalDefaults);\n },\n\n /**\n * Registers a custom module to be included in every new editor instance.\n * @param {string} name - unique module key used for ctx.invoke() calls\n * @param {Function} ModuleClass - class with initialize() and optional destroy()\n */\n registerModule(name, ModuleClass) { _customModules.set(name, ModuleClass); },\n\n /** Library version */\n version: '1.0.1',\n};\n\n// ---------------------------------------------------------------------------\n// Helper\n// ---------------------------------------------------------------------------\n\n/**\n * @param {string|Element|NodeList|Element[]} selector\n * @returns {Element[]}\n */\nfunction resolveElements(selector) {\n if (typeof selector === 'string') {\n return Array.from(document.querySelectorAll(selector));\n }\n if (selector instanceof Element) {\n return [selector];\n }\n if (selector instanceof NodeList || Array.isArray(selector)) {\n return Array.from(selector);\n }\n return [];\n}\n\nexport default AutumnNote;\n"],"names":["clamp","val","min","max","debounce","fn","delay","timer","args","throttle","limit","lastCall","now","compose","fns","x","v","f","identity","isNil","isString","isFunction","mergeDeep","target","source","output","key","isPlainObject","rect2bnd","rect","ELEMENT_NODE","TEXT_NODE","isElement","node","isText","isVoid","isPara","isLi","isList","isTable","isInline","isEditable","isAnchor","isImage","closest","predicate","stopAt","cur","closestPara","editable","ancestors","result","children","prevElement","sibling","nextElement","createElement","tag","attrs","childNodes","el","k","child","remove","unwrap","parent","wrap","wrapper","insertAfter","newNode","refNode","nodeValue","isEmpty","outerHtml","placeCaret","range","sel","isInsideEditable","on","type","handler","options","trapFocus","container","onEscape","FOCUSABLE","getFocusable","e","els","first","last","WrappedRange","sc","so","ec","eo","ancestor","n","rects","fromNativeRange","currentRange","native","rangeFromElement","collapsedRange","offset","isSelectionInside","withSavedRange","saved","splitText","textNode","after","execCommand","cmd","value","bold","italic","underline","uEl","nativeState","strikethrough","superscript","subscript","foreColor","color","backColor","fontName","name","fontSize","size","span","formatBlock","tagName","justifyLeft","justifyCenter","justifyRight","justifyFull","indent","outdent","insertUnorderedList","insertOrderedList","lineHeight","BLOCK_TAGS","nearestBlock","block","blocks","iter","toggleInlineCode","codeEl","code","newRange","frag","isInlineCode","toggleChecklist","li","ul","text","p","nr","startNode","MARKER","newLi","cbEl","isInChecklist","btn","icon","tooltip","action","isActive","isDisabled","boldBtn","Style.bold","italicBtn","Style.italic","underlineBtn","Style.underline","strikeBtn","Style.strikethrough","superscriptBtn","Style.superscript","subscriptBtn","Style.subscript","alignLeftBtn","Style.justifyLeft","alignCenterBtn","Style.justifyCenter","alignRightBtn","Style.justifyRight","alignJustifyBtn","Style.justifyFull","ulBtn","Style.insertUnorderedList","olBtn","Style.insertOrderedList","indentBtn","Style.indent","outdentBtn","Style.outdent","undoBtn","_ctx","ctx","redoBtn","hrBtn","Style.execCommand","linkBtn","imageBtn","videoBtn","emojiBtn","iconBtn","tableBtn","rows","cols","fontSizeBtn","Style.fontSize","removeFormatBtn","directionBtn","next","fontFamilyBtn","Style.fontName","paragraphStyleBtn","Style.formatBlock","raw","lineHeightBtn","Style.lineHeight","BLOCKS","codeviewBtn","fullscreenBtn","shortcutsBtn","findBtn","findReplaceBtn","inlineCodeBtn","Style.isInlineCode","checklistBtn","Style.isInChecklist","printBtn","foreColorBtn","Style.foreColor","backColorBtn","Style.backColor","defaultToolbar","defaultOptions","PROHIBITED_TAGS","URL_ATTRS","TRUSTED_IFRAME_HOSTS","sanitiseHTML","html","allowIframes","doc","t","attr","isTrustedIframeSrc","src","trimmed","url","sanitiseUrl","allowData","renderLayout","targetEl","initialContent","defaultFont","History","count","walker","startOff","endNode","endOff","len","lastWalker","lastNode","images","point","index","match","token","current","tokenized","prev","createTable","opts","headerRow","table","thead","tr","c","th","bodyRows","tbody","td","insertTable","isKey","event","keyName","isModifier","handleKeydown","isFAIcon","isZwsAnchor","moveCaret","setFn","movingLeft","para","selI","videoWrapper","checkLi","nativeRange","afterRange","afterFrag","cb","cursorNode","htmlToMarkdown","_domToMd","inner","langMatch","lang","content","l","href","items","i","cellTexts","r","padRow","row","md","isMarkdown","markdownToHTML","lines","out","line","fenceMatch","codeLines","_esc","langAttr","_escAttr","hMatch","level","_inline","bqLines","headerCells","_parseTableRow","paraLines","_","alt","label","Editor","context","d","onKeydown","onInput","onBeforeInput","onSelChange","onCheckboxClick","fixChecklistCursor","caret","cp","anchorNode","maxChars","maxWords","chars","hasMedia","Style.toggleInlineCode","Style.toggleChecklist","openInNewTab","safeUrl","link","displayText","align","safeSrc","style","styleAttr","str","_faPageLevelReady","Toolbar","b","group","groupEl","btnDef","def","baseClass","faPrefix","S","popup","grid","cells","cell","isOpen","setHighlight","openPopup","closePopup","d1","d2","d3","d4","d5","PRESETS","currentColor","applyBtn","iconSvg","strip","arrowBtn","swatches","userSwatches","sw","customRow","colorInput","customLabel","savedRange","saveSelection","restoreSelection","popupMinW","left","applyColor","d2b","d3b","d6","onScrollResize","idx","cls","select","placeholderText","placeholder","item","isHeader","opt","disposer","selectedOpt","extra","classAttr","svgWrap","paths","svgMap","faMap","faName","links","btnMap","matched","_segmenter","_countWords","seg","_applyLimitClass","Statusbar","handle","info","startY","startH","containerEl","applyDelta","clientY","delta","MIN_EDITABLE","fixedH","sum","trueMin","onMouseMove","onMouseUp","onMouseDown","onTouchMove","touch","onTouchEnd","onTouchStart","updateDebounced","words","Clipboard","mutations","mutation","blobUrl","imgs","img","_m","cleaned","s","UNWRAP_TAGS","changed","KEEP_ATTRS","a","clipboardData","forcePlain","imageItems","files","isWordContent","isSocialContent","dt","imageFiles","maxBytes","file","message","dataUrl","blob","err","_a","header","b64","mime","binary","arr","resolve","objectUrl","width","height","canvas","reader","webp","y","pos","Placeholder","update","isFocused","Codeview","INLINE_RE","remaining","stripped","Fullscreen","LinkDialog","overlay","box","title","urlLabel","urlInput","textLabel","textInput","tabLabel","tabCheckbox","btnRow","insertBtn","cancelBtn","anchor","newTab","parsed","ImageDialog","altLabel","altInput","alignLabel","alignRow","radioId","radio","lbl","fileLabel","fileInput","maxSize","alignRadio","VideoDialog","hintEl","widthLabel","widthInput","d0","rawUrl","ytWatch","ytShort","ytShorts","vimeo","iframeTitle","escapedSrc","HANDLE_DEFS","ImageResizer","h","offsetParent","containerRect","top","startX","startW","aspectRatio","isCorner","onMove","me","dx","dy","maxW","newW","newH","onUp","VideoResizer","w","embed","ICONS","SHOW_DELAY","HIDE_DELAY","LinkTooltip","to","tipW","tipH","margin","u","display","ta","ImageTooltip","isDanger","figure","existing","cap","figcaption","VideoTooltip","shield","getVisualColIndex","visualIdx","getCellAtVisualCol","vIdx","getCellAfterVisualCol","TableTooltip","HIT","_nearCell","_nearEdge","_resizing","_edge","_startX","_startY","_startW","_startH","_colIdx","_row","_table","clearHover","onEditorMove","onRight","onBottom","onEditorDown","onDocMove","onDocUp","cellFromSel","position","colCount","newRow","refCells","ref","visualColIdx","newCell","selected","rowSelected","popover","titleEl","body","inputEl","unitEl","actionsEl","isCol","tipRect","pw","ph","CodeTooltip","pre","wrapped","fromAttr","fromClass","original","isWrapped","applyPrism","br","cdn","themeHref","scriptSrc","existingScript","script","poll","EMOJI_CATS","EMOJI_LIST","EmojiDialog","titleRow","closeBtn","searchInput","catBar","allTab","id","tab","char","keywords","cat","query","q","matchCat","matchQuery","visible","empty","ICON_CATEGORIES","ICON_LIST","IconDialog","optRow","styleLabel","styleSelect","sizeLabel","sizeSelect","colorLabel","useColorLabel","useColorCb","preview","previewHint","d7","d8","d9","d10","d11","visibleCount","cellCat","matchesCat","matchesQuery","styleParts","iconEl","caretTextNode","caretOffset","caretRange","defaultItems","doInsert","clean","ContextMenu","it","backBtn","iconSpan","off","chevron","headerBtn","panel","gridEl","labelEl","expanded","offHeader","offMove","offLeave","offClick","winSel","rx","ry","cs","explicitFontFamily","explicitFontSize","boundary","prop","fmt","marker","preExisting","root","rootEl","SHORTCUTS","ShortcutsDialog","category","catEl","keys","keyEl","actEl","FindReplace","mode","replaceRow","replaceActions","isReplace","findRow","findInput","caseLabel","caseCheckbox","counter","findActions","prevBtn","nextBtn","replaceInput","replaceBtn","replaceAllBtn","rawMatches","start","end","mark","m","results","flags","escaped","re","replacement","savedIndex","total","_customModules","Context","userOptions","toolbar","statusbar","register","ModuleClass","instance","path","_b","moduleName","methodName","module","eventName","handlers","cbName","filename","mimeType","safeTitle","disabled","initial","tail","flatten","acc","unique","chunk","groupBy","keyFn","groups","all","any","userAgent","env","_originalDefaults","instances","AutumnNote","selector","ctxs","resolveElements","overrides"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"autumnnote.es.js","sources":["../src/js/core/func.js","../src/js/core/dom.js","../src/js/core/range.js","../src/js/editing/Style.js","../src/js/module/Buttons.js","../src/js/settings.js","../src/js/core/sanitise.js","../src/js/renderer.js","../src/js/editing/History.js","../src/js/editing/Table.js","../src/js/core/key.js","../src/js/editing/Typing.js","../src/js/core/markdown.js","../src/js/module/Editor.js","../src/js/module/Toolbar.js","../src/js/module/Statusbar.js","../src/js/module/Clipboard.js","../src/js/module/Placeholder.js","../src/js/module/Codeview.js","../src/js/module/Fullscreen.js","../src/js/module/LinkDialog.js","../src/js/module/ImageDialog.js","../src/js/module/VideoDialog.js","../src/js/module/ImageResizer.js","../src/js/module/VideoResizer.js","../src/js/module/LinkTooltip.js","../src/js/module/ImageTooltip.js","../src/js/module/VideoTooltip.js","../src/js/module/TableTooltip.js","../src/js/module/CodeTooltip.js","../src/js/module/EmojiDialog.js","../src/js/module/IconDialog.js","../src/js/module/ContextMenu.js","../src/js/module/ShortcutsDialog.js","../src/js/module/FindReplace.js","../src/js/Context.js","../src/js/core/lists.js","../src/js/core/env.js","../src/js/index.js"],"sourcesContent":["/**\n * func.js - General utility / functional helpers\n * Inspired by Summernote's func.js\n */\n\n/**\n * Clamp a value between min and max.\n * @param {number} val\n * @param {number} min\n * @param {number} max\n * @returns {number}\n */\nexport function clamp(val, min, max) {\n return Math.min(Math.max(val, min), max);\n}\n\n/**\n * Debounce a function call.\n * @param {Function} fn\n * @param {number} delay - milliseconds\n * @returns {Function}\n */\nexport function debounce(fn, delay) {\n let timer;\n return function (...args) {\n clearTimeout(timer);\n timer = setTimeout(() => fn.apply(this, args), delay);\n };\n}\n\n/**\n * Throttle a function call.\n * @param {Function} fn\n * @param {number} limit - milliseconds\n * @returns {Function}\n */\nexport function throttle(fn, limit) {\n let lastCall = 0;\n return function (...args) {\n const now = Date.now();\n if (now - lastCall >= limit) {\n lastCall = now;\n return fn.apply(this, args);\n }\n };\n}\n\n/**\n * Compose multiple functions right-to-left.\n * @param {...Function} fns\n * @returns {Function}\n */\nexport function compose(...fns) {\n return (x) => fns.reduceRight((v, f) => f(v), x);\n}\n\n/**\n * Identity function.\n * @template T\n * @param {T} x\n * @returns {T}\n */\nexport function identity(x) {\n return x;\n}\n\n/**\n * Determines if a value is null or undefined.\n * @param {*} val\n * @returns {boolean}\n */\nexport function isNil(val) {\n return val === null || val === undefined;\n}\n\n/**\n * Determines if a value is a string.\n * @param {*} val\n * @returns {boolean}\n */\nexport function isString(val) {\n return typeof val === 'string';\n}\n\n/**\n * Determines if a value is a function.\n * @param {*} val\n * @returns {boolean}\n */\nexport function isFunction(val) {\n return typeof val === 'function';\n}\n\n/**\n * Deep-merge two plain objects. Returns a new object.\n * Arrays are cloned (shallow copy) rather than shared by reference so that\n * mutations to the merged result do not bleed back into the source object\n * (e.g. mutating `instance.options.fontFamilies` should not affect\n * `AutumnNote.defaults.fontFamilies`).\n * @param {object} target\n * @param {object} source\n * @returns {object}\n */\nexport function mergeDeep(target, source) {\n // Start with a shallow copy of target; clone any arrays to avoid shared refs\n const output = {};\n for (const key of Object.keys(target)) {\n output[key] = Array.isArray(target[key]) ? [...target[key]] : target[key];\n }\n if (isPlainObject(target) && isPlainObject(source)) {\n for (const key of Object.keys(source)) {\n if (isPlainObject(source[key])) {\n if (!(key in target)) {\n output[key] = mergeDeep({}, source[key]);\n } else {\n output[key] = mergeDeep(target[key], source[key]);\n }\n } else if (Array.isArray(source[key])) {\n output[key] = [...source[key]];\n } else {\n output[key] = source[key];\n }\n }\n }\n return output;\n}\n\n/**\n * Checks if value is a plain object.\n * @param {*} val\n * @returns {boolean}\n */\nexport function isPlainObject(val) {\n return val !== null && typeof val === 'object' && !Array.isArray(val);\n}\n\n/**\n * Convert a DOMRect (or similar bounding object) to a plain object bounding box.\n * Guards against missing/null rect (e.g. in AirMode).\n * @param {DOMRect|null|undefined} rect\n * @returns {{ top: number, left: number, width: number, height: number, bottom: number, right: number }|null}\n */\nexport function rect2bnd(rect) {\n if (!rect) return null;\n return {\n top: Math.round(rect.top),\n left: Math.round(rect.left),\n width: Math.round(rect.width),\n height: Math.round(rect.height),\n bottom: Math.round(rect.bottom),\n right: Math.round(rect.right),\n };\n}\n","/**\n * dom.js - DOM manipulation utilities\n * Inspired by Summernote's dom.js — rewritten for vanilla JS without jQuery\n */\n\n// ---------------------------------------------------------------------------\n// Node type helpers\n// ---------------------------------------------------------------------------\n\nexport const ELEMENT_NODE = 1;\nexport const TEXT_NODE = 3;\n\n/** @param {Node} node */\nexport const isElement = (node) => node && node.nodeType === ELEMENT_NODE;\n/** @param {Node} node */\nexport const isText = (node) => node && node.nodeType === TEXT_NODE;\n/** @param {Node} node */\nexport const isVoid = (node) => isElement(node) && /^(area|base|br|col|embed|hr|img|input|link|meta|param|source|track|wbr)$/i.test(node.nodeName);\n/** @param {Node} node */\nexport const isPara = (node) => isElement(node) && /^(p|div|li|h[1-6]|blockquote|td|th|pre)$/i.test(node.nodeName);\n/** @param {Node} node */\nexport const isLi = (node) => isElement(node) && /^(li)$/i.test(node.nodeName);\n/** @param {Node} node */\nexport const isList = (node) => isElement(node) && /^(ul|ol)$/i.test(node.nodeName);\n/** @param {Node} node */\nexport const isTable = (node) => isElement(node) && node.nodeName.toUpperCase() === 'TABLE';\n/** @param {Node} node */\nexport const isInline = (node) =>\n isElement(node) &&\n /^(a|abbr|acronym|b|bdo|big|br|button|cite|code|dfn|em|i|img|input|kbd|label|map|object|output|q|s|samp|select|small|span|strong|sub|sup|textarea|time|tt|u|var)$/i.test(node.nodeName);\n/** @param {Node} node */\nexport const isEditable = (node) => isElement(node) && node.isContentEditable;\n/** @param {Node} node */\nexport const isAnchor = (node) => isElement(node) && node.nodeName.toUpperCase() === 'A';\n/** @param {Node} node */\nexport const isImage = (node) => isElement(node) && node.nodeName.toUpperCase() === 'IMG';\n\n// ---------------------------------------------------------------------------\n// Tree traversal\n// ---------------------------------------------------------------------------\n\n/**\n * Walk up the DOM tree from node, returning the first element matching predicate (inclusive).\n * @param {Node} node\n * @param {(node: Node) => boolean} predicate\n * @param {Node} [stopAt] - stop traversal at this ancestor (exclusive)\n * @returns {Node|null}\n */\nexport function closest(node, predicate, stopAt) {\n let cur = node;\n while (cur && cur !== stopAt) {\n if (predicate(cur)) return cur;\n cur = cur.parentNode;\n }\n return null;\n}\n\n/**\n * Returns the nearest ancestor that is a paragraph-like block.\n * @param {Node} node\n * @param {Node} [editable]\n * @returns {Node|null}\n */\nexport function closestPara(node, editable) {\n return closest(node, isPara, editable);\n}\n\n/**\n * Returns all ancestors of node up to (but not including) stopAt.\n * @param {Node} node\n * @param {Node} [stopAt]\n * @returns {Node[]}\n */\nexport function ancestors(node, stopAt) {\n const result = [];\n let cur = node.parentNode;\n while (cur && cur !== stopAt) {\n result.push(cur);\n cur = cur.parentNode;\n }\n return result;\n}\n\n/**\n * Returns all children of node as an Array.\n * @param {Node} node\n * @returns {Node[]}\n */\nexport function children(node) {\n return Array.from(node.childNodes);\n}\n\n/**\n * Returns the previous sibling element (skipping text/comment nodes).\n * @param {Node} node\n * @returns {Element|null}\n */\nexport function prevElement(node) {\n let sibling = node.previousSibling;\n while (sibling && !isElement(sibling)) {\n sibling = sibling.previousSibling;\n }\n return sibling;\n}\n\n/**\n * Returns the next sibling element.\n * @param {Node} node\n * @returns {Element|null}\n */\nexport function nextElement(node) {\n let sibling = node.nextSibling;\n while (sibling && !isElement(sibling)) {\n sibling = sibling.nextSibling;\n }\n return sibling;\n}\n\n// ---------------------------------------------------------------------------\n// DOM mutation helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Creates an element with optional attributes and children.\n * @param {string} tag\n * @param {Record<string, string>} [attrs]\n * @param {(Node|string)[]} [childNodes]\n * @returns {HTMLElement}\n */\nexport function createElement(tag, attrs = {}, childNodes = []) {\n const el = document.createElement(tag);\n for (const [k, v] of Object.entries(attrs)) {\n el.setAttribute(k, v);\n }\n for (const child of childNodes) {\n if (typeof child === 'string') {\n el.appendChild(document.createTextNode(child));\n } else {\n el.appendChild(child);\n }\n }\n return el;\n}\n\n/**\n * Removes a node from its parent.\n * @param {Node} node\n */\nexport function remove(node) {\n if (node && node.parentNode) {\n node.parentNode.removeChild(node);\n }\n}\n\n/**\n * Unwraps a node — replaces the node with its children.\n * @param {Node} node\n */\nexport function unwrap(node) {\n const parent = node.parentNode;\n if (!parent) return;\n while (node.firstChild) {\n parent.insertBefore(node.firstChild, node);\n }\n parent.removeChild(node);\n}\n\n/**\n * Wraps a node with a wrapper element.\n * @param {Node} node\n * @param {HTMLElement} wrapper\n * @returns {HTMLElement} the wrapper\n */\nexport function wrap(node, wrapper) {\n node.parentNode.insertBefore(wrapper, node);\n wrapper.appendChild(node);\n return wrapper;\n}\n\n/**\n * Insert node after reference node.\n * @param {Node} newNode\n * @param {Node} refNode\n */\nexport function insertAfter(newNode, refNode) {\n if (refNode.nextSibling) {\n refNode.parentNode.insertBefore(newNode, refNode.nextSibling);\n } else {\n refNode.parentNode.appendChild(newNode);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Content helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Returns the text content of a node (safe).\n * @param {Node} node\n * @returns {string}\n */\nexport function nodeValue(node) {\n return isText(node) ? node.nodeValue : node.textContent || '';\n}\n\n/**\n * Returns true if a node is empty (no visible content).\n * @param {Node} node\n * @returns {boolean}\n */\nexport function isEmpty(node) {\n if (isText(node)) return !node.nodeValue;\n if (isVoid(node)) return false;\n return !node.textContent.trim() && !node.querySelector('img, video, hr, table');\n}\n\n/**\n * Returns the outerHTML of an element.\n * @param {Element} el\n * @returns {string}\n */\nexport function outerHtml(el) {\n return el.outerHTML;\n}\n\n// ---------------------------------------------------------------------------\n// Selection / editing helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Places the caret at the end of a contenteditable element.\n * @param {HTMLElement} el\n */\nexport function placeCaret(el) {\n const range = document.createRange();\n range.selectNodeContents(el);\n range.collapse(false);\n const sel = window.getSelection();\n if (sel) {\n sel.removeAllRanges();\n sel.addRange(range);\n }\n}\n\n/**\n * Returns true if the node is inside a contenteditable root.\n * @param {Node} node\n * @returns {boolean}\n */\nexport function isInsideEditable(node) {\n return !!closest(node, isEditable);\n}\n\n// ---------------------------------------------------------------------------\n// Event helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Adds an event listener and returns a disposer function.\n * @param {EventTarget} target\n * @param {string} type\n * @param {EventListener} handler\n * @param {AddEventListenerOptions} [options]\n * @returns {() => void} disposer\n */\nexport function on(target, type, handler, options) {\n target.addEventListener(type, handler, options);\n return () => target.removeEventListener(type, handler, options);\n}\n\n/**\n * Installs a keyboard focus trap inside a dialog container.\n * - Tab / Shift+Tab cycles focus within the container's focusable children.\n * - Escape calls `onEscape` and removes the trap listener.\n *\n * Returns a disposer function that removes the listener (call on dialog close).\n *\n * @param {HTMLElement} container - the dialog element to trap focus inside\n * @param {() => void} onEscape - called when Escape is pressed\n * @returns {() => void} disposer\n */\nexport function trapFocus(container, onEscape) {\n const FOCUSABLE = 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"])';\n\n const getFocusable = () => Array.from(container.querySelectorAll(FOCUSABLE)).filter(\n (el) => !el.closest('[style*=\"display: none\"]') && !el.closest('[style*=\"display:none\"]'),\n );\n\n const handler = (e) => {\n if (e.key === 'Escape') {\n e.stopPropagation();\n onEscape && onEscape();\n return;\n }\n if (e.key !== 'Tab') return;\n const els = getFocusable();\n if (!els.length) return;\n const first = els[0];\n const last = els[els.length - 1];\n if (e.shiftKey) {\n if (document.activeElement === first) {\n e.preventDefault();\n last.focus();\n }\n } else {\n if (document.activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n }\n };\n\n document.addEventListener('keydown', handler);\n return () => document.removeEventListener('keydown', handler);\n}\n","/**\n * range.js - Selection and Range utilities\n * Inspired by Summernote's range.js — rewritten as vanilla JS\n */\n\nimport { isElement, closest } from './dom.js';\n\n// ---------------------------------------------------------------------------\n// WrappedRange — a convenience wrapper over the native Range API\n// ---------------------------------------------------------------------------\n\nexport class WrappedRange {\n /**\n * @param {Node} sc - start container\n * @param {number} so - start offset\n * @param {Node} ec - end container\n * @param {number} eo - end offset\n */\n constructor(sc, so, ec, eo) {\n this.sc = sc;\n this.so = so;\n this.ec = ec;\n this.eo = eo;\n }\n\n /** @returns {boolean} */\n isCollapsed() {\n return this.sc === this.ec && this.so === this.eo;\n }\n\n /** @returns {Range} */\n toNativeRange() {\n const range = document.createRange();\n try {\n range.setStart(this.sc, this.so);\n range.setEnd(this.ec, this.eo);\n } catch (_e) {\n // Guard against detached nodes\n }\n return range;\n }\n\n /**\n * Select this wrapped range in the window.\n */\n select() {\n const sel = window.getSelection();\n if (!sel) return;\n sel.removeAllRanges();\n sel.addRange(this.toNativeRange());\n }\n\n /**\n * Returns the common ancestor element of this range.\n * @returns {Element|null}\n */\n commonAncestor() {\n const native = this.toNativeRange();\n const ancestor = native.commonAncestorContainer;\n return isElement(ancestor) ? ancestor : ancestor.parentElement;\n }\n\n /**\n * Returns the nearest paragraph/block ancestor within the editable area.\n * @param {HTMLElement} editable\n * @returns {Element|null}\n */\n blockNode(editable) {\n return closest(this.sc, (n) => isElement(n) && n !== editable, editable);\n }\n\n /**\n * Returns either the selected text string or empty string.\n * @returns {string}\n */\n toString() {\n return this.toNativeRange().toString();\n }\n\n /**\n * Returns the bounding DOMRect of the range (or null).\n * @returns {DOMRect|null}\n */\n getClientRects() {\n const rects = this.toNativeRange().getClientRects();\n return rects.length > 0 ? rects[rects.length - 1] : null;\n }\n\n /**\n * Inserts a node at the start of this range.\n * @param {Node} node\n */\n insertNode(node) {\n const native = this.toNativeRange();\n native.insertNode(node);\n }\n\n}\n\n// ---------------------------------------------------------------------------\n// Factory helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Creates a WrappedRange from a native Range object.\n * @param {Range} range\n * @returns {WrappedRange}\n */\nexport function fromNativeRange(range) {\n return new WrappedRange(\n range.startContainer,\n range.startOffset,\n range.endContainer,\n range.endOffset,\n );\n}\n\n/**\n * Returns a WrappedRange for the current window selection,\n * optionally restricted to a given editable element.\n * @param {HTMLElement} [editable]\n * @returns {WrappedRange|null}\n */\nexport function currentRange(editable) {\n const sel = window.getSelection();\n if (!sel || sel.rangeCount === 0) return null;\n const native = sel.getRangeAt(0);\n // Optionally check that the selection is inside the editable element\n if (editable && !editable.contains(native.commonAncestorContainer)) {\n return null;\n }\n return fromNativeRange(native);\n}\n\n/**\n * Creates a WrappedRange that covers the entire content of an element.\n * @param {HTMLElement} el\n * @returns {WrappedRange}\n */\nexport function rangeFromElement(el) {\n return new WrappedRange(el, 0, el, el.childNodes.length);\n}\n\n/**\n * Creates a collapsed range (cursor) at the given node / offset.\n * @param {Node} node\n * @param {number} offset\n * @returns {WrappedRange}\n */\nexport function collapsedRange(node, offset = 0) {\n return new WrappedRange(node, offset, node, offset);\n}\n\n// ---------------------------------------------------------------------------\n// Utility helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Returns true if the current selection is inside the given element.\n * @param {HTMLElement} el\n * @returns {boolean}\n */\nexport function isSelectionInside(el) {\n const sel = window.getSelection();\n if (!sel || sel.rangeCount === 0) return false;\n return el.contains(sel.getRangeAt(0).commonAncestorContainer);\n}\n\n/**\n * Saves the current selection, executes fn, then restores the selection.\n * @param {Function} fn\n */\nexport function withSavedRange(fn) {\n const sel = window.getSelection();\n if (!sel || sel.rangeCount === 0) {\n fn(null);\n return;\n }\n const saved = sel.getRangeAt(0).cloneRange();\n fn(fromNativeRange(saved));\n sel.removeAllRanges();\n sel.addRange(saved);\n}\n\n/**\n * Splits the text node at the given offset and returns the two halves.\n * @param {Text} textNode\n * @param {number} offset\n * @returns {[Text, Text]}\n */\nexport function splitText(textNode, offset) {\n const after = textNode.splitText(offset);\n return [textNode, after];\n}\n","/**\n * Style.js - Inline / block style detection and application utilities\n * Rewritten from Summernote's approach using vanilla JS + execCommand fallback\n */\n\nimport { closest, isElement, isPara } from '../core/dom.js';\nimport { currentRange } from '../core/range.js';\n\n// ---------------------------------------------------------------------------\n// execCommand wrappers (still the most compatible way in contenteditable)\n// ---------------------------------------------------------------------------\n\n/**\n * Applies a document execCommand.\n * @param {string} cmd\n * @param {string} [value]\n * @returns {boolean}\n */\nexport function execCommand(cmd, value = null) {\n return document.execCommand(cmd, false, value);\n}\n\n// ---------------------------------------------------------------------------\n// Inline style helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Bolds / unbolds the selection.\n */\nexport const bold = () => execCommand('bold');\n\n/**\n * Italicises / un-italicises the selection.\n */\nexport const italic = () => execCommand('italic');\n\n/**\n * Underlines / un-underlines the selection.\n * Falls back to manual DOM manipulation when inside <code> where\n * execCommand's state detection is unreliable.\n */\nexport function underline() {\n const sel = window.getSelection();\n if (!sel || !sel.rangeCount) return;\n let container = sel.getRangeAt(0).commonAncestorContainer;\n if (container.nodeType === 3) container = container.parentElement;\n // Check if we're inside a <u> (DOM truth), to guard against unreliable queryCommandState\n const uEl = container && container.closest && container.closest('u');\n const nativeState = document.queryCommandState('underline');\n if (uEl && !nativeState) {\n // Browser doesn't recognise the underline state (e.g. inside <code>).\n // Manually unwrap the <u> element.\n const parent = uEl.parentNode;\n while (uEl.firstChild) parent.insertBefore(uEl.firstChild, uEl);\n parent.removeChild(uEl);\n return;\n }\n execCommand('underline');\n}\n\n/**\n * Strikethrough / removes strikethrough.\n */\nexport const strikethrough = () => execCommand('strikeThrough');\n\n/**\n * Superscript toggle.\n */\nexport const superscript = () => execCommand('superscript');\n\n/**\n * Subscript toggle.\n */\nexport const subscript = () => execCommand('subscript');\n\n/**\n * Sets the foreground colour of the selected text.\n * @param {string} color - CSS colour string\n */\nexport const foreColor = (color) => execCommand('foreColor', color);\n\n/**\n * Sets the background (highlight) colour of the selected text.\n * @param {string} color - CSS colour string\n */\nexport const backColor = (color) => execCommand('hiliteColor', color);\n\n/**\n * Sets the font name for the selection.\n * @param {string} name\n */\nexport const fontName = (name) => execCommand('fontName', name);\n\n/**\n * Sets the font size (in pt or with unit) for the selection.\n * Uses a span-based approach to set px sizes precisely.\n * @param {string} size - e.g. '14px'\n * @param {HTMLElement} [editable] - scoping element to avoid touching nodes outside this editor\n */\nexport function fontSize(size, editable = document) {\n execCommand('fontSize', '7'); // placeholder\n // Replace font elements with spans, scoped to the active editable\n editable.querySelectorAll('font[size=\"7\"]').forEach((el) => {\n const span = document.createElement('span');\n span.style.fontSize = size;\n el.parentNode.insertBefore(span, el);\n while (el.firstChild) span.appendChild(el.firstChild);\n el.parentNode.removeChild(el);\n });\n}\n\n// ---------------------------------------------------------------------------\n// Block style helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Wraps the selection in the given block tag (p, h1-h6, blockquote, pre).\n * @param {string} tagName\n */\nexport const formatBlock = (tagName) => execCommand('formatBlock', `<${tagName}>`);\n\n/**\n * Left-aligns the current block.\n */\nexport const justifyLeft = () => execCommand('justifyLeft');\n\n/**\n * Center-aligns the current block.\n */\nexport const justifyCenter = () => execCommand('justifyCenter');\n\n/**\n * Right-aligns the current block.\n */\nexport const justifyRight = () => execCommand('justifyRight');\n\n/**\n * Fully justifies the current block.\n */\nexport const justifyFull = () => execCommand('justifyFull');\n\n/**\n * Indents the list or block.\n */\nexport const indent = () => execCommand('indent');\n\n/**\n * Outdents the list or block.\n */\nexport const outdent = () => execCommand('outdent');\n\n/**\n * Inserts an unordered list or converts selection.\n */\nexport const insertUnorderedList = () => execCommand('insertUnorderedList');\n\n/**\n * Inserts an ordered list or converts selection.\n */\nexport const insertOrderedList = () => execCommand('insertOrderedList');\n\n// ---------------------------------------------------------------------------\n// Line-height helper\n// ---------------------------------------------------------------------------\n\n/**\n * Applies a line-height value to every block-level element that intersects\n * the current selection.\n * @param {string} value - unitless multiplier, e.g. '1.5'\n */\nexport function lineHeight(value) {\n const sel = window.getSelection();\n if (!sel || sel.rangeCount === 0) return;\n\n const range = sel.getRangeAt(0);\n const BLOCK_TAGS = new Set(['P', 'DIV', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'LI', 'BLOCKQUOTE', 'PRE', 'TD', 'TH']);\n\n const nearestBlock = (node) => {\n let el = node instanceof Element ? node : node.parentElement;\n while (el) {\n if (BLOCK_TAGS.has(el.tagName)) return el;\n el = el.parentElement;\n }\n return null;\n };\n\n if (range.collapsed) {\n const block = nearestBlock(range.startContainer);\n if (block) block.style.lineHeight = value;\n return;\n }\n\n // For a range selection, collect all unique block ancestors of text nodes\n const blocks = new Set();\n const iter = document.createNodeIterator(range.commonAncestorContainer, NodeFilter.SHOW_TEXT, null);\n let textNode;\n while ((textNode = iter.nextNode())) {\n if (range.intersectsNode(textNode)) {\n const block = nearestBlock(textNode);\n if (block) blocks.add(block);\n }\n }\n if (blocks.size === 0) {\n const block = nearestBlock(range.commonAncestorContainer);\n if (block) blocks.add(block);\n }\n blocks.forEach((block) => { block.style.lineHeight = value; });\n}\n\n// ---------------------------------------------------------------------------\n// Style query helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Returns the computed styles relevant to the current cursor position.\n * @param {HTMLElement} editable\n * @returns {object} styleMap\n */\nexport function currentStyle(editable) {\n const range = currentRange(editable);\n if (!range) return {};\n\n const container = range.isCollapsed()\n ? range.sc\n : range.commonAncestor();\n\n const el = isElement(container) ? container : container.parentElement;\n if (!el) return {};\n\n const computed = window.getComputedStyle(el);\n\n return {\n bold: document.queryCommandState('bold'),\n italic: document.queryCommandState('italic'),\n underline: document.queryCommandState('underline'),\n strikethrough: document.queryCommandState('strikeThrough'),\n superscript: document.queryCommandState('superscript'),\n subscript: document.queryCommandState('subscript'),\n fontSize: computed.fontSize,\n fontFamily: computed.fontFamily,\n color: computed.color,\n backgroundColor: computed.backgroundColor,\n textAlign: computed.textAlign,\n lineHeight: computed.lineHeight,\n formatBlock: (closest(el, isPara, editable) || { nodeName: 'p' }).nodeName.toLowerCase(),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Inline code toggle\n// ---------------------------------------------------------------------------\n\n/**\n * Wraps the selection in an inline <code> element, or unwraps it if the\n * cursor is already inside a <code> that is not inside a <pre>.\n * @param {HTMLElement} [editable]\n */\nexport function toggleInlineCode(editable) {\n const sel = window.getSelection();\n if (!sel || !sel.rangeCount) return;\n const range = sel.getRangeAt(0);\n let container = range.commonAncestorContainer;\n if (container.nodeType === 3) container = container.parentElement;\n const codeEl = container && container.closest ? container.closest('code') : null;\n if (codeEl && !codeEl.closest('pre')) {\n // Unwrap\n const parent = codeEl.parentNode;\n while (codeEl.firstChild) parent.insertBefore(codeEl.firstChild, codeEl);\n parent.removeChild(codeEl);\n if (editable) editable.normalize();\n } else {\n if (range.collapsed) return;\n try {\n const code = document.createElement('code');\n range.surroundContents(code);\n // Re-select wrapped content so subsequent format toggles work\n const newRange = document.createRange();\n newRange.selectNodeContents(code);\n sel.removeAllRanges();\n sel.addRange(newRange);\n } catch {\n // surroundContents fails across element boundaries — extract and rewrap\n const frag = range.extractContents();\n const code = document.createElement('code');\n code.appendChild(frag);\n range.insertNode(code);\n // Re-select wrapped content\n const newRange = document.createRange();\n newRange.selectNodeContents(code);\n sel.removeAllRanges();\n sel.addRange(newRange);\n }\n }\n}\n\n/**\n * Returns true when the cursor / selection is inside an inline <code>\n * (not nested in a <pre>).\n * @returns {boolean}\n */\nexport function isInlineCode() {\n const sel = window.getSelection();\n if (!sel || !sel.rangeCount) return false;\n let container = sel.getRangeAt(0).commonAncestorContainer;\n if (container.nodeType === 3) container = container.parentElement;\n const code = container && container.closest ? container.closest('code') : null;\n return !!(code && !code.closest('pre'));\n}\n\n// ---------------------------------------------------------------------------\n// Checklist (task list)\n// ---------------------------------------------------------------------------\n\n/**\n * Toggles a task-list at the cursor.\n * If inside a checklist <li>, converts it back to a <p>.\n * Otherwise inserts a new <ul class=\"an-checklist\"> with one item.\n */\nexport function toggleChecklist() {\n const sel = window.getSelection();\n if (!sel || !sel.rangeCount) return;\n const range = sel.getRangeAt(0);\n let container = range.commonAncestorContainer;\n if (container.nodeType === 3) container = container.parentElement;\n const li = container && container.closest ? container.closest('.an-checklist li') : null;\n if (li) {\n // Exit checklist — convert item to a <p>\n const ul = li.closest('.an-checklist');\n const text = Array.from(li.childNodes)\n .filter((n) => !(n.nodeType === 1 && n.tagName === 'INPUT'))\n .map((n) => n.textContent).join('').replace(/\\u00a0/g, ' ').trim();\n const p = document.createElement('p');\n p.textContent = text || '\\u00a0';\n ul.parentNode.insertBefore(p, ul.nextSibling);\n ul.removeChild(li);\n if (ul.children.length === 0) ul.remove();\n const nr = document.createRange();\n // Point into the text node (or first child) rather than the element node\n // so the cursor is at a well-defined text position, not element-offset 0.\n const startNode = p.firstChild || p;\n nr.setStart(startNode, 0);\n nr.collapse(true);\n sel.removeAllRanges();\n sel.addRange(nr);\n } else {\n // Use a temporary marker attribute so the new <li> can be found reliably\n // even when execCommand('insertHTML') places the cursor outside the list.\n // Chrome often moves the caret to a generated <p> after the <ul> rather\n // than staying inside the <li>, making a selection-based lookup fail.\n const MARKER = 'data-an-new-cli';\n execCommand('insertHTML',\n `<ul class=\"an-checklist\"><li ${MARKER}><input type=\"checkbox\" contenteditable=\"false\"></li></ul>`);\n const newLi = document.querySelector(`[${MARKER}]`);\n if (newLi) {\n newLi.removeAttribute(MARKER);\n const cbEl = newLi.querySelector('input[type=\"checkbox\"]');\n if (cbEl) {\n // Use \\u200B (zero-width space) instead of an empty string.\n // Chrome does not reliably honour a Selection pointing into an empty\n // text node and may silently normalise it to an element-level offset,\n // rendering the caret before the absolutely-positioned checkbox.\n // \\u200B is invisible/zero-width and is stripped by getHTML().\n let textNode = cbEl.nextSibling;\n if (!textNode || textNode.nodeType !== Node.TEXT_NODE) {\n textNode = document.createTextNode('\\u200B');\n newLi.appendChild(textNode);\n } else if (!textNode.textContent) {\n textNode.textContent = '\\u200B';\n }\n const nr = document.createRange();\n nr.setStart(textNode, 0);\n nr.collapse(true);\n sel.removeAllRanges();\n sel.addRange(nr);\n }\n }\n }\n}\n\n/**\n * Returns true when the cursor is inside a checklist item.\n * @returns {boolean}\n */\nexport function isInChecklist() {\n const sel = window.getSelection();\n if (!sel || !sel.rangeCount) return false;\n let container = sel.getRangeAt(0).commonAncestorContainer;\n if (container.nodeType === 3) container = container.parentElement;\n return !!(container && container.closest && container.closest('.an-checklist li'));\n}\n","/**\n * Buttons.js - Toolbar button definitions and factories\n * All buttons are plain objects describing their appearance and action.\n * They are rendered by the Toolbar module.\n */\n\nimport * as Style from '../editing/Style.js';\n\n// ---------------------------------------------------------------------------\n// Dropdown definition helper\n// ---------------------------------------------------------------------------\n\n/**\n * @typedef {object} DropdownDef\n * @property {string} name - unique identifier\n * @property {'select'} type - discriminator for Toolbar renderer\n * @property {string} tooltip\n * @property {string[]} [items] - overridden at render time from options\n * @property {Function} action - called with (context, value)\n * @property {Function} [getValue] - called with (context) to get current value\n */\n\n// ---------------------------------------------------------------------------\n// Button factory helpers\n// ---------------------------------------------------------------------------\n\n/**\n * @typedef {object} ButtonDef\n * @property {string} name - unique identifier\n * @property {string} icon - SVG or HTML icon markup / text\n * @property {string} tooltip - tooltip string\n * @property {Function} action - called with (context) when clicked\n * @property {Function} [isActive] - called with (context) to determine active state\n * @property {Function} [isDisabled] - called with (context) to determine disabled state\n * @property {string} [className] - extra CSS class(es)\n */\n\n/**\n * Creates a simple button definition.\n * @param {string} name\n * @param {string} icon\n * @param {string} tooltip\n * @param {Function} action\n * @param {Function} [isActive]\n * @param {Function} [isDisabled]\n * @returns {ButtonDef}\n */\nfunction btn(name, icon, tooltip, action, isActive, isDisabled) {\n // `icon` is an identifier (e.g. 'bold', 'italic'). Rendering to\n // visual markup (FontAwesome or fallback) is done in Toolbar._createButton\n return { name, icon, tooltip, action, isActive, isDisabled };\n}\n\n// ---------------------------------------------------------------------------\n// Style buttons\n// ---------------------------------------------------------------------------\n\nexport const boldBtn = btn('bold', 'bold', 'Bold (Ctrl+B)', () => Style.bold(), () => document.queryCommandState('bold'));\nexport const italicBtn = btn('italic', 'italic', 'Italic (Ctrl+I)', () => Style.italic(), () => document.queryCommandState('italic'));\nexport const underlineBtn = btn('underline', 'underline', 'Underline (Ctrl+U)', () => Style.underline(), () => {\n // queryCommandState('underline') is unreliable inside <code> elements;\n // also check for a <u> ancestor in the DOM.\n if (document.queryCommandState('underline')) return true;\n const sel = window.getSelection();\n if (!sel || !sel.rangeCount) return false;\n let container = sel.getRangeAt(0).commonAncestorContainer;\n if (container.nodeType === 3) container = container.parentElement;\n return !!(container && container.closest && container.closest('u'));\n});\nexport const strikeBtn = btn('strikethrough', 'strikethrough', 'Strikethrough', () => Style.strikethrough(), () => document.queryCommandState('strikeThrough'));\nexport const superscriptBtn = btn('superscript', 'superscript', 'Superscript', () => Style.superscript(), () => document.queryCommandState('superscript'));\nexport const subscriptBtn = btn('subscript', 'subscript', 'Subscript', () => Style.subscript(), () => document.queryCommandState('subscript'));\n\n// ---------------------------------------------------------------------------\n// Alignment buttons\n// ---------------------------------------------------------------------------\n\nexport const alignLeftBtn = btn('alignLeft', 'align-left', 'Align Left', () => Style.justifyLeft());\nexport const alignCenterBtn = btn('alignCenter', 'align-center', 'Align Center', () => Style.justifyCenter());\nexport const alignRightBtn = btn('alignRight', 'align-right', 'Align Right', () => Style.justifyRight());\nexport const alignJustifyBtn = btn('alignJustify', 'align-justify', 'Justify', () => Style.justifyFull());\n\n// ---------------------------------------------------------------------------\n// List buttons\n// ---------------------------------------------------------------------------\n\nexport const ulBtn = btn('ul', 'list-ul', 'Unordered List', () => Style.insertUnorderedList());\nexport const olBtn = btn('ol', 'list-ol', 'Ordered List', () => Style.insertOrderedList());\n\n// ---------------------------------------------------------------------------\n// Indent buttons\n// ---------------------------------------------------------------------------\n\nexport const indentBtn = btn('indent', 'indent', 'Indent', () => Style.indent());\nexport const outdentBtn = btn('outdent', 'outdent', 'Outdent', () => Style.outdent());\n\n// ---------------------------------------------------------------------------\n// Undo / redo buttons\n// ---------------------------------------------------------------------------\n\nexport const undoBtn = btn('undo', 'undo', 'Undo (Ctrl+Z)', (_ctx) => _ctx.invoke('editor.undo'), undefined, (ctx) => !ctx.invoke('editor.canUndo'));\nexport const redoBtn = btn('redo', 'redo', 'Redo (Ctrl+Y)', (_ctx) => _ctx.invoke('editor.redo'), undefined, (ctx) => !ctx.invoke('editor.canRedo'));\n\n// ---------------------------------------------------------------------------\n// Insert media — HR, Link, Image\n// ---------------------------------------------------------------------------\n\nexport const hrBtn = btn('hr', 'minus', 'Horizontal Rule', () => Style.execCommand('insertHorizontalRule'));\nexport const linkBtn = btn('link', 'link', 'Insert Link', (ctx) => ctx.invoke('linkDialog.show'));\nexport const imageBtn = btn('image', 'image', 'Insert Image', (ctx) => ctx.invoke('imageDialog.show'));\nexport const videoBtn = btn('video', 'video', 'Insert Video', (ctx) => ctx.invoke('videoDialog.show'));\nexport const emojiBtn = btn('emoji', 'emoji', 'Insert Emoji', (ctx) => ctx.invoke('emojiDialog.show'));\nexport const iconBtn = btn('icon', 'icon', 'Insert FA Icon', (ctx) => ctx.invoke('iconDialog.show'));\n\n/** @type {ButtonDef & { type: 'grid' }} */\nexport const tableBtn = {\n name: 'table',\n type: 'grid',\n icon: 'table',\n tooltip: 'Insert Table',\n action: (ctx, rows, cols) => {\n ctx.invoke('editor.insertTable', cols, rows);\n ctx.invoke('editor.afterCommand');\n },\n};\n\n// ---------------------------------------------------------------------------\n// Font size dropdown\n// ---------------------------------------------------------------------------\n\n/** @type {DropdownDef} */\nexport const fontSizeBtn = {\n name: 'fontSize',\n type: 'select',\n tooltip: 'Font Size',\n placeholder: 'Size',\n selectClass: 'an-select-narrow',\n items: ['8px', '10px', '11px', '12px', '13px', '14px', '16px', '18px', '20px', '24px', '28px', '32px', '36px', '48px', '72px'],\n action: (ctx, value) => Style.fontSize(value, ctx.layoutInfo.editable),\n getValue: (ctx) => {\n try {\n const sel = window.getSelection();\n if (sel && sel.rangeCount) {\n let el = sel.getRangeAt(0).startContainer;\n if (el.nodeType === 3) el = el.parentElement;\n while (el && el.nodeType === 1 && !el.style.fontSize) el = el.parentElement;\n const size = (el && el.style && el.style.fontSize) ? el.style.fontSize : '';\n if (size) return size;\n }\n // Fallback: read the base font size from the editable element itself\n const editable = ctx && ctx.layoutInfo && ctx.layoutInfo.editable;\n if (editable) return editable.style.fontSize || '';\n return '';\n } catch { return ''; }\n },\n};\n\n// ---------------------------------------------------------------------------\n// Remove format button\n// ---------------------------------------------------------------------------\n\nexport const removeFormatBtn = btn('removeFormat', 'remove-format', 'Remove Format', () => Style.execCommand('removeFormat'));\n\n// ---------------------------------------------------------------------------\n// Direction (LTR / RTL) toggle button\n// ---------------------------------------------------------------------------\n\nexport const directionBtn = btn(\n 'direction',\n 'direction',\n 'Toggle Text Direction (LTR / RTL)',\n (ctx) => {\n const editable = ctx.layoutInfo.editable;\n const current = editable.getAttribute('dir') || 'ltr';\n const next = current === 'ltr' ? 'rtl' : 'ltr';\n editable.setAttribute('dir', next);\n editable.style.textAlign = next === 'rtl' ? 'right' : 'left';\n ctx.invoke('editor.afterCommand');\n },\n);\n\n// ---------------------------------------------------------------------------\n// Font family dropdown\n// ---------------------------------------------------------------------------\n\n/** @type {DropdownDef} */\nexport const fontFamilyBtn = {\n name: 'fontFamily',\n type: 'select',\n tooltip: 'Font Family',\n action: (ctx, value) => Style.fontName(value),\n getValue: () => {\n try { return document.queryCommandValue('fontName') || ''; } catch { return ''; }\n },\n};\n\n// ---------------------------------------------------------------------------\n// Paragraph style dropdown (Normal / H1-H6 / Quote / Code)\n// ---------------------------------------------------------------------------\n\n/** @type {DropdownDef} */\nexport const paragraphStyleBtn = {\n name: 'paragraphStyle',\n type: 'select',\n tooltip: 'Paragraph Style',\n placeholder: 'Style',\n selectClass: 'an-select-style',\n items: [\n { value: 'p', label: 'Normal' },\n { value: 'h1', label: 'H1' },\n { value: 'h2', label: 'H2' },\n { value: 'h3', label: 'H3' },\n { value: 'h4', label: 'H4' },\n { value: 'h5', label: 'H5' },\n { value: 'h6', label: 'H6' },\n { value: 'blockquote', label: 'Quote' },\n { value: 'pre', label: 'Code' },\n ],\n action: (_ctx, value) => Style.formatBlock(value),\n getValue: () => {\n try {\n const raw = document.queryCommandValue('formatBlock').toLowerCase().replace(/[<>]/g, '');\n return raw === 'div' ? 'p' : (raw || 'p');\n } catch { return ''; }\n },\n};\n\n// ---------------------------------------------------------------------------\n// Line-height dropdown\n// ---------------------------------------------------------------------------\n\n/** @type {DropdownDef} */\nexport const lineHeightBtn = {\n name: 'lineHeight',\n type: 'select',\n tooltip: 'Line Height',\n placeholder: '\\u2195 Line',\n selectClass: 'an-select-narrow',\n items: ['1.0', '1.15', '1.5', '1.75', '2.0', '2.5', '3.0'],\n action: (_ctx, value) => Style.lineHeight(value),\n getValue: () => {\n try {\n const sel = window.getSelection();\n if (!sel || !sel.rangeCount) return '';\n const BLOCKS = new Set(['P','DIV','H1','H2','H3','H4','H5','H6','LI','BLOCKQUOTE','PRE','TD','TH']);\n let el = sel.getRangeAt(0).startContainer;\n if (el.nodeType === 3) el = el.parentElement;\n while (el && !BLOCKS.has(el.tagName)) el = el.parentElement;\n if (!el) return '';\n return el.style.lineHeight || getComputedStyle(el).lineHeight || '';\n } catch { return ''; }\n },\n};\n\n// ---------------------------------------------------------------------------\n// Code view / fullscreen\n// ---------------------------------------------------------------------------\n\nexport const codeviewBtn = btn('codeview', 'code', 'HTML Code View', (ctx) => ctx.invoke('codeview.toggle'), (ctx) => ctx.invoke('codeview.isActive'));\nexport const fullscreenBtn = btn('fullscreen', 'expand', 'Fullscreen', (ctx) => ctx.invoke('fullscreen.toggle'), (ctx) => ctx.invoke('fullscreen.isActive'));\nexport const shortcutsBtn = btn('shortcuts', 'keyboard', 'Keyboard Shortcuts (Ctrl+Shift+/)', (ctx) => ctx.invoke('shortcutsDialog.show'));\nexport const findBtn = btn('find', 'search', 'Find (Ctrl+F)', (ctx) => ctx.invoke('findReplace.show', 'find'));\nexport const findReplaceBtn = btn('findReplace', 'find-replace', 'Find & Replace (Ctrl+H)', (ctx) => ctx.invoke('findReplace.show', 'replace'));\nexport const inlineCodeBtn = btn('inlineCode', 'inline-code', 'Inline Code (Ctrl+`)', (ctx) => ctx.invoke('editor.inlineCode'), () => Style.isInlineCode());\nexport const checklistBtn = btn('checklist', 'checklist', 'Checklist', (ctx) => ctx.invoke('editor.toggleChecklist'), () => Style.isInChecklist());\nexport const printBtn = btn('print', 'print', 'Print', (ctx) => ctx.invoke('editor.print'));\n\n// ---------------------------------------------------------------------------\n// Text / background colour pickers\n// ---------------------------------------------------------------------------\n\n/** @type {{ name: string, type: 'colorpicker', icon: string, tooltip: string, defaultColor: string, action: Function }} */\nexport const foreColorBtn = {\n name: 'foreColor',\n type: 'colorpicker',\n icon: 'foreColor',\n tooltip: 'Text Color',\n defaultColor: '#e11d48',\n action: (ctx, color) => Style.foreColor(color),\n};\n\n/** @type {{ name: string, type: 'colorpicker', icon: string, tooltip: string, defaultColor: string, action: Function }} */\nexport const backColorBtn = {\n name: 'backColor',\n type: 'colorpicker',\n icon: 'backColor',\n tooltip: 'Highlight Color',\n defaultColor: '#fbbf24',\n action: (ctx, color) => Style.backColor(color),\n};\n\n// ---------------------------------------------------------------------------\n// Default toolbar layout\n// ---------------------------------------------------------------------------\n\n/**\n * The default toolbar button groups.\n * Each sub-array is a button group (separated by a divider).\n */\nexport const defaultToolbar = [\n [paragraphStyleBtn, fontFamilyBtn, fontSizeBtn, lineHeightBtn],\n [undoBtn, redoBtn],\n [boldBtn, italicBtn, underlineBtn, strikeBtn, inlineCodeBtn],\n [superscriptBtn, subscriptBtn],\n [foreColorBtn, backColorBtn],\n [alignLeftBtn, alignCenterBtn, alignRightBtn, alignJustifyBtn],\n [ulBtn, olBtn, checklistBtn, indentBtn, outdentBtn],\n [hrBtn, linkBtn, imageBtn, videoBtn, tableBtn, emojiBtn, iconBtn],\n [removeFormatBtn, codeviewBtn, fullscreenBtn, findBtn, printBtn, shortcutsBtn],\n];\n","/**\n * settings.js - Default editor options\n * Inspired by Summernote's settings.js\n */\n\nimport { defaultToolbar } from './module/Buttons.js';\n\n/**\n * @typedef {object} AsnOptions\n * @property {string} [placeholder] - Placeholder text when editor is empty\n * @property {number} [height] - Editor height in px (min)\n * @property {number} [minHeight] - Minimum height in px\n * @property {number} [maxHeight] - Maximum height in px (0 = unlimited)\n * @property {boolean} [focus] - Auto-focus on init\n * @property {boolean} [resizable] - Show resize handle\n * @property {Array} [toolbar] - Toolbar button group config\n * @property {boolean} [pasteAsPlainText] - Force plain-text paste\n * @property {boolean} [pasteCleanHTML] - Sanitise HTML on paste\n * @property {boolean} [pasteStripAttributes] - Strip class/style/data-* from pasted HTML (default: false)\n * @property {boolean} [allowImageUpload] - Allow file upload in image dialog\n * @property {number} [maxImageSize] - Max upload size in MB\n * @property {number} [tabSize] - Spaces per tab in non-list context\n * @property {Function} [onChange] - Callback on content change\n * @property {Function} [onFocus] - Callback on focus\n * @property {Function} [onBlur] - Callback on blur\n * @property {Function} [onImageUpload] - Custom upload handler: (files) => void\n * @property {boolean} [stickyToolbar] - Stick the toolbar to the viewport top when scrolling\n * @property {number} [stickyToolbarOffset] - Top offset in px for sticky toolbar (e.g. fixed nav height)\n * @property {string} [theme] - 'light' (default) | 'dark'\n * @property {boolean} [codeHighlight] - Auto-load Prism.js for syntax highlighting of code blocks\n * @property {string} [codeHighlightCDN] - CDN base URL for Prism assets (defaults to cdnjs)\n * @property {boolean} [markdownPaste] - Convert pasted Markdown text to HTML (default: true)\n * @property {boolean} [readOnly] - Start editor in read-only / non-editable mode\n * @property {boolean} [spellcheck] - Enable browser spellcheck in the editable area (default: true)\n * @property {string} [direction] - Text direction: 'ltr' (default) | 'rtl'\n * @property {string} [toolbarOverflow] - Toolbar overflow strategy: 'wrap' (default) | 'scroll'\n * @property {boolean} [autoSave] - Auto-save content to localStorage on change\n * @property {string} [autoSaveKey] - localStorage key used for auto-save (default: 'autumnnote-autosave')\n * @property {number} [maxChars] - Maximum character count (0 = unlimited). Shows warning in statusbar.\n * @property {number} [maxWords] - Maximum word count (0 = unlimited). Shows warning in statusbar.\n * @property {boolean} [tableHeaderRow] - Insert a header row (<thead><th>) when creating tables\n * @property {Function} [onPaste] - Callback fired on every paste: ({ text, html }) => void\n * @property {Function} [onSelectionChange] - Callback fired on cursor/selection change: (context) => void\n * @property {string[]} [colorSwatches] - Custom brand colour swatches prepended to the colour-picker palette\n * @property {Function} [onDestroy] - Callback fired when the editor is destroyed: (context) => void\n * @property {Function} [onCharLimitReached] - Callback fired when the character limit is hit: (context) => void\n * @property {Function} [onWordLimitReached] - Callback fired when the word limit is hit: (context) => void\n * @property {string} [focusColor] - Custom focus ring colour, e.g. '#f97316'. Overrides the default blue.\n */\n\n/** @type {AsnOptions} */\nexport const defaultOptions = {\n placeholder: '',\n height: 200,\n minHeight: 100,\n maxHeight: 0,\n focus: false,\n resizable: true,\n toolbar: defaultToolbar,\n // UI integration options\n // If `useBootstrap` is true, toolbar buttons will use the Bootstrap button classes\n // (set `toolbarButtonClass` to customize). Works with Bootstrap 4 and 5.\n useBootstrap: false,\n toolbarButtonClass: 'btn btn-sm btn-light',\n // Icon options — uses Font Awesome by default. Consumers must include Font Awesome CSS.\n useFontAwesome: true,\n // Default FontAwesome prefix — 'fas' for FA5, 'fa-solid' for FA6. Change if needed.\n fontAwesomeClass: 'fas',\n pasteAsPlainText: false,\n pasteCleanHTML: true,\n pasteStripAttributes: false,\n allowImageUpload: true,\n maxImageSize: 5,\n tabSize: 4,\n onChange: null,\n onFocus: null,\n onBlur: null,\n onInit: null,\n onImageUpload: null,\n onImageError: null,\n stickyToolbar: false,\n stickyToolbarOffset: 0,\n theme: 'light',\n codeHighlight: true,\n codeHighlightCDN: 'https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0',\n markdownPaste: true,\n historyLimit: 100,\n // Default font family applied to the editor and shown in the dropdown when no explicit font is set\n defaultFontFamily: 'Arial',\n // Default font size applied to the editor and shown in the size dropdown when no explicit size is set\n defaultFontSize: '14px',\n // Font families shown in the toolbar font-family dropdown\n fontFamilies: [\n 'Arial',\n 'Arial Black',\n 'Comic Sans MS',\n 'Courier New',\n 'Georgia',\n 'Impact',\n 'Tahoma',\n 'Times New Roman',\n 'Trebuchet MS',\n 'Verdana',\n ],\n // Read-only mode — disables all editing when true\n readOnly: false,\n // Enable/disable browser spell-check on the editable area\n spellcheck: true,\n // Text direction: 'ltr' (default) or 'rtl'\n direction: 'ltr',\n // How the toolbar handles overflow: 'wrap' (default, wraps to next line) or 'scroll' (single scrollable row)\n toolbarOverflow: 'wrap',\n // Auto-save content to localStorage on every change\n autoSave: false,\n // localStorage key used when autoSave is enabled\n autoSaveKey: 'autumnnote-autosave',\n // Maximum character count (0 = unlimited)\n maxChars: 0,\n // Maximum word count (0 = unlimited)\n maxWords: 0,\n // Insert a header row (<thead>) when creating new tables\n tableHeaderRow: false,\n // Callback fired on every cursor/selection change inside the editor\n onSelectionChange: null,\n // Custom brand colour swatches to prepend to the toolbar colour-picker palette\n colorSwatches: [],\n // Callback fired after a paste event: function({ text, html })\n onPaste: null,\n // Callback fired just before the editor instance is destroyed\n onDestroy: null,\n // Callback fired when the character limit is reached: function(context)\n onCharLimitReached: null,\n // Callback fired when the word limit is reached: function(context)\n onWordLimitReached: null,\n // Custom focus ring colour — overrides the default blue when set.\n // Accepts any valid CSS colour string, e.g. '#f97316', 'hsl(25,90%,55%)'.\n focusColor: null,\n};\n","/**\n * sanitise.js - Shared HTML and URL sanitisation utilities\n *\n * Single source of truth used by Editor, Clipboard, Codeview, and renderer.\n * DOM-parser based — no regex-based stripping of HTML (avoids bypass tricks).\n */\n\n/** Tags that are unconditionally removed from editor content. */\nconst PROHIBITED_TAGS = ['script', 'style', 'iframe', 'object', 'embed', 'form', 'input', 'button'];\n\n/** Attributes whose values must be sanitised as URLs. */\nconst URL_ATTRS = ['href', 'src', 'action', 'formaction'];\n\n/** Trusted hosts for iframe embeds when allowIframes is enabled. */\nconst TRUSTED_IFRAME_HOSTS = new Set([\n 'www.youtube.com',\n 'youtube.com',\n 'm.youtube.com',\n 'www.youtube-nocookie.com',\n 'youtube-nocookie.com',\n 'player.vimeo.com',\n]);\n\n/**\n * Sanitises an HTML string by removing dangerous elements and attributes.\n * Uses DOMParser so the sanitisation follows normal browser parsing rules —\n * no regex shortcuts that can be bypassed by encoding tricks.\n *\n * - Strips PROHIBITED_TAGS (script, style, iframe, object, embed, form, input, button)\n * - Removes all on* event-handler attributes\n * - Rejects javascript: and vbscript: URLs in URL attributes\n * - Rejects data: URIs everywhere except img[src] (base64 uploads)\n *\n * @param {string} html\n * @returns {string}\n */\nexport function sanitiseHTML(html, { allowIframes = false } = {}) {\n const doc = new DOMParser().parseFromString(`<body>${html || ''}</body>`, 'text/html');\n\n // Remove outright dangerous elements (optionally preserve iframes for video embeds)\n const tags = allowIframes ? PROHIBITED_TAGS.filter((t) => t !== 'iframe') : PROHIBITED_TAGS;\n tags.forEach((tag) => {\n doc.querySelectorAll(tag).forEach((el) => el.remove());\n });\n\n // Strip dangerous attributes from remaining elements\n doc.querySelectorAll('*').forEach((el) => {\n Array.from(el.attributes).forEach((attr) => {\n // Remove all event handlers (onclick, onload, onerror, …)\n if (attr.name.startsWith('on')) {\n el.removeAttribute(attr.name);\n return;\n }\n // Sanitise URL attributes\n if (URL_ATTRS.includes(attr.name)) {\n const val = attr.value.trim();\n // Block javascript: and vbscript: protocols\n if (/^(javascript|vbscript):/i.test(val)) {\n el.removeAttribute(attr.name);\n return;\n }\n // Allow data: URIs only on img[src] (base64 image uploads); block elsewhere\n if (/^data:/i.test(val) && !(attr.name === 'src' && el.tagName === 'IMG')) {\n el.removeAttribute(attr.name);\n }\n }\n\n // Strip iframe HTML-injection vectors and limit iframe src to trusted hosts.\n if (el.tagName === 'IFRAME') {\n if (attr.name === 'srcdoc') {\n el.removeAttribute(attr.name);\n return;\n }\n if (attr.name === 'src') {\n if (!isTrustedIframeSrc(attr.value)) {\n el.removeAttribute(attr.name);\n }\n return;\n }\n }\n });\n });\n\n return doc.body.innerHTML;\n}\n\n/**\n * Returns true if iframe src points to an approved video host.\n * Relative, protocol-relative and invalid URLs are rejected.\n * @param {string} src\n * @returns {boolean}\n */\nfunction isTrustedIframeSrc(src) {\n const trimmed = (src || '').trim();\n if (!trimmed) return false;\n if (trimmed.startsWith('//') || trimmed.startsWith('/')) return false;\n try {\n const url = new URL(trimmed);\n if (url.protocol !== 'https:') return false;\n return TRUSTED_IFRAME_HOSTS.has(url.hostname.toLowerCase());\n } catch {\n return false;\n }\n}\n\n/**\n * Sanitises a URL string, rejecting dangerous protocols.\n *\n * Blocked protocols: javascript:, vbscript:\n * Optionally blocked: data: (safe to allow for img/src base64 embeds)\n *\n * @param {string} url\n * @param {{ allowData?: boolean }} [opts]\n * @returns {string|null} The original URL if safe, null if rejected.\n */\nexport function sanitiseUrl(url, { allowData = false } = {}) {\n const trimmed = (url || '').trim();\n if (/^(javascript|vbscript):/i.test(trimmed)) return null;\n if (!allowData && /^data:/i.test(trimmed)) return null;\n return url;\n}\n","/**\n * renderer.js - Builds the editor DOM structure\n * Inspired by Summernote's renderer.js\n */\n\nimport { createElement } from './core/dom.js';\nimport { sanitiseHTML } from './core/sanitise.js';\n\n/**\n * Renders the editor layout around the original element.\n *\n * Structure:\n * <div class=\"an-container\">\n * <div class=\"an-toolbar\">...</div>\n * <div class=\"an-editable\" contenteditable=\"true\">...</div>\n * <div class=\"an-statusbar\">...</div>\n * </div>\n *\n * @param {HTMLElement} targetEl - the original element to replace/wrap\n * @param {import('./settings.js').AsnOptions} options\n * @returns {{ container: HTMLElement, editable: HTMLElement }}\n */\nexport function renderLayout(targetEl, options) {\n const container = createElement('div', { class: 'an-container' });\n\n // Editable area\n const editable = createElement('div', {\n class: 'an-editable',\n contenteditable: options.readOnly ? 'false' : 'true',\n spellcheck: String(options.spellcheck !== false),\n 'aria-multiline': 'true',\n 'aria-label': 'Rich text editor',\n role: 'textbox',\n });\n\n // Restore auto-saved content when available; fall back to element content\n let initialContent = '';\n if (options.autoSave && options.autoSaveKey) {\n try { initialContent = localStorage.getItem(options.autoSaveKey) || ''; } catch (_) {}\n }\n if (!initialContent) {\n initialContent = targetEl.tagName === 'TEXTAREA'\n ? (targetEl.value || '').trim()\n : (targetEl.innerHTML || '').trim();\n }\n editable.innerHTML = sanitiseHTML(initialContent, { allowIframes: true });\n\n // Apply default font family so the editable renders in the configured font\n const defaultFont = options.defaultFontFamily || (options.fontFamilies && options.fontFamilies[0]);\n if (defaultFont) {\n editable.style.fontFamily = defaultFont;\n }\n\n // Apply default font size so the size dropdown shows the correct value on startup\n if (options.defaultFontSize) {\n editable.style.fontSize = options.defaultFontSize;\n }\n\n // Apply height options.\n // `height` sets the initial visible height (takes priority).\n // `minHeight` is the drag-resize floor — only applied when no explicit `height` is given.\n if (options.height) {\n editable.style.minHeight = `${options.height}px`;\n } else if (options.minHeight) {\n editable.style.minHeight = `${options.minHeight}px`;\n }\n if (options.maxHeight) {\n editable.style.maxHeight = `${options.maxHeight}px`;\n }\n\n container.appendChild(editable);\n\n // Apply dark theme\n if (options.theme === 'dark') {\n container.classList.add('an-theme-dark');\n }\n\n // Read-only mode\n if (options.readOnly) {\n container.classList.add('an-disabled');\n }\n\n // Text direction\n if (options.direction === 'rtl') {\n editable.setAttribute('dir', 'rtl');\n container.classList.add('an-dir-rtl');\n }\n\n // Toolbar overflow\n if (options.toolbarOverflow === 'scroll') {\n container.classList.add('an-toolbar-overflow-scroll');\n }\n\n // Configure sticky toolbar\n if (options.stickyToolbar) {\n container.classList.add('an-sticky-toolbar');\n if (options.stickyToolbarOffset) {\n container.style.setProperty('--an-sticky-top', `${options.stickyToolbarOffset}px`);\n }\n }\n\n // Custom focus ring colour\n if (options.focusColor) {\n container.style.setProperty('--an-focus-color', options.focusColor);\n }\n\n // Hide the original element; keep it in DOM for form submission\n targetEl.style.display = 'none';\n targetEl.insertAdjacentElement('afterend', container);\n\n return { container, editable };\n}\n","/**\n * History.js - Undo / redo stack for editor content\n * Inspired by Summernote's History module, rewritten without jQuery\n */\n\nexport class History {\n /**\n * @param {HTMLElement} editable - the contenteditable element\n * @param {number} [limit=100] - maximum number of undo/redo states\n */\n constructor(editable, limit = 100) {\n this.editable = editable;\n this._limit = limit;\n /** @type {Array<{html: string, range: {sc: string, so: number, ec: string, eo: number}|null}>} */\n this.stack = [];\n this.stackOffset = -1;\n this._savePoint();\n }\n\n // ---------------------------------------------------------------------------\n // Private helpers\n // ---------------------------------------------------------------------------\n\n _serialize() {\n return this.editable.innerHTML;\n }\n\n /**\n * Serializes the current selection as character offsets from the start of\n * the editable element, so it can be restored after innerHTML replacement.\n * @returns {{ start: number, end: number }|null}\n */\n _serializeSelection() {\n const sel = window.getSelection();\n if (!sel || sel.rangeCount === 0) return null;\n const range = sel.getRangeAt(0);\n if (!this.editable.contains(range.startContainer)) return null;\n return {\n start: this._charOffset(range.startContainer, range.startOffset),\n end: this._charOffset(range.endContainer, range.endOffset),\n };\n }\n\n /**\n * Returns the character offset of (node, offset) from the beginning of\n * the editable's text content.\n * @param {Node} node\n * @param {number} offset\n * @returns {number}\n */\n _charOffset(node, offset) {\n let count = 0;\n const walker = document.createTreeWalker(this.editable, NodeFilter.SHOW_TEXT, null);\n let cur;\n while ((cur = walker.nextNode())) {\n if (cur === node) return count + offset;\n count += cur.length;\n }\n return 0;\n }\n\n /**\n * Restores a previously serialized selection inside the editable.\n * @param {{ start: number, end: number }|null} saved\n */\n _restoreSelection(saved) {\n if (!saved) return;\n let startNode = null, startOff = 0;\n let endNode = null, endOff = 0;\n let count = 0;\n const walker = document.createTreeWalker(this.editable, NodeFilter.SHOW_TEXT, null);\n let cur;\n while ((cur = walker.nextNode())) {\n const len = cur.length;\n if (!startNode && count + len >= saved.start) {\n startNode = cur;\n startOff = saved.start - count;\n }\n if (!endNode && count + len >= saved.end) {\n endNode = cur;\n endOff = saved.end - count;\n break;\n }\n count += len;\n }\n if (!startNode) {\n // Offset exceeds content (e.g. undo to a shorter state): place at end\n const lastWalker = document.createTreeWalker(this.editable, NodeFilter.SHOW_TEXT, null);\n let lastNode = null;\n while ((lastNode = lastWalker.nextNode())) { startNode = lastNode; }\n startOff = startNode ? startNode.length : 0;\n endNode = startNode;\n endOff = startOff;\n }\n if (!endNode) { endNode = startNode; endOff = startOff; }\n try {\n const range = document.createRange();\n range.setStart(startNode, startOff);\n range.setEnd(endNode, endOff);\n const sel = window.getSelection();\n sel.removeAllRanges();\n sel.addRange(range);\n } catch (_) { /* detached node — ignore */ }\n }\n\n _savePoint() {\n // Trim future history if we're mid-stack\n if (this.stackOffset < this.stack.length - 1) {\n this.stack = this.stack.slice(0, this.stackOffset + 1);\n }\n const raw = this._serialize();\n const { html, images } = this._tokenizeImages(raw);\n this.stack.push({ html, images, sel: this._serializeSelection() });\n if (this.stack.length > this._limit) {\n this.stack.shift();\n } else {\n this.stackOffset++;\n }\n }\n\n _restore(point) {\n if (!point) return;\n this.editable.innerHTML = this._detokenizeImages(point);\n this._restoreSelection(point.sel);\n }\n\n // ---------------------------------------------------------------------------\n // Base64 tokenisation — keeps snapshot strings small so that the\n // per-keystroke `recordUndo` string comparison stays fast even when the\n // editor contains large embedded images.\n // ---------------------------------------------------------------------------\n\n /**\n * Replaces every `data:…;base64,…` occurrence in `html` with a compact\n * token `__asn_img_0__`, `__asn_img_1__`, … and returns the tokenized\n * string together with a map from token → original data URL.\n * @param {string} html\n * @returns {{ html: string, images: Object<string,string> }}\n */\n _tokenizeImages(html) {\n const images = {};\n let index = 0;\n const tokenized = html.replace(/data:[^;]+;base64,[^\"' >]*/g, (match) => {\n const token = `__asn_img_${index}__`;\n images[token] = match;\n index++;\n return token;\n });\n return { html: tokenized, images };\n }\n\n /**\n * Restores a snapshot by replacing tokens back with their data URLs.\n * @param {{ html: string, images: Object<string,string> }} point\n * @returns {string}\n */\n _detokenizeImages(point) {\n if (!point.images || Object.keys(point.images).length === 0) return point.html;\n return point.html.replace(/__asn_img_\\d+__/g, (token) => point.images[token] || token);\n }\n\n // ---------------------------------------------------------------------------\n // Public API\n // ---------------------------------------------------------------------------\n\n /**\n * Records the current editor state as a history checkpoint.\n */\n recordUndo() {\n const current = this._serialize();\n const { html: tokenized } = this._tokenizeImages(current);\n const prev = this.stack[this.stackOffset];\n if (prev && prev.html === tokenized) return; // No change\n this._savePoint();\n }\n\n /**\n * Undo to the previous state.\n */\n undo() {\n if (this.stackOffset <= 0) return;\n this.stackOffset--;\n this._restore(this.stack[this.stackOffset]);\n }\n\n /**\n * Redo to the next state.\n */\n redo() {\n if (this.stackOffset >= this.stack.length - 1) return;\n this.stackOffset++;\n this._restore(this.stack[this.stackOffset]);\n }\n\n /**\n * Resets the history stack (e.g. on editor destroy or full content replace).\n */\n reset() {\n this.stack = [];\n this.stackOffset = -1;\n this._savePoint();\n }\n\n /** @returns {boolean} */\n canUndo() {\n return this.stackOffset > 0;\n }\n\n /** @returns {boolean} */\n canRedo() {\n return this.stackOffset < this.stack.length - 1;\n }\n}\n","/**\n * Table.js - Table creation and manipulation utilities\n * Inspired by Summernote's table handling\n */\n\nimport { createElement } from '../core/dom.js';\nimport { execCommand } from './Style.js';\n\n// ---------------------------------------------------------------------------\n// Table creation\n// ---------------------------------------------------------------------------\n\n/**\n * Creates a table element with the specified dimensions.\n * @param {number} cols\n * @param {number} rows\n * @param {{ headerRow?: boolean }} [opts]\n * @returns {HTMLTableElement}\n */\nexport function createTable(cols, rows, opts = {}) {\n const { headerRow = false } = opts;\n const table = createElement('table', { class: 'an-table' });\n\n if (headerRow && rows > 0) {\n const thead = createElement('thead');\n const tr = createElement('tr');\n for (let c = 0; c < cols; c++) {\n const th = createElement('th', {}, ['\\u00a0']);\n tr.appendChild(th);\n }\n thead.appendChild(tr);\n table.appendChild(thead);\n }\n\n const bodyRows = headerRow ? Math.max(rows - 1, 1) : rows;\n const tbody = createElement('tbody');\n table.appendChild(tbody);\n\n for (let r = 0; r < bodyRows; r++) {\n const tr = createElement('tr');\n for (let c = 0; c < cols; c++) {\n const td = createElement('td', {}, ['\\u00a0']); // \n tr.appendChild(td);\n }\n tbody.appendChild(tr);\n }\n return table;\n}\n\n/**\n * Inserts a table at the current cursor position.\n * @param {number} cols\n * @param {number} rows\n * @param {{ headerRow?: boolean }} [opts]\n */\nexport function insertTable(cols, rows, opts = {}) {\n const table = createTable(cols, rows, opts);\n execCommand('insertHTML', table.outerHTML);\n}\n","/**\n * key.js - Keyboard key code constants\n * Inspired by Summernote's key.js\n */\n\nexport const key = {\n BACKSPACE: 'Backspace',\n TAB: 'Tab',\n ENTER: 'Enter',\n ESCAPE: 'Escape',\n SPACE: ' ',\n PAGE_UP: 'PageUp',\n PAGE_DOWN: 'PageDown',\n END: 'End',\n HOME: 'Home',\n LEFT: 'ArrowLeft',\n UP: 'ArrowUp',\n RIGHT: 'ArrowRight',\n DOWN: 'ArrowDown',\n DELETE: 'Delete',\n // Numbers\n NUM0: '0',\n NUM1: '1',\n NUM2: '2',\n NUM3: '3',\n NUM4: '4',\n NUM5: '5',\n NUM6: '6',\n NUM7: '7',\n NUM8: '8',\n // Letters\n B: 'b',\n E: 'e',\n I: 'i',\n J: 'j',\n K: 'k',\n L: 'l',\n R: 'r',\n S: 's',\n U: 'u',\n V: 'v',\n Y: 'y',\n Z: 'z',\n SLASH: '/',\n PERIOD: '.',\n};\n\n/**\n * Returns true if the event matches the given key\n * @param {KeyboardEvent} event\n * @param {string} keyName - one of key.*\n * @returns {boolean}\n */\nexport function isKey(event, keyName) {\n return event.key === keyName || event.key === keyName.toUpperCase();\n}\n\n/**\n * Returns true if the event is a modifier key press (Ctrl/Cmd + key)\n * @param {KeyboardEvent} event\n * @param {string} keyName\n * @returns {boolean}\n */\nexport function isModifier(event, keyName) {\n return (event.ctrlKey || event.metaKey) && isKey(event, keyName);\n}\n","/**\n * Typing.js - Keyboard typing event handling (Enter, Tab, Backspace behaviour)\n * Inspired by Summernote's Typing module\n */\n\nimport { key, isKey } from '../core/key.js';\nimport { closestPara, isLi } from '../core/dom.js';\nimport { execCommand } from './Style.js';\nimport { currentRange } from '../core/range.js';\n\n/**\n * Handles special keydown behaviour inside the editor.\n * @param {KeyboardEvent} event\n * @param {HTMLElement} editable\n * @param {object} options - editor options\n * @returns {boolean} true if the event was consumed\n */\nexport function handleKeydown(event, editable, options = {}) {\n const isFAIcon = (n) => !!(n && n.nodeName === 'I' && /\\bfa-/.test(n.className || ''));\n const isZwsAnchor = (n) => !!(n && n.nodeType === Node.TEXT_NODE && (n.textContent === '\\u200B' || n.textContent === ''));\n const moveCaret = (setFn) => {\n const sel = window.getSelection();\n if (!sel) return false;\n const nr = document.createRange();\n setFn(nr);\n nr.collapse(true);\n sel.removeAllRanges();\n sel.addRange(nr);\n return true;\n };\n\n // -------------------------------------------------------------------------\n // Backspace key — one-press deletion of a preceding FA icon (<i> element)\n // -------------------------------------------------------------------------\n if (isKey(event, key.BACKSPACE)) {\n const sel = window.getSelection();\n if (sel && sel.rangeCount > 0) {\n const r = sel.getRangeAt(0);\n if (r.collapsed && r.startContainer.nodeType === Node.TEXT_NODE) {\n const textNode = r.startContainer;\n // Case A: cursor at offset 0, preceding sibling is an FA icon\n if (r.startOffset === 0 && isFAIcon(textNode.previousSibling)) {\n event.preventDefault();\n textNode.previousSibling.remove();\n return true;\n }\n\n // Case B: cursor at offset 1 of a ZWS-only text node whose preceding\n // sibling is an FA icon. The ZWS is the invisible caret anchor inserted\n // by IconDialog; treat the whole Backspace as \"delete icon + its anchor\".\n if (r.startOffset === 1 && textNode.textContent === '\\u200B' &&\n isFAIcon(textNode.previousSibling)) {\n event.preventDefault();\n textNode.previousSibling.remove();\n textNode.remove();\n return true;\n }\n }\n }\n return false;\n }\n\n // -------------------------------------------------------------------------\n // ArrowLeft / ArrowRight — one-press navigation across FA icon nodes\n // -------------------------------------------------------------------------\n if (isKey(event, key.LEFT) || isKey(event, key.RIGHT)) {\n const sel = window.getSelection();\n if (!sel || sel.rangeCount === 0) return false;\n\n const r = sel.getRangeAt(0);\n if (!r.collapsed) return false;\n\n const sc = r.startContainer;\n const movingLeft = isKey(event, key.LEFT);\n\n if (sc.nodeType === Node.TEXT_NODE) {\n const textNode = sc;\n\n if (movingLeft &&\n r.startOffset === 1 &&\n textNode.textContent === '\\u200B' &&\n isFAIcon(textNode.previousSibling)) {\n event.preventDefault();\n return moveCaret((nr) => nr.setStartBefore(textNode.previousSibling));\n }\n\n if (movingLeft && r.startOffset === 0 && isFAIcon(textNode.previousSibling)) {\n event.preventDefault();\n return moveCaret((nr) => nr.setStartBefore(textNode.previousSibling));\n }\n\n if (movingLeft &&\n r.startOffset === 0 &&\n isZwsAnchor(textNode.previousSibling) &&\n isFAIcon(textNode.previousSibling.previousSibling)) {\n event.preventDefault();\n return moveCaret((nr) => nr.setStartBefore(textNode.previousSibling.previousSibling));\n }\n\n if (!movingLeft &&\n r.startOffset === textNode.textContent.length &&\n isFAIcon(textNode.nextSibling)) {\n const icon = textNode.nextSibling;\n const after = icon.nextSibling;\n event.preventDefault();\n if (after && after.nodeType === Node.TEXT_NODE) {\n const offset = ((after.textContent || '').startsWith('\\u200B')) ? 1 : 0;\n return moveCaret((nr) => nr.setStart(after, Math.min(offset, after.textContent.length)));\n }\n return moveCaret((nr) => nr.setStartAfter(icon));\n }\n\n if (!movingLeft &&\n r.startOffset === textNode.textContent.length &&\n isZwsAnchor(textNode.nextSibling) &&\n isFAIcon(textNode.nextSibling.nextSibling)) {\n const icon = textNode.nextSibling.nextSibling;\n const after = icon.nextSibling;\n event.preventDefault();\n if (after && after.nodeType === Node.TEXT_NODE) {\n const offset = ((after.textContent || '').startsWith('\\u200B')) ? 1 : 0;\n return moveCaret((nr) => nr.setStart(after, Math.min(offset, after.textContent.length)));\n }\n return moveCaret((nr) => nr.setStartAfter(icon));\n }\n }\n\n if (sc.nodeType === Node.ELEMENT_NODE) {\n const el = sc;\n if (movingLeft && r.startOffset > 0) {\n const prev = el.childNodes[r.startOffset - 1];\n if (isFAIcon(prev)) {\n event.preventDefault();\n return moveCaret((nr) => nr.setStartBefore(prev));\n }\n if (isZwsAnchor(prev) && isFAIcon(prev.previousSibling)) {\n event.preventDefault();\n return moveCaret((nr) => nr.setStartBefore(prev.previousSibling));\n }\n }\n if (!movingLeft && r.startOffset < el.childNodes.length) {\n const next = el.childNodes[r.startOffset];\n if (isFAIcon(next)) {\n const after = next.nextSibling;\n event.preventDefault();\n if (after && after.nodeType === Node.TEXT_NODE) {\n const offset = ((after.textContent || '').startsWith('\\u200B')) ? 1 : 0;\n return moveCaret((nr) => nr.setStart(after, Math.min(offset, after.textContent.length)));\n }\n return moveCaret((nr) => nr.setStartAfter(next));\n }\n if (isZwsAnchor(next) && isFAIcon(next.nextSibling)) {\n const icon = next.nextSibling;\n const after = icon.nextSibling;\n event.preventDefault();\n if (after && after.nodeType === Node.TEXT_NODE) {\n const offset = ((after.textContent || '').startsWith('\\u200B')) ? 1 : 0;\n return moveCaret((nr) => nr.setStart(after, Math.min(offset, after.textContent.length)));\n }\n return moveCaret((nr) => nr.setStartAfter(icon));\n }\n }\n }\n }\n\n // -------------------------------------------------------------------------\n // Tab key — indent / outdent list items, or insert soft tab in code blocks\n // -------------------------------------------------------------------------\n if (isKey(event, key.TAB)) {\n const range = currentRange(editable);\n if (!range) return false;\n\n const para = closestPara(range.sc, editable);\n if (para && isLi(para)) {\n event.preventDefault();\n if (event.shiftKey) {\n execCommand('outdent');\n } else {\n execCommand('indent');\n }\n return true;\n }\n\n // In a pre/code block, insert spaces\n if (para && para.nodeName.toUpperCase() === 'PRE') {\n if (event.shiftKey) return false;\n event.preventDefault();\n execCommand('insertText', ' ');\n return true;\n }\n\n // Default: insert * tabSize\n if (options.tabSize) {\n if (event.shiftKey) return false;\n event.preventDefault();\n execCommand('insertText', ' '.repeat(options.tabSize));\n return true;\n }\n }\n\n // -------------------------------------------------------------------------\n // Shift+Enter — insert <br> instead of opening a new block element\n // -------------------------------------------------------------------------\n if (isKey(event, key.ENTER) && event.shiftKey) {\n event.preventDefault();\n execCommand('insertLineBreak');\n return true;\n }\n\n // -------------------------------------------------------------------------\n // Enter key — keep consistent paragraph insertion\n // -------------------------------------------------------------------------\n if (isKey(event, key.ENTER) && !event.shiftKey) {\n const range = currentRange(editable);\n if (!range) return false;\n\n // Hoist sc/el once so all guards below can reuse them.\n const sc = range.sc;\n const el = sc.nodeType === 3 ? sc.parentElement : sc;\n\n // Guard: if the cursor is inside a <i> FA icon element (zero text children,\n // rendered entirely by CSS ::before), pressing Enter would split the block\n // and leave an orphan <i> in the new paragraph — visually an \"auto-created\n // icon\". Push the cursor to just after the <i> first, then fall through so\n // the browser fires its default Enter at a safe text boundary.\n if (el && el.nodeName === 'I' && /\\bfa-/.test(el.className || '')) {\n const nr = document.createRange();\n nr.setStartAfter(el);\n nr.collapse(true);\n const selI = window.getSelection();\n if (selI) { selI.removeAllRanges(); selI.addRange(nr); }\n return false; // cursor is now outside <i> — let browser default handle Enter\n }\n\n // Video wrapper — Enter should create a new paragraph after the wrapper,\n // not split the wrapper's container and produce an empty video clone.\n const videoWrapper = el && el.closest && el.closest('.an-video-wrapper');\n if (videoWrapper) {\n event.preventDefault();\n const p = document.createElement('p');\n p.innerHTML = '\\u00a0';\n videoWrapper.parentNode.insertBefore(p, videoWrapper.nextSibling);\n const nr = document.createRange();\n nr.setStart(p, 0);\n nr.collapse(true);\n const sel = window.getSelection();\n sel.removeAllRanges();\n sel.addRange(nr);\n return true;\n }\n\n // Checklist — Enter creates new item; empty item exits the list\n const checkLi = el && el.closest && el.closest('.an-checklist li');\n if (checkLi) {\n event.preventDefault();\n const ul = checkLi.closest('.an-checklist');\n const sel = window.getSelection();\n let nativeRange = sel.getRangeAt(0);\n\n // Helper: get trimmed text content of a li, excluding the checkbox INPUT.\n // Strip both \\u00a0 (placeholder nbsp) and \\u200B (ZWS cursor anchors).\n const liText = (li) =>\n Array.from(li.childNodes)\n .filter((n) => !(n.nodeType === 1 && n.tagName === 'INPUT'))\n .map((n) => n.textContent).join('').replace(/[\\u00a0\\u200B]/g, ' ').trim();\n\n // 1. Check if the ENTIRE item is empty BEFORE any DOM mutation.\n // (Do NOT check only the \"before-cursor\" part — that check incorrectly\n // exits the list when cursor is at the start of a non-empty item.)\n if (!liText(checkLi)) {\n // Empty item — exit checklist, insert <p> after list\n const p = document.createElement('p');\n p.innerHTML = '\\u00a0';\n ul.parentNode.insertBefore(p, ul.nextSibling);\n checkLi.remove();\n if (ul.children.length === 0) ul.remove();\n const nr = document.createRange();\n nr.setStart(p.firstChild, 0);\n nr.collapse(true);\n sel.removeAllRanges();\n sel.addRange(nr);\n return true;\n }\n\n // 2. If selection is not collapsed, delete the selected content first —\n // mirrors browser-default Enter behaviour (delete selection, then split).\n if (!nativeRange.collapsed) {\n nativeRange.deleteContents();\n // nativeRange is now collapsed at the deletion point; re-read it\n nativeRange = sel.getRangeAt(0);\n }\n\n // 3. Extract everything from cursor to end of li into afterFrag.\n // Use startContainer/startOffset (cursor position after potential delete),\n // NOT endContainer/endOffset which is wrong for non-collapsed ranges.\n const afterRange = document.createRange();\n afterRange.setStart(nativeRange.startContainer, nativeRange.startOffset);\n afterRange.setEnd(checkLi, checkLi.childNodes.length);\n const afterFrag = afterRange.extractContents();\n\n // 4. Build the new checklist item with the extracted \"after\" content.\n const newLi = document.createElement('li');\n const cb = document.createElement('input');\n cb.type = 'checkbox';\n cb.setAttribute('contenteditable', 'false');\n newLi.appendChild(cb);\n\n // Append extracted \"after\" content (if any) then insert the new item.\n if (afterFrag.textContent.replace(/[\\u00a0\\u200B]/g, '').length > 0) {\n newLi.appendChild(afterFrag);\n }\n\n // Always ensure a text node exists so the cursor has a text-level\n // anchor. Use \\u200B (zero-width space) instead of an empty string:\n // Chrome does not reliably honour a Selection in an empty text node and\n // may normalise it to element-level, placing the caret before the\n // absolutely-positioned checkbox. \\u200B is stripped by getHTML().\n let cursorNode = newLi.childNodes[1]; // first child after checkbox\n if (!cursorNode || cursorNode.nodeType !== Node.TEXT_NODE) {\n cursorNode = document.createTextNode('\\u200B');\n newLi.appendChild(cursorNode);\n }\n checkLi.insertAdjacentElement('afterend', newLi);\n\n const nr = document.createRange();\n nr.setStart(cursorNode, 0);\n nr.collapse(true);\n sel.removeAllRanges();\n sel.addRange(nr);\n return true;\n }\n\n const para = closestPara(range.sc, editable);\n\n // Pressing Enter at the end of a blockquote should exit it\n if (para && para.nodeName.toUpperCase() === 'BLOCKQUOTE') {\n const native = range.toNativeRange();\n native.setEnd(para, para.childNodes.length);\n if (native.toString() === '' && range.isCollapsed()) {\n event.preventDefault();\n execCommand('formatBlock', '<p>');\n return true;\n }\n }\n }\n\n return false;\n}\n","/**\n * markdown.js - Lightweight Markdown → HTML converter for paste handling.\n *\n * Handles: headings H1–H6, bold/italic/strikethrough/inline-code, fenced code\n * blocks (with language), blockquotes, unordered/ordered lists, horizontal\n * rules, links, images, and plain paragraphs.\n *\n * The HTML output MUST be passed through sanitiseHTML() before insertion.\n */\n\n/**\n * Converts an HTML string to Markdown.\n * Handles: headings, paragraphs, bold/italic/del/code, links, images,\n * unordered/ordered lists, blockquote, pre/code blocks, tables, hr.\n * @param {string} html\n * @returns {string}\n */\nexport function htmlToMarkdown(html) {\n const doc = new DOMParser().parseFromString(`<body>${html || ''}</body>`, 'text/html');\n return _domToMd(doc.body).replace(/\\n{3,}/g, '\\n\\n').trim();\n}\n\nfunction _domToMd(node) {\n if (node.nodeType === 3) {\n return node.textContent.replace(/\\s+/g, ' ');\n }\n if (node.nodeType !== 1) return '';\n\n const tag = node.nodeName.toLowerCase();\n const inner = () => Array.from(node.childNodes).map(_domToMd).join('');\n\n switch (tag) {\n case 'p':\n case 'div': return `\\n\\n${inner()}\\n\\n`;\n case 'br': return ' \\n';\n case 'h1': return `\\n\\n# ${inner()}\\n\\n`;\n case 'h2': return `\\n\\n## ${inner()}\\n\\n`;\n case 'h3': return `\\n\\n### ${inner()}\\n\\n`;\n case 'h4': return `\\n\\n#### ${inner()}\\n\\n`;\n case 'h5': return `\\n\\n##### ${inner()}\\n\\n`;\n case 'h6': return `\\n\\n###### ${inner()}\\n\\n`;\n case 'strong':\n case 'b': return `**${inner()}**`;\n case 'em':\n case 'i': return `*${inner()}*`;\n case 'del':\n case 's':\n case 'strike': return `~~${inner()}~~`;\n case 'sup': return `^${inner()}`;\n case 'sub': return `~${inner()}`;\n case 'code': {\n // Inside <pre> we emit raw text; outside we wrap in backticks\n if (node.closest('pre')) return inner();\n return `\\`${inner()}\\``;\n }\n case 'pre': {\n const codeEl = node.querySelector('code');\n const langMatch = ((codeEl && codeEl.className) || '').match(/language-(\\S+)/);\n const lang = langMatch ? langMatch[1] : '';\n const content = (codeEl || node).textContent || '';\n return `\\n\\n\\`\\`\\`${lang}\\n${content}\\n\\`\\`\\`\\n\\n`;\n }\n case 'blockquote': {\n const lines = inner().trim().split('\\n');\n return `\\n\\n${lines.map((l) => `> ${l}`).join('\\n')}\\n\\n`;\n }\n case 'a': {\n const href = node.getAttribute('href') || '';\n return `[${inner()}](${href})`;\n }\n case 'img': {\n const src = node.getAttribute('src') || '';\n const alt = node.getAttribute('alt') || '';\n return ``;\n }\n case 'ul': {\n const items = Array.from(node.querySelectorAll(':scope > li'));\n if (!items.length) return inner();\n return `\\n\\n${items.map((li) => `- ${_domToMd(li).trim()}`).join('\\n')}\\n\\n`;\n }\n case 'ol': {\n const items = Array.from(node.querySelectorAll(':scope > li'));\n if (!items.length) return inner();\n return `\\n\\n${items.map((li, i) => `${i + 1}. ${_domToMd(li).trim()}`).join('\\n')}\\n\\n`;\n }\n case 'li': return inner();\n case 'hr': return '\\n\\n---\\n\\n';\n case 'table': {\n const rows = Array.from(node.querySelectorAll('tr'));\n if (!rows.length) return inner();\n const cellTexts = rows.map((tr) =>\n Array.from(tr.querySelectorAll('th, td')).map((c) => c.textContent.trim().replace(/\\|/g, '\\\\|')),\n );\n const cols = Math.max(...cellTexts.map((r) => r.length));\n const padRow = (row) => { const r = [...row]; while (r.length < cols) r.push(''); return r; };\n let md = '\\n\\n';\n md += `| ${padRow(cellTexts[0]).join(' | ')} |\\n`;\n md += `| ${Array(cols).fill('---').join(' | ')} |\\n`;\n for (let r = 1; r < cellTexts.length; r++) {\n md += `| ${padRow(cellTexts[r]).join(' | ')} |\\n`;\n }\n return md + '\\n';\n }\n default: return inner();\n }\n}\n\n/**\n * Returns true if the text contains recognisable Markdown patterns.\n * @param {string} text\n * @returns {boolean}\n */\nexport function isMarkdown(text) {\n return /^#{1,6} \\S|^\\s*[-*+] \\S|^\\s*\\d+\\. \\S|^> \\S|\\*{2}.+?\\*{2}|^```/m.test(text);\n}\n\n/**\n * Converts a Markdown string to an HTML string.\n * @param {string} text\n * @returns {string}\n */\nexport function markdownToHTML(text) {\n const lines = text.replace(/\\r\\n/g, '\\n').replace(/\\r/g, '\\n').split('\\n');\n const out = [];\n let i = 0;\n\n while (i < lines.length) {\n const line = lines[i];\n\n // ---- Fenced code block ``` lang ... ``` -----------------------------------\n const fenceMatch = line.match(/^```(\\S*)$/);\n if (fenceMatch) {\n const lang = fenceMatch[1];\n const codeLines = [];\n i++;\n while (i < lines.length && !lines[i].startsWith('```')) {\n codeLines.push(_esc(lines[i]));\n i++;\n }\n const langAttr = lang ? ` class=\"language-${_escAttr(lang)}\"` : '';\n out.push(`<pre><code${langAttr}>${codeLines.join('\\n')}</code></pre>`);\n i++; // skip closing ```\n continue;\n }\n\n // ---- Horizontal rule --- / *** / _________________________________________\n if (/^(-{3,}|\\*{3,}|_{3,})\\s*$/.test(line)) {\n out.push('<hr>');\n i++;\n continue;\n }\n\n // ---- ATX Headings # – ###### -------------------------------------------\n const hMatch = line.match(/^(#{1,6})\\s+(.+)$/);\n if (hMatch) {\n const level = hMatch[1].length;\n out.push(`<h${level}>${_inline(hMatch[2])}</h${level}>`);\n i++;\n continue;\n }\n\n // ---- Blockquote > text --------------------------------------------------\n if (line.startsWith('> ')) {\n const bqLines = [];\n while (i < lines.length && lines[i].startsWith('> ')) {\n bqLines.push(lines[i].slice(2));\n i++;\n }\n out.push(`<blockquote>${bqLines.map(_inline).join('<br>')}</blockquote>`);\n continue;\n }\n\n // ---- Unordered list - / * / + item ------------------------------------\n if (/^[-*+] /.test(line)) {\n const items = [];\n while (i < lines.length && /^[-*+] /.test(lines[i])) {\n items.push(`<li>${_inline(lines[i].slice(2))}</li>`);\n i++;\n }\n out.push(`<ul>${items.join('')}</ul>`);\n continue;\n }\n\n // ---- Ordered list 1. item ----------------------------------------------\n if (/^\\d+\\. /.test(line)) {\n const items = [];\n while (i < lines.length && /^\\d+\\. /.test(lines[i])) {\n items.push(`<li>${_inline(lines[i].replace(/^\\d+\\. /, ''))}</li>`);\n i++;\n }\n out.push(`<ol>${items.join('')}</ol>`);\n continue;\n }\n\n // ---- Blank line ----------------------------------------------------------\n if (line.trim() === '') {\n i++;\n continue;\n }\n\n // ---- GFM Table | col | col | -------------------------------------------\n // A table starts with a pipe-prefixed or pipe-containing line followed by\n // a separator row (| --- | --- |). We detect and collect all rows.\n if (/^\\|.+\\|/.test(line) && i + 1 < lines.length && /^\\|[\\s|:-]+\\|/.test(lines[i + 1])) {\n const headerCells = _parseTableRow(line);\n i += 2; // skip header + separator\n const bodyRows = [];\n while (i < lines.length && /^\\|.+\\|/.test(lines[i])) {\n bodyRows.push(_parseTableRow(lines[i]));\n i++;\n }\n const thead = `<thead><tr>${headerCells.map((c) => `<th>${_inline(c)}</th>`).join('')}</tr></thead>`;\n const tbody = bodyRows.length\n ? `<tbody>${bodyRows.map((row) => `<tr>${row.map((c) => `<td>${_inline(c)}</td>`).join('')}</tr>`).join('')}</tbody>`\n : '';\n out.push(`<table>${thead}${tbody}</table>`);\n continue;\n }\n\n // ---- Paragraph: collect consecutive non-block lines ---------------------\n const paraLines = [];\n while (\n i < lines.length &&\n lines[i].trim() !== '' &&\n !/^(#{1,6} |> |[-*+] |\\d+\\. |```|---\\s*$|\\*{3}\\s*$|_{3}\\s*$)/.test(lines[i]) &&\n !/^\\|.+\\|/.test(lines[i])\n ) {\n paraLines.push(lines[i]);\n i++;\n }\n if (paraLines.length) {\n out.push(`<p>${_inline(paraLines.join(' '))}</p>`);\n }\n }\n\n return out.join('');\n}\n\n// ---------------------------------------------------------------------------\n// Inline formatting\n// ---------------------------------------------------------------------------\n\n/**\n * Splits a GFM table row string into trimmed cell strings.\n * '| a | b | c |' → ['a', 'b', 'c']\n * @param {string} row\n * @returns {string[]}\n */\nfunction _parseTableRow(row) {\n return row\n .replace(/^\\|/, '')\n .replace(/\\|$/, '')\n .split('|')\n .map((c) => c.trim());\n}\n\nfunction _inline(text) {\n // Images before links (they share [] syntax)\n text = text.replace(/!\\[([^\\]]*)\\]\\(([^)]+)\\)/g, (_, alt, src) =>\n `<img src=\"${_escAttr(src)}\" alt=\"${_escAttr(alt)}\" class=\"an-image\">`);\n // Links\n text = text.replace(/\\[([^\\]]+)\\]\\(([^)]+)\\)/g, (_, label, href) =>\n `<a href=\"${_escAttr(href)}\">${_esc(label)}</a>`);\n // Bold + italic ***text***\n text = text.replace(/\\*{3}(.+?)\\*{3}/g, (_, c) => `<strong><em>${_esc(c)}</em></strong>`);\n text = text.replace(/_{3}(.+?)_{3}/g, (_, c) => `<strong><em>${_esc(c)}</em></strong>`);\n // Bold **text**\n text = text.replace(/\\*{2}(.+?)\\*{2}/g, (_, c) => `<strong>${_esc(c)}</strong>`);\n text = text.replace(/_{2}(.+?)_{2}/g, (_, c) => `<strong>${_esc(c)}</strong>`);\n // Italic *text* _text_\n text = text.replace(/\\*([^*\\n]+?)\\*/g, (_, c) => `<em>${_esc(c)}</em>`);\n text = text.replace(/_([^_\\n]+?)_/g, (_, c) => `<em>${_esc(c)}</em>`);\n // Strikethrough ~~text~~\n text = text.replace(/~~(.+?)~~/g, (_, c) => `<del>${_esc(c)}</del>`);\n // Inline code `code`\n text = text.replace(/`([^`]+)`/g, (_, c) => `<code>${_esc(c)}</code>`);\n return text;\n}\n\nfunction _esc(v) {\n return String(v)\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>');\n}\n\nfunction _escAttr(v) {\n return String(v)\n .replace(/&/g, '&')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n .replace(/</g, '<')\n .replace(/>/g, '>');\n}\n","/**\n * Editor.js - Core editing command module\n * Wraps all execCommand calls, undo/redo, and fires events via the context.\n * Inspired by Summernote's Editor module.\n */\n\nimport { History } from '../editing/History.js';\nimport * as Style from '../editing/Style.js';\nimport { insertTable } from '../editing/Table.js';\nimport { isModifier } from '../core/key.js';\nimport { handleKeydown } from '../editing/Typing.js';\nimport { on } from '../core/dom.js';\nimport { sanitiseHTML, sanitiseUrl } from '../core/sanitise.js';\nimport { markdownToHTML, htmlToMarkdown } from '../core/markdown.js';\n\nexport class Editor {\n /**\n * @param {import('../Context.js').Context} context\n */\n constructor(context) {\n this.context = context;\n this.options = context.options;\n /** @type {History|null} */\n this._history = null;\n this._disposers = [];\n /** @type {number|null} Timer handle for debounced undo snapshot */\n this._snapshotTimer = null;\n }\n\n // ---------------------------------------------------------------------------\n // Lifecycle\n // ---------------------------------------------------------------------------\n\n initialize() {\n const editable = this.context.layoutInfo.editable;\n this._history = new History(editable, this.options.historyLimit || 100);\n this._bindEvents(editable);\n return this;\n }\n\n destroy() {\n this._disposers.forEach((d) => d());\n this._disposers = [];\n this._history = null;\n clearTimeout(this._snapshotTimer);\n this._snapshotTimer = null;\n }\n\n // ---------------------------------------------------------------------------\n // Event binding\n // ---------------------------------------------------------------------------\n\n _bindEvents(editable) {\n // Keyboard shortcuts\n const onKeydown = (event) => this._onKeydown(event);\n // Catch ALL content mutations: typing, IME, spellcheck, voice, drag-drop text.\n const onInput = () => this.afterCommand();\n // Hard-enforce maxChars / maxWords before content is mutated\n const onBeforeInput = (event) => this._enforceLimit(event);\n // Refresh toolbar on selection change, scoped to this editor\n const onSelChange = () => {\n if (!this.context._alive) return;\n const sel = window.getSelection();\n if (sel && sel.rangeCount > 0 && editable.contains(sel.anchorNode)) {\n this.context.invoke('toolbar.refresh');\n if (typeof this.options.onSelectionChange === 'function') {\n this.options.onSelectionChange(this.context);\n }\n }\n };\n\n // Checklist checkboxes are contenteditable=false so native clicks work;\n // hook afterCommand so the checked state is preserved in undo history.\n const onCheckboxClick = (e) => {\n if (e.target.type === 'checkbox' && e.target.closest('.an-checklist')) {\n this.afterCommand();\n }\n };\n\n // Guard: when cursor lands at the <li> element node of a checklist item\n // (before the checkbox), nudge it to the correct text position.\n //\n // mouseup: use caretRangeFromPoint / caretPositionFromPoint so the cursor\n // lands WHERE the user actually clicked (middle, end of text…).\n // keyup : arrow-key navigation may land at <li>[0]; move to start-of-text.\n const fixChecklistCursor = (event) => {\n const sel = window.getSelection();\n if (!sel || !sel.rangeCount) return;\n const r = sel.getRangeAt(0);\n if (!r.collapsed) return;\n const sc = r.startContainer;\n\n // Only act when cursor is at the <li> element node itself (not inside\n // a text node — the browser already placed it correctly in that case).\n if (sc.nodeType !== Node.ELEMENT_NODE) return;\n const li = sc.matches && sc.matches('.an-checklist li') ? sc : null;\n if (!li) return;\n const cb = li.querySelector('input[type=\"checkbox\"]');\n if (!cb) return;\n\n // For mouse events: ask the browser where the pointer landed so the\n // cursor respects the actual click position inside the text.\n if (event && event.type === 'mouseup') {\n let caret = null;\n if (document.caretRangeFromPoint) {\n caret = document.caretRangeFromPoint(event.clientX, event.clientY);\n } else if (document.caretPositionFromPoint) {\n const cp = document.caretPositionFromPoint(event.clientX, event.clientY);\n if (cp) {\n caret = document.createRange();\n caret.setStart(cp.offsetNode, cp.offset);\n }\n }\n // If the caret from point landed inside a text node of this li, use it\n if (caret && editable.contains(caret.startContainer) &&\n caret.startContainer !== li) {\n caret.collapse(true);\n sel.removeAllRanges();\n sel.addRange(caret);\n return;\n }\n }\n\n // Fallback (keyboard nav, or caretRangeFromPoint not available / landed\n // at li again): prefer the first text node after the checkbox so the\n // cursor renders at the padding-left edge (after the visual checkbox)\n // rather than at element-level where the browser may place it at x=0.\n const nr = document.createRange();\n let anchorNode = null;\n for (const child of li.childNodes) {\n if (child !== cb && child.nodeType === Node.TEXT_NODE) {\n anchorNode = child;\n break;\n }\n }\n if (anchorNode) {\n nr.setStart(anchorNode, 0);\n } else {\n nr.setStartAfter(cb);\n }\n nr.collapse(true);\n sel.removeAllRanges();\n sel.addRange(nr);\n };\n\n this._disposers.push(\n on(editable, 'keydown', onKeydown),\n on(editable, 'beforeinput', onBeforeInput),\n on(editable, 'input', onInput),\n on(document, 'selectionchange', onSelChange),\n on(editable, 'click', onCheckboxClick),\n on(editable, 'mouseup', fixChecklistCursor),\n on(editable, 'keyup', fixChecklistCursor),\n );\n }\n\n _onKeydown(event) {\n const editable = this.context.layoutInfo.editable;\n\n // Let Typing module handle special keys (Tab, Enter etc.)\n if (handleKeydown(event, editable, this.options)) return;\n\n // Built-in shortcuts\n if (isModifier(event, 'z') && !event.shiftKey) {\n event.preventDefault();\n this.undo();\n return;\n }\n if ((isModifier(event, 'z') && event.shiftKey) || isModifier(event, 'y')) {\n event.preventDefault();\n this.redo();\n return;\n }\n if (isModifier(event, 'b')) { event.preventDefault(); this.bold(); return; }\n if (isModifier(event, 'i')) { event.preventDefault(); this.italic(); return; }\n if (isModifier(event, 'u')) { event.preventDefault(); this.underline(); return; }\n if (isModifier(event, 'k')) { event.preventDefault(); this.context.invoke('linkDialog.show'); return; }\n\n // Ctrl+Shift+V — paste as plain text (signals Clipboard module)\n if (isModifier(event, 'v') && event.shiftKey) {\n this.context.invoke('clipboard.setForcePlain', true);\n return; // let the native paste event fire\n }\n\n // Show keyboard shortcuts dialog: Ctrl+Shift+/\n if (event.key === '/' && event.shiftKey && event.ctrlKey && !event.metaKey) {\n event.preventDefault();\n this.context.invoke('shortcutsDialog.show');\n return;\n }\n // Find: Ctrl+F\n if (isModifier(event, 'f')) {\n event.preventDefault();\n this.context.invoke('findReplace.show', 'find');\n return;\n }\n // Ctrl+H — Find & Replace\n if (isModifier(event, 'h')) {\n event.preventDefault();\n this.context.invoke('findReplace.show', 'replace');\n }\n // Ctrl+` — Inline Code\n if (isModifier(event, '`')) {\n event.preventDefault();\n this.inlineCode();\n }\n }\n\n // ---------------------------------------------------------------------------\n // Limit enforcement\n // ---------------------------------------------------------------------------\n\n /**\n * Called from beforeinput to block typing when char/word limits are reached.\n * Deletions and non-typing input types are always allowed.\n * @param {InputEvent} event\n */\n _enforceLimit(event) {\n const maxChars = this.options.maxChars || 0;\n const maxWords = this.options.maxWords || 0;\n if (!maxChars && !maxWords) return;\n\n const type = event.inputType || '';\n // Allow deletions, undo, redo and non-insert operations\n if (type.startsWith('delete') || type === 'historyUndo' || type === 'historyRedo') return;\n // Allow paste/drop — handled after the fact by Clipboard\n if (type === 'insertFromPaste' || type === 'insertFromDrop') return;\n // Only enforce for keyboard/IME/composition insertions\n if (!type.startsWith('insert')) return;\n\n const text = this.context.layoutInfo.editable.innerText || '';\n const chars = text.replace(/\\n/g, '').length;\n\n if (maxChars && chars >= maxChars) {\n event.preventDefault();\n if (typeof this.options.onCharLimitReached === 'function') {\n this.options.onCharLimitReached(this.context);\n }\n return;\n }\n\n // Word limit: block space / newline insertion when already at the limit\n if (maxWords && (event.data === ' ' || type === 'insertParagraph' || type === 'insertLineBreak')) {\n const words = text.trim() ? text.trim().split(/\\s+/).length : 0;\n if (words >= maxWords) {\n event.preventDefault();\n if (typeof this.options.onWordLimitReached === 'function') {\n this.options.onWordLimitReached(this.context);\n }\n }\n }\n }\n\n // ---------------------------------------------------------------------------\n // Post-command hook — records undo, fires change event\n // ---------------------------------------------------------------------------\n\n afterCommand() {\n // Immediate: keep toolbar and statusbar in sync on every mutation.\n this.context.invoke('toolbar.refresh');\n this.context.invoke('statusbar.update');\n // Debounced: recording an undo snapshot and firing the change event require\n // a full innerHTML serialization. Batching rapid keystrokes prevents the\n // browser from re-serializing large content (e.g. embedded images) on every\n // single key press.\n this._scheduleSnapshot();\n }\n\n /**\n * Schedules a debounced undo snapshot + change event.\n * Resets the timer on each call so rapid typing produces one snapshot.\n */\n _scheduleSnapshot() {\n clearTimeout(this._snapshotTimer);\n this._snapshotTimer = setTimeout(() => {\n this._snapshotTimer = null;\n if (this._history) this._history.recordUndo();\n this.context.triggerEvent('change', this.getHTML());\n }, 400);\n }\n\n // ---------------------------------------------------------------------------\n // Focus management\n // ---------------------------------------------------------------------------\n\n focus() {\n const editable = this.context.layoutInfo.editable;\n editable.focus();\n }\n\n // ---------------------------------------------------------------------------\n // Content API\n // ---------------------------------------------------------------------------\n\n /**\n * Returns the editor HTML content.\n * @returns {string}\n */\n getHTML() {\n // Strip zero-width spaces inserted after icons to allow caret placement.\n const raw = this.context.layoutInfo.editable.innerHTML.replace(/\\u200B/g, '');\n // Replace any blob: URLs (lightweight DOM references to pasted/dropped images)\n // with their original data URLs so the returned HTML is fully self-contained.\n return this.context.invoke('clipboard.resolveImages', raw) ?? raw;\n }\n\n /**\n * Sets the editor HTML content.\n * @param {string} html - HTML string (will be sanitised)\n */\n setHTML(html) {\n this.context.layoutInfo.editable.innerHTML = sanitiseHTML(html);\n if (this._history) this._history.reset();\n this.afterCommand();\n }\n\n /**\n * Returns the editor plain text content.\n * @returns {string}\n */\n getText() {\n return this.context.layoutInfo.editable.innerText || '';\n }\n\n /**\n * Sets the editor content as plain text.\n * @param {string} text\n */\n setText(text) {\n this.context.layoutInfo.editable.textContent = text;\n if (this._history) this._history.reset();\n this.afterCommand();\n }\n\n /**\n * Clears the editor content.\n */\n clear() {\n this.setHTML('');\n }\n\n /**\n * Resets the undo/redo history stack.\n */\n clearHistory() {\n if (this._history) this._history.reset();\n }\n\n /**\n * Returns true when the editor has no meaningful content.\n * @returns {boolean}\n */\n isEmpty() {\n const text = (this.context.layoutInfo.editable.innerText || '')\n .trim()\n .replace(/\\u00a0/g, '');\n const hasMedia = !!this.context.layoutInfo.editable.querySelector('img, video, iframe, table');\n return !text && !hasMedia;\n }\n\n /**\n * Inserts HTML at the current cursor position.\n * @param {string} html\n */\n insertHTML(html) {\n if (!html) return;\n Style.execCommand('insertHTML', sanitiseHTML(html));\n this.afterCommand();\n }\n\n /**\n * Inserts plain text at the current cursor position.\n * @param {string} text\n */\n insertText(text) {\n if (!text) return;\n Style.execCommand('insertText', text);\n this.afterCommand();\n }\n\n /**\n * Sets editor content from a Markdown string.\n * @param {string} md\n */\n setMarkdown(md) {\n this.setHTML(markdownToHTML(md || ''));\n }\n\n /**\n * Returns the editor content as Markdown.\n * @returns {string}\n */\n getMarkdown() {\n return htmlToMarkdown(this.getHTML());\n }\n\n // ---------------------------------------------------------------------------\n // Undo / redo\n // ---------------------------------------------------------------------------\n\n undo() {\n if (this._history) {\n clearTimeout(this._snapshotTimer);\n this._snapshotTimer = null;\n this._history.undo();\n this.context.invoke('toolbar.refresh');\n this.context.invoke('statusbar.update');\n this.context.triggerEvent('change', this.getHTML());\n }\n }\n\n redo() {\n if (this._history) {\n clearTimeout(this._snapshotTimer);\n this._snapshotTimer = null;\n this._history.redo();\n this.context.invoke('toolbar.refresh');\n this.context.invoke('statusbar.update');\n this.context.triggerEvent('change', this.getHTML());\n }\n }\n\n canUndo() {\n return this._history ? this._history.canUndo() : false;\n }\n\n canRedo() {\n return this._history ? this._history.canRedo() : false;\n }\n\n // ---------------------------------------------------------------------------\n // Style commands (delegated to Style module)\n // ---------------------------------------------------------------------------\n\n bold() { Style.bold(); this.afterCommand(); }\n italic() { Style.italic(); this.afterCommand(); }\n underline() { Style.underline(); this.afterCommand(); }\n strikethrough() { Style.strikethrough(); this.afterCommand(); }\n superscript() { Style.superscript(); this.afterCommand(); }\n subscript() { Style.subscript(); this.afterCommand(); }\n justifyLeft() { Style.justifyLeft(); this.afterCommand(); }\n justifyCenter() { Style.justifyCenter(); this.afterCommand(); }\n justifyRight() { Style.justifyRight(); this.afterCommand(); }\n justifyFull() { Style.justifyFull(); this.afterCommand(); }\n indent() { Style.indent(); this.afterCommand(); }\n outdent() { Style.outdent(); this.afterCommand(); }\n insertUL() { Style.insertUnorderedList(); this.afterCommand(); }\n insertOL() { Style.insertOrderedList(); this.afterCommand(); }\n inlineCode() { Style.toggleInlineCode(this.context.layoutInfo.editable); this.afterCommand(); }\n toggleChecklist() { Style.toggleChecklist(); this.afterCommand(); }\n print() { this.context.print(); }\n\n /**\n * @param {string} tagName - e.g. 'h1', 'p', 'blockquote'\n */\n formatBlock(tagName) { Style.formatBlock(tagName); this.afterCommand(); }\n\n /**\n * @param {string} color\n */\n foreColor(color) { Style.foreColor(color); this.afterCommand(); }\n\n /**\n * @param {string} color\n */\n backColor(color) { Style.backColor(color); this.afterCommand(); }\n\n /**\n * @param {string} name\n */\n fontName(name) { Style.fontName(name); this.afterCommand(); }\n\n /**\n * @param {string} size - e.g. '14px'\n */\n fontSize(size) { Style.fontSize(size, this.context.layoutInfo.editable); this.afterCommand(); }\n\n // ---------------------------------------------------------------------------\n // Insert helpers\n // ---------------------------------------------------------------------------\n\n /**\n * Inserts a horizontal rule at the cursor.\n */\n insertHr() {\n Style.execCommand('insertHorizontalRule');\n this.afterCommand();\n }\n\n /**\n * Creates a link at the current selection.\n * @param {string} url\n * @param {string} text\n * @param {boolean} [openInNewTab=false]\n */\n insertLink(url, text, openInNewTab = false) {\n const sel = window.getSelection();\n if (!sel || sel.rangeCount === 0) return;\n const safeUrl = sanitiseUrl(url);\n if (!safeUrl) return;\n\n const hasText = sel.toString().trim().length > 0;\n if (!hasText) {\n const displayText = this._escapeAttr(text || safeUrl);\n Style.execCommand('insertHTML', `<a href=\"${this._escapeAttr(safeUrl)}\"${openInNewTab ? ' target=\"_blank\" rel=\"noopener noreferrer\"' : ''}>${displayText}</a>`);\n } else {\n Style.execCommand('createLink', safeUrl);\n if (openInNewTab) {\n const link = this._getClosestAnchor();\n if (link) {\n link.setAttribute('target', '_blank');\n link.setAttribute('rel', 'noopener noreferrer');\n }\n }\n }\n this.afterCommand();\n }\n\n /**\n * Removes the link from the selected anchor.\n */\n unlink() {\n Style.execCommand('unlink');\n this.afterCommand();\n }\n\n /**\n * Inserts an image.\n * @param {string} src - URL or data-URI\n * @param {string} [alt]\n */\n insertImage(src, alt = '', align = '') {\n const safeSrc = sanitiseUrl(src, { allowData: true });\n if (!safeSrc) return;\n const styleMap = {\n left: 'float:left;margin:0 1em 1em 0',\n center: 'display:block;margin:0 auto',\n right: 'float:right;margin:0 0 1em 1em',\n };\n const style = styleMap[align] || '';\n const styleAttr = style ? ` style=\"${style}\"` : '';\n Style.execCommand('insertHTML', `<img src=\"${this._escapeAttr(safeSrc)}\" alt=\"${this._escapeAttr(alt)}\" class=\"an-image\"${styleAttr}>`);\n this.afterCommand();\n }\n\n /**\n * Inserts a video embed (iframe or <video> element).\n * The html string is already validated/built by VideoDialog.\n * @param {string} html\n */\n insertVideo(html) {\n if (!html) return;\n Style.execCommand('insertHTML', html);\n this.afterCommand();\n }\n\n /**\n * Inserts a table.\n * @param {number} cols\n * @param {number} rows\n */\n insertTable(cols, rows) {\n insertTable(cols, rows, { headerRow: this.context.options.tableHeaderRow });\n this.afterCommand();\n }\n\n // ---------------------------------------------------------------------------\n // Helpers\n // ---------------------------------------------------------------------------\n\n _getClosestAnchor() {\n const sel = window.getSelection();\n if (!sel || sel.rangeCount === 0) return null;\n let node = sel.getRangeAt(0).startContainer;\n while (node) {\n if (node.nodeName === 'A') return node;\n node = node.parentNode;\n }\n return null;\n }\n\n /**\n * Escapes a string for safe use inside an HTML attribute value.\n * @param {string} str\n * @returns {string}\n */\n _escapeAttr(str) {\n return String(str ?? '')\n .replace(/&/g, '&')\n .replace(/\"/g, '"')\n .replace(/</g, '<')\n .replace(/>/g, '>');\n }\n\n // --- delegated to shared sanitise.js ---\n}\n","/**\n * Toolbar.js - Builds and manages the editor toolbar UI\n * Inspired by Summernote's Toolbar module — rewritten without jQuery\n */\n\nimport { createElement, on } from '../core/dom.js';\n\n// Module-level cache for FontAwesome detection.\n// Evaluated once per page load so all Toolbar instances on the same page agree\n// on whether the HOST PAGE included FA — regardless of whether IconDialog later\n// auto-injects its own FA <link> for the icon-picker glyph rendering.\nlet _faPageLevelReady = null;\n\nexport class Toolbar {\n /**\n * @param {import('../Context.js').Context} context\n */\n constructor(context) {\n this.context = context;\n this.options = context.options;\n /** @type {HTMLElement|null} */\n this.el = null;\n /** @type {Array<() => void>} disposers */\n this._disposers = [];\n /** @type {Array<() => void>} closers for all open color picker popups */\n this._colorPickerClosers = [];\n }\n\n // ---------------------------------------------------------------------------\n // Lifecycle\n // ---------------------------------------------------------------------------\n\n initialize() {\n this.el = createElement('div', { class: 'an-toolbar' });\n // Detect FontAwesome once at toolbar build time to avoid re-querying the DOM\n // for every button rendered.\n this._faReady = this._detectFontAwesome();\n this._buildButtons();\n this._btnMap = new Map((this.options.toolbar || []).flat().map((b) => [b.name, b]));\n return this;\n }\n\n destroy() {\n this._disposers.forEach((d) => d());\n this._disposers = [];\n if (this.el && this.el.parentNode) {\n this.el.parentNode.removeChild(this.el);\n }\n this.el = null;\n }\n\n // ---------------------------------------------------------------------------\n // Build\n // ---------------------------------------------------------------------------\n\n _buildButtons() {\n const toolbar = this.options.toolbar || [];\n toolbar.forEach((group) => {\n const groupEl = createElement('div', { class: 'an-btn-group' });\n group.forEach((btnDef) => {\n let el;\n if (btnDef.type === 'select') el = this._createSelect(btnDef);\n else if (btnDef.type === 'grid') el = this._createGridPicker(btnDef);\n else if (btnDef.type === 'colorpicker') el = this._createColorPicker(btnDef);\n else el = this._createButton(btnDef);\n groupEl.appendChild(el);\n });\n this.el.appendChild(groupEl);\n });\n }\n\n /**\n * Creates a table-grid picker button with a hoverable row/col selector popup.\n * @param {import('./Buttons.js').ButtonDef} def\n * @returns {HTMLDivElement}\n */\n _createGridPicker(def) {\n const ROWS = 10;\n const COLS = 10;\n\n const wrap = createElement('div', { class: 'an-table-picker-wrap' });\n\n const useBootstrap = !!this.options.useBootstrap;\n const baseClass = useBootstrap\n ? (this.options.toolbarButtonClass || 'btn btn-sm btn-light')\n : 'an-btn';\n const btn = createElement('button', {\n type: 'button',\n class: baseClass,\n title: def.tooltip || '',\n 'data-btn': def.name,\n 'aria-label': def.tooltip || def.name,\n 'aria-haspopup': 'true',\n 'aria-expanded': 'false',\n });\n\n // Set icon — inline SVG (table) with optional FontAwesome fallback\n if (this._faReady) {\n const faPrefix = this.options.fontAwesomeClass || 'fas';\n btn.innerHTML = `<i class=\"${faPrefix} fa-table\" aria-hidden=\"true\"></i>`;\n } else {\n const S = 'stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"';\n btn.innerHTML = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" ${S} style=\"display:block\"><rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"1\"/><line x1=\"3\" y1=\"9\" x2=\"21\" y2=\"9\"/><line x1=\"3\" y1=\"15\" x2=\"21\" y2=\"15\"/><line x1=\"9\" y1=\"3\" x2=\"9\" y2=\"21\"/><line x1=\"15\" y1=\"3\" x2=\"15\" y2=\"21\"/></svg>`;\n }\n\n // Popup\n const popup = createElement('div', {\n class: 'an-table-picker-popup',\n role: 'dialog',\n 'aria-label': 'Select table size',\n });\n const grid = createElement('div', { class: 'an-table-grid' });\n const label = createElement('div', { class: 'an-table-label' });\n label.textContent = 'Insert Table';\n\n const cells = [];\n for (let r = 1; r <= ROWS; r++) {\n for (let c = 1; c <= COLS; c++) {\n const cell = createElement('div', {\n class: 'an-table-cell',\n 'data-row': String(r),\n 'data-col': String(c),\n });\n cells.push(cell);\n grid.appendChild(cell);\n }\n }\n\n popup.appendChild(grid);\n popup.appendChild(label);\n\n let isOpen = false;\n\n const setHighlight = (rows, cols) => {\n cells.forEach((cell) => {\n const r = +cell.getAttribute('data-row');\n const c = +cell.getAttribute('data-col');\n cell.classList.toggle('active', r <= rows && c <= cols);\n });\n label.textContent = (rows && cols) ? `${rows} × ${cols}` : 'Insert Table';\n };\n\n const openPopup = () => {\n isOpen = true;\n popup.style.display = 'block';\n btn.setAttribute('aria-expanded', 'true');\n };\n\n const closePopup = () => {\n isOpen = false;\n popup.style.display = 'none';\n btn.setAttribute('aria-expanded', 'false');\n setHighlight(0, 0);\n };\n\n const d1 = on(btn, 'click', (e) => {\n e.stopPropagation();\n if (isOpen) closePopup(); else openPopup();\n });\n\n const d2 = on(grid, 'mouseover', (e) => {\n const cell = e.target.closest('.an-table-cell');\n if (!cell) return;\n setHighlight(+cell.getAttribute('data-row'), +cell.getAttribute('data-col'));\n });\n\n const d3 = on(grid, 'mouseleave', () => setHighlight(0, 0));\n\n const d4 = on(grid, 'click', (e) => {\n const cell = e.target.closest('.an-table-cell');\n if (!cell) return;\n const rows = +cell.getAttribute('data-row');\n const cols = +cell.getAttribute('data-col');\n closePopup();\n this.context.invoke('editor.focus');\n def.action(this.context, rows, cols);\n });\n\n const d5 = on(document, 'click', () => { if (isOpen) closePopup(); });\n\n this._disposers.push(d1, d2, d3, d4, d5);\n\n wrap.appendChild(btn);\n wrap.appendChild(popup);\n return wrap;\n }\n\n /**\n * Creates a split color-picker widget:\n * [icon + strip | ▾] — left applies current color, right opens swatch popup.\n * @param {{ name: string, type: 'colorpicker', tooltip: string, defaultColor: string, action: Function }} def\n * @returns {HTMLDivElement}\n */\n _createColorPicker(def) {\n const PRESETS = [\n // Grayscale\n '#000000', '#434343', '#666666', '#999999', '#b7b7b7', '#cccccc', '#efefef', '#ffffff',\n // Saturated\n '#ff0000', '#ff9900', '#ffff00', '#00ff00', '#00ffff', '#4a86e8', '#9900ff', '#ff00ff',\n // Pastel\n '#f4cccc', '#fce5cd', '#fff2cc', '#d9ead3', '#d0e0e3', '#c9daf8', '#d9d2e9', '#ead1dc',\n ];\n\n let currentColor = def.defaultColor || '#000000';\n\n const wrap = createElement('div', { class: 'an-color-picker-wrap' });\n\n const useBootstrap = !!this.options.useBootstrap;\n const baseClass = useBootstrap ? (this.options.toolbarButtonClass || 'btn btn-sm btn-light') : 'an-btn';\n\n // ---- Apply button (icon + color strip) ----\n const applyBtn = createElement('button', {\n type: 'button',\n class: `${baseClass} an-color-btn`,\n title: def.tooltip || '',\n 'data-btn': def.name,\n 'aria-label': def.tooltip || def.name,\n });\n\n const S = 'stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"';\n const iconSvg = def.name === 'foreColor'\n ? `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" ${S} style=\"display:block\"><path d=\"M4 20L12 4L20 20\"/><line x1=\"7.5\" y1=\"14\" x2=\"16.5\" y2=\"14\"/></svg>`\n : `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" ${S} style=\"display:block\"><path d=\"M3 21v-4l9-9 4 4-9 9z\"/><path d=\"M12 8l4 4\"/></svg>`;\n\n applyBtn.innerHTML = iconSvg;\n const strip = createElement('span', { class: 'an-color-strip' });\n strip.style.background = currentColor;\n applyBtn.appendChild(strip);\n\n // ---- Arrow button (open popup) ----\n const arrowBtn = createElement('button', {\n type: 'button',\n class: `${baseClass} an-color-arrow`,\n title: `Choose ${def.name === 'foreColor' ? 'text' : 'highlight'} color`,\n 'aria-haspopup': 'true',\n 'aria-expanded': 'false',\n });\n arrowBtn.innerHTML = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"8\" height=\"8\" viewBox=\"0 0 24 24\" fill=\"currentColor\" stroke=\"none\" style=\"display:block\"><path d=\"M7 10l5 5 5-5H7z\"/></svg>`;\n\n // ---- Popup ----\n const popup = createElement('div', { class: 'an-color-popup' });\n popup.style.display = 'none';\n\n const swatches = createElement('div', { class: 'an-color-swatches' });\n const userSwatches = Array.isArray(this.options.colorSwatches) ? this.options.colorSwatches : [];\n const allColors = [...new Set([...userSwatches, ...PRESETS])];\n allColors.forEach((color) => {\n const sw = createElement('div', { class: 'an-color-swatch', title: color, 'data-color': color });\n sw.style.background = color;\n swatches.appendChild(sw);\n });\n\n const customRow = createElement('div', { class: 'an-color-custom' });\n const colorInput = createElement('input', { type: 'color', value: currentColor, title: 'Custom color' });\n const customLabel = createElement('span', {}, ['Custom color']);\n customRow.appendChild(colorInput);\n customRow.appendChild(customLabel);\n\n popup.appendChild(swatches);\n popup.appendChild(customRow);\n\n // ---- State ----\n let isOpen = false;\n /** @type {Range|null} saved selection range before popup opens */\n let savedRange = null;\n\n const saveSelection = () => {\n const sel = window.getSelection();\n savedRange = (sel && sel.rangeCount) ? sel.getRangeAt(0).cloneRange() : null;\n };\n\n const restoreSelection = () => {\n if (!savedRange) return;\n const sel = window.getSelection();\n if (sel) {\n sel.removeAllRanges();\n sel.addRange(savedRange);\n }\n };\n\n const openPopup = () => {\n // Close any other open color picker before opening this one\n this._colorPickerClosers.forEach((fn) => { if (fn !== closePopup) fn(); });\n saveSelection();\n isOpen = true;\n // Use fixed positioning so the popup escapes any overflow-clipping ancestor\n // (notably toolbar scroll mode, where overflow-x:auto coerces overflow-y)\n const rect = arrowBtn.getBoundingClientRect();\n const popupMinW = 184;\n let left = rect.left;\n if (left + popupMinW > window.innerWidth) left = rect.right - popupMinW;\n popup.style.top = `${rect.bottom + 4}px`;\n popup.style.left = `${Math.max(4, left)}px`;\n popup.style.display = 'block';\n arrowBtn.setAttribute('aria-expanded', 'true');\n };\n\n const closePopup = () => {\n isOpen = false;\n popup.style.display = 'none';\n popup.style.top = '';\n popup.style.left = '';\n arrowBtn.setAttribute('aria-expanded', 'false');\n };\n\n const applyColor = (color) => {\n currentColor = color;\n strip.style.background = color;\n colorInput.value = color;\n restoreSelection();\n def.action(this.context, color);\n this.context.invoke('editor.afterCommand');\n closePopup();\n };\n\n const d1 = on(applyBtn, 'click', (e) => {\n e.preventDefault();\n restoreSelection();\n def.action(this.context, currentColor);\n this.context.invoke('editor.afterCommand');\n });\n\n const d2 = on(arrowBtn, 'mousedown', (e) => {\n // Prevent editor blur so selection is preserved when the popup opens\n e.preventDefault();\n });\n\n const d2b = on(arrowBtn, 'click', (e) => {\n e.stopPropagation();\n if (isOpen) closePopup(); else openPopup();\n });\n\n const d3 = on(swatches, 'mousedown', (e) => {\n // Prevent blur before the click handler fires\n e.preventDefault();\n });\n\n const d3b = on(swatches, 'click', (e) => {\n const sw = e.target.closest('.an-color-swatch');\n if (sw) applyColor(sw.dataset.color);\n });\n\n const d4 = on(colorInput, 'change', (e) => {\n applyColor(e.target.value);\n });\n\n const d5 = on(document, 'click', (e) => {\n // popup is in document.body, not inside wrap — check both\n if (isOpen && !wrap.contains(e.target) && !popup.contains(e.target)) closePopup();\n });\n\n const d6 = on(popup, 'click', (e) => e.stopPropagation());\n\n // Close the popup when the viewport scrolls or resizes so the fixed-position\n // popup doesn't drift away from the button it belongs to.\n const onScrollResize = () => { if (isOpen) closePopup(); };\n document.addEventListener('scroll', onScrollResize, { passive: true, capture: true });\n window.addEventListener('resize', onScrollResize, { passive: true });\n\n this._disposers.push(d1, d2, d2b, d3, d3b, d4, d5, d6,\n () => document.removeEventListener('scroll', onScrollResize, { capture: true }),\n () => window.removeEventListener('resize', onScrollResize),\n // Remove popup from body on editor destroy\n () => { if (popup.parentNode) popup.parentNode.removeChild(popup); },\n );\n\n // Register this popup's closer so other color pickers can close it\n this._colorPickerClosers.push(closePopup);\n this._disposers.push(() => {\n const idx = this._colorPickerClosers.indexOf(closePopup);\n if (idx !== -1) this._colorPickerClosers.splice(idx, 1);\n });\n\n // Append popup to document.body so it escapes all overflow-clipping and\n // contain:layout ancestors (contain:layout makes the container a fixed-pos\n // containing block per the CSS Contain spec, breaking viewport coordinates).\n wrap.appendChild(applyBtn);\n wrap.appendChild(arrowBtn);\n document.body.appendChild(popup);\n return wrap;\n }\n\n /**\n * Creates a <select> dropdown for font-family (or similar) options.\n * @param {import('./Buttons.js').DropdownDef} def\n * @returns {HTMLSelectElement}\n */\n _createSelect(def) {\n const items = (def.name === 'fontFamily')\n ? (this.options.fontFamilies || [])\n : (def.items || []);\n\n const cls = def.selectClass ? `an-select ${def.selectClass}` : 'an-select';\n const select = createElement('select', {\n class: cls,\n title: def.tooltip || '',\n 'data-btn': def.name,\n 'aria-label': def.tooltip || def.name,\n });\n\n // Blank \"placeholder\" option (non-selectable header)\n const placeholderText = def.placeholder || 'Font';\n const placeholder = createElement('option', { value: '', disabled: '', hidden: '' }, [placeholderText]);\n select.appendChild(placeholder);\n\n items.forEach((item) => {\n const value = (typeof item === 'object') ? item.value : item;\n const label = (typeof item === 'object') ? item.label : item;\n const isHeader = (typeof item === 'object') && !!item.disabled;\n const attrs = { value };\n if (isHeader) attrs.disabled = '';\n const opt = createElement('option', attrs, [label]);\n // Only apply fontFamily face preview on real (non-header) entries\n if (def.name === 'fontFamily' && !isHeader) opt.style.fontFamily = value;\n select.appendChild(opt);\n });\n\n const disposer = on(select, 'change', (e) => {\n const value = e.target.value;\n const selectedOpt = e.target.options[e.target.selectedIndex];\n if (!value || selectedOpt.disabled) return;\n this.context.invoke('editor.focus');\n def.action(this.context, value);\n this.context.invoke('editor.afterCommand');\n });\n\n this._disposers.push(disposer);\n return select;\n }\n\n /**\n * @param {import('./Buttons.js').ButtonDef} btnDef\n * @returns {HTMLButtonElement}\n */\n _createButton(btnDef) {\n // Determine classes based on whether the consumer wants Bootstrap styling\n const useBootstrap = !!this.options.useBootstrap;\n const baseClass = useBootstrap ? (this.options.toolbarButtonClass || 'btn btn-sm btn-light') : `an-btn`;\n const extra = btnDef.className ? ` ${btnDef.className}` : '';\n const classAttr = `${baseClass}${extra}`;\n\n const btn = createElement('button', {\n type: 'button',\n class: classAttr,\n title: btnDef.tooltip || '',\n 'data-btn': btnDef.name,\n 'aria-label': btnDef.tooltip || btnDef.name,\n });\n\n // Render icon: prefer FontAwesome if enabled; otherwise fall back to SVG or text.\n\n // Heroicons-style stroke SVGs — consistent with context menu icons\n const S = 'stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"';\n const svgWrap = (paths) => `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" ${S} style=\"display:block\">${paths}</svg>`;\n\n const svgMap = new Map([\n // Format\n ['bold', svgWrap('<path d=\"M6 4h8a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z\"/><path d=\"M6 12h9a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z\"/>')],\n ['italic', svgWrap('<line x1=\"19\" y1=\"4\" x2=\"10\" y2=\"4\"/><line x1=\"14\" y1=\"20\" x2=\"5\" y2=\"20\"/><line x1=\"15\" y1=\"4\" x2=\"9\" y2=\"20\"/>')],\n ['underline', svgWrap('<path d=\"M6 3v7a6 6 0 0 0 6 6 6 6 0 0 0 6-6V3\"/><line x1=\"4\" y1=\"21\" x2=\"20\" y2=\"21\"/>')],\n ['strikethrough', svgWrap('<path d=\"M17.3 12H6.7\"/><path d=\"M10 6.5C10 5.1 11.1 4 12.5 4c1.4 0 2.5 1.1 2.5 2.5 0 .8-.4 1.5-1 2\"/><path d=\"M14 17.5C14 19 12.9 20 11.5 20 10.1 20 9 18.9 9 17.5c0-.8.4-1.5 1-2\"/>')],\n ['superscript', svgWrap('<path d=\"m4 19 8-8\"/><path d=\"m12 19-8-8\"/><path d=\"M20 12h-4c0-1.5.44-2 1.5-2.5S20 8.33 20 7.25C20 6 19 5 17.5 5S15 6 15 7\"/>')],\n ['subscript', svgWrap('<path d=\"m4 5 8 8\"/><path d=\"m12 5-8 8\"/><path d=\"M20 21h-4c0-1.5.44-2 1.5-2.5S20 17.33 20 16.25C20 15 19 14 17.5 14S15 15 15 16\"/>')],\n // Alignment\n ['align-left', svgWrap('<line x1=\"21\" y1=\"6\" x2=\"3\" y2=\"6\"/><line x1=\"15\" y1=\"12\" x2=\"3\" y2=\"12\"/><line x1=\"17\" y1=\"18\" x2=\"3\" y2=\"18\"/>')],\n ['align-center', svgWrap('<line x1=\"21\" y1=\"6\" x2=\"3\" y2=\"6\"/><line x1=\"18\" y1=\"12\" x2=\"6\" y2=\"12\"/><line x1=\"21\" y1=\"18\" x2=\"3\" y2=\"18\"/>')],\n ['align-right', svgWrap('<line x1=\"21\" y1=\"6\" x2=\"3\" y2=\"6\"/><line x1=\"21\" y1=\"12\" x2=\"9\" y2=\"12\"/><line x1=\"21\" y1=\"18\" x2=\"7\" y2=\"18\"/>')],\n ['align-justify', svgWrap('<line x1=\"21\" y1=\"6\" x2=\"3\" y2=\"6\"/><line x1=\"21\" y1=\"12\" x2=\"3\" y2=\"12\"/><line x1=\"21\" y1=\"18\" x2=\"3\" y2=\"18\"/>')],\n // Lists\n ['list-ul', svgWrap('<line x1=\"9\" y1=\"6\" x2=\"20\" y2=\"6\"/><line x1=\"9\" y1=\"12\" x2=\"20\" y2=\"12\"/><line x1=\"9\" y1=\"18\" x2=\"20\" y2=\"18\"/><circle cx=\"4\" cy=\"6\" r=\"1\" fill=\"currentColor\" stroke=\"none\"/><circle cx=\"4\" cy=\"12\" r=\"1\" fill=\"currentColor\" stroke=\"none\"/><circle cx=\"4\" cy=\"18\" r=\"1\" fill=\"currentColor\" stroke=\"none\"/>')],\n ['list-ol', svgWrap('<line x1=\"10\" y1=\"6\" x2=\"21\" y2=\"6\"/><line x1=\"10\" y1=\"12\" x2=\"21\" y2=\"12\"/><line x1=\"10\" y1=\"18\" x2=\"21\" y2=\"18\"/><path d=\"M4 6h1V3\"/><path d=\"M4 10h2l-2 2h2\"/><path d=\"M4 16.5A1.5 1.5 0 0 1 5.5 15a1.5 1.5 0 0 1 0 3H4\"/>')],\n ['indent', svgWrap('<polyline points=\"3 8 7 12 3 16\"/><line x1=\"21\" y1=\"12\" x2=\"11\" y2=\"12\"/><line x1=\"21\" y1=\"6\" x2=\"11\" y2=\"6\"/><line x1=\"21\" y1=\"18\" x2=\"11\" y2=\"18\"/>')],\n ['outdent', svgWrap('<polyline points=\"7 8 3 12 7 16\"/><line x1=\"21\" y1=\"12\" x2=\"11\" y2=\"12\"/><line x1=\"21\" y1=\"6\" x2=\"11\" y2=\"6\"/><line x1=\"21\" y1=\"18\" x2=\"11\" y2=\"18\"/>')],\n // History\n ['undo', svgWrap('<path d=\"M3 7v6h6\"/><path d=\"M21 17a9 9 0 0 0-9-9 9 9 0 0 0-6 2.3L3 13\"/>')],\n ['redo', svgWrap('<path d=\"M21 7v6h-6\"/><path d=\"M3 17a9 9 0 0 1 9-9 9 9 0 0 1 6 2.3L21 13\"/>')],\n // Insert\n ['minus', svgWrap('<line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/>')],\n ['link', svgWrap('<path d=\"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71\"/><path d=\"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71\"/>')],\n ['image', svgWrap('<rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\"/><circle cx=\"8.5\" cy=\"8.5\" r=\"1.5\"/><polyline points=\"21 15 16 10 5 21\"/>')],\n ['video', svgWrap('<polygon points=\"23 7 16 12 23 17 23 7\"/><rect x=\"1\" y=\"5\" width=\"15\" height=\"14\" rx=\"2\"/>')],\n ['table', svgWrap('<rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"1\"/><line x1=\"3\" y1=\"9\" x2=\"21\" y2=\"9\"/><line x1=\"3\" y1=\"15\" x2=\"21\" y2=\"15\"/><line x1=\"9\" y1=\"3\" x2=\"9\" y2=\"21\"/><line x1=\"15\" y1=\"3\" x2=\"15\" y2=\"21\"/>')],\n ['emoji', svgWrap('<circle cx=\"12\" cy=\"12\" r=\"10\"/><path d=\"M8.5 14.5s1.5 2.5 3.5 2.5 3.5-2.5 3.5-2.5\"/><circle cx=\"9\" cy=\"9\" r=\"1.5\" fill=\"currentColor\" stroke=\"none\"/><circle cx=\"15\" cy=\"9\" r=\"1.5\" fill=\"currentColor\" stroke=\"none\"/>')],\n ['icon', svgWrap('<circle cx=\"8\" cy=\"8\" r=\"3\"/><circle cx=\"16\" cy=\"8\" r=\"3\"/><rect x=\"5\" y=\"13\" width=\"6\" height=\"6\" rx=\"1\"/><rect x=\"13\" y=\"13\" width=\"6\" height=\"6\" rx=\"1\"/>')],\n // View\n ['code', svgWrap('<polyline points=\"16 18 22 12 16 6\"/><polyline points=\"8 6 2 12 8 18\"/>')],\n ['expand', svgWrap('<polyline points=\"15 3 21 3 21 9\"/><polyline points=\"9 21 3 21 3 15\"/><line x1=\"21\" y1=\"3\" x2=\"14\" y2=\"10\"/><line x1=\"3\" y1=\"21\" x2=\"10\" y2=\"14\"/>')],\n // Color pickers\n ['foreColor', svgWrap('<path d=\"M4 20L12 4L20 20\"/><line x1=\"7.5\" y1=\"14\" x2=\"16.5\" y2=\"14\"/>')],\n ['backColor', svgWrap('<path d=\"M3 21v-4l9-9 4 4-9 9z\"/><path d=\"M12 8l4 4\"/>')],\n ['keyboard', svgWrap('<rect x=\"2\" y=\"6\" width=\"20\" height=\"12\" rx=\"2\"/><line x1=\"6\" y1=\"10\" x2=\"6\" y2=\"10\" stroke-width=\"2.5\"/><line x1=\"10\" y1=\"10\" x2=\"10\" y2=\"10\" stroke-width=\"2.5\"/><line x1=\"14\" y1=\"10\" x2=\"14\" y2=\"10\" stroke-width=\"2.5\"/><line x1=\"18\" y1=\"10\" x2=\"18\" y2=\"10\" stroke-width=\"2.5\"/><line x1=\"8\" y1=\"14\" x2=\"16\" y2=\"14\" stroke-width=\"2\"/>')],\n ['caption', svgWrap('<rect x=\"3\" y=\"3\" width=\"18\" height=\"11\" rx=\"2\"/><line x1=\"6\" y1=\"18\" x2=\"18\" y2=\"18\"/><line x1=\"9\" y1=\"21\" x2=\"15\" y2=\"21\"/>')],\n ['remove-format', svgWrap('<path d=\"m7 21-4.3-4.3c-1-1-1-2.5 0-3.4l9.6-9.6c1-1 2.5-1 3.4 0l5.6 5.6c1 1 1 2.5 0 3.4L13 21\"/><path d=\"M22 21H7\"/><path d=\"m5 11 9 9\"/>')],\n ['direction', svgWrap('<path d=\"M12 20V4\"/><path d=\"m9 7-3 3 3 3\"/><path d=\"M4 10h8\"/><path d=\"m15 7 3 3-3 3\"/><path d=\"M20 10h-8\"/>')],\n ['search', svgWrap('<circle cx=\"11\" cy=\"11\" r=\"7\"/><line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\"/>')],\n ['find-replace', svgWrap('<circle cx=\"10\" cy=\"10\" r=\"6\"/><line x1=\"18\" y1=\"18\" x2=\"14.35\" y2=\"14.35\"/><path d=\"M16 19h6\"/><path d=\"M19 16v6\"/>')],\n ['inline-code', svgWrap('<path d=\"M8 3H7a2 2 0 0 0-2 2v5a2 2 0 0 1-2 2 2 2 0 0 1 2 2v5c0 1.1.9 2 2 2h1\"/><path d=\"M16 3h1a2 2 0 0 1 2 2v5c0 1.1.9 2 2 2a2 2 0 0 1-2 2v5a2 2 0 0 1-2 2h-1\"/>')],\n ['checklist', svgWrap('<rect x=\"3\" y=\"4\" width=\"5\" height=\"5\" rx=\"1\"/><path d=\"m4 6.5 1 1 2-2\"/><rect x=\"3\" y=\"13\" width=\"5\" height=\"5\" rx=\"1\"/><line x1=\"10\" y1=\"6.5\" x2=\"21\" y2=\"6.5\"/><line x1=\"10\" y1=\"15.5\" x2=\"21\" y2=\"15.5\"/>')],\n ['print', svgWrap('<path d=\"M6 9V2h12v7\"/><path d=\"M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2\"/><rect x=\"6\" y=\"14\" width=\"12\" height=\"8\"/>')],\n ]);\n\n const faPrefix = this.options.fontAwesomeClass || 'fas';\n const faMap = new Map([\n ['bold', 'fa-bold'],\n ['italic', 'fa-italic'],\n ['underline', 'fa-underline'],\n ['strikethrough', 'fa-strikethrough'],\n ['superscript', 'fa-superscript'],\n ['subscript', 'fa-subscript'],\n ['align-left', 'fa-align-left'],\n ['align-center', 'fa-align-center'],\n ['align-right', 'fa-align-right'],\n ['align-justify', 'fa-align-justify'],\n ['list-ul', 'fa-list-ul'],\n ['list-ol', 'fa-list-ol'],\n ['indent', 'fa-indent'],\n ['outdent', 'fa-outdent'],\n ['undo', 'fa-rotate-left'],\n ['redo', 'fa-rotate-right'],\n ['minus', 'fa-minus'],\n ['link', 'fa-link'],\n ['image', 'fa-image'],\n ['code', 'fa-code'],\n ['expand', 'fa-expand'],\n ['emoji', 'fa-face-smile'],\n ['icon', 'fa-icons'],\n ['foreColor', 'fa-font'],\n ['backColor', 'fa-highlighter'],\n ['keyboard', 'fa-keyboard'],\n ['remove-format', 'fa-remove-format'],\n ['direction', 'fa-arrow-right-arrow-left'],\n ['search', 'fa-magnifying-glass'],\n ['find-replace', 'fa-magnifying-glass-plus'],\n ['inline-code', 'fa-code'],\n ['checklist', 'fa-list-check'],\n ['print', 'fa-print'],\n ]);\n\n const useFaNow = this._faReady;\n if (useFaNow) {\n const faName = faMap.get(btnDef.icon) || faMap.get(btnDef.name) || null;\n if (faName) {\n btn.innerHTML = `<i class=\"${faPrefix} ${faName}\" aria-hidden=\"true\"></i>`;\n } else if (svgMap.has(btnDef.icon)) {\n btn.innerHTML = svgMap.get(btnDef.icon);\n } else {\n btn.textContent = btnDef.icon || btnDef.name;\n }\n } else {\n // FontAwesome absent: use SVG fallback when available\n if (svgMap.has(btnDef.icon)) {\n btn.innerHTML = svgMap.get(btnDef.icon);\n } else if (svgMap.has(btnDef.name)) {\n btn.innerHTML = svgMap.get(btnDef.name);\n } else {\n btn.textContent = btnDef.icon || btnDef.name;\n }\n }\n\n const disposer = on(btn, 'click', (event) => {\n event.preventDefault();\n // Restore focus to the editor before executing the action\n this.context.invoke('editor.focus');\n btnDef.action(this.context);\n this.context.invoke('editor.afterCommand');\n this.refresh();\n });\n\n this._disposers.push(disposer);\n return btn;\n }\n\n // ---------------------------------------------------------------------------\n // FontAwesome detection (run once at initialize time)\n // ---------------------------------------------------------------------------\n\n _detectFontAwesome() {\n if (!this.options.useFontAwesome) return false;\n // Return cached result when available. This ensures that a later-initialised\n // toolbar sees the same detection state as the first one — even if IconDialog\n // has since injected its own FA <link> into <head> for the icon-picker UI.\n if (_faPageLevelReady !== null) return _faPageLevelReady;\n if (document.querySelector('.fa, .fas, .far, .fal, .fab, .fa-solid')) {\n _faPageLevelReady = true;\n return true;\n }\n // Exclude the editor-self-injected link (id='an-fontawesome-css') so it doesn't\n // count as \"the host page loaded FA\" for toolbar icon rendering purposes.\n const links = Array.from(document.querySelectorAll('link[rel=\"stylesheet\"]'))\n .filter((l) => l.id !== 'an-fontawesome-css')\n .map((l) => l.href || '').join(' ');\n _faPageLevelReady = /fontawesome|font-awesome|use\\.fontawesome|all\\.css/.test(links);\n return _faPageLevelReady;\n }\n\n // ---------------------------------------------------------------------------\n // State refresh (active / disabled states)\n // ---------------------------------------------------------------------------\n\n refresh() {\n if (!this.el) return;\n const btnMap = this._btnMap || new Map();\n\n // Sync button active states\n this.el.querySelectorAll('button[data-btn]').forEach((btn) => {\n const def = btnMap.get(btn.getAttribute('data-btn'));\n if (def && typeof def.isActive === 'function') {\n btn.classList.toggle('active', !!def.isActive(this.context));\n }\n if (def && typeof def.isDisabled === 'function') {\n btn.disabled = !!def.isDisabled(this.context);\n }\n });\n\n // Sync select dropdowns (e.g. font family) with current cursor position\n this.el.querySelectorAll('select[data-btn]').forEach((select) => {\n const def = btnMap.get(select.getAttribute('data-btn'));\n if (!def || typeof def.getValue !== 'function') return;\n // queryCommandValue returns the font name, possibly quoted — strip quotes\n let raw = (def.getValue(this.context) || '').replace(/[\"']/g, '').trim();\n // Fallback: when no selection/font set, use the configured default font\n if (!raw) {\n raw = this.options.defaultFontFamily\n || (this.options.fontFamilies && this.options.fontFamilies[0])\n || '';\n }\n // Try to match against available options (case-insensitive)\n const matched = Array.from(select.options).find(\n (opt) => opt.value && opt.value.toLowerCase() === raw.toLowerCase()\n );\n select.value = matched ? matched.value : '';\n });\n }\n\n /**\n * Shows the toolbar.\n */\n show() {\n if (this.el) this.el.style.display = '';\n }\n\n /**\n * Hides the toolbar.\n */\n hide() {\n if (this.el) this.el.style.display = 'none';\n }\n}\n","/**\n * Statusbar.js - Displays word count, character count and resize handle\n * Inspired by Summernote's Statusbar module — rewritten without jQuery\n */\n\nimport { createElement, on } from '../core/dom.js';\nimport { debounce } from '../core/func.js';\n\n// Cache the segmenter instance at module level to avoid per-call allocation\nconst _segmenter =\n typeof Intl !== 'undefined' && typeof Intl.Segmenter === 'function'\n ? new Intl.Segmenter(undefined, { granularity: 'word' })\n : null;\n\n/**\n * Count words in a string, CJK-aware.\n * Uses Intl.Segmenter (Chromium 87+, Firefox 125+, Safari 17+) when available,\n * falling back to a simple whitespace split for older environments.\n * @param {string} text\n * @returns {number}\n */\nfunction _countWords(text) {\n const trimmed = text.trim();\n if (!trimmed) return 0;\n if (_segmenter) {\n let count = 0;\n for (const seg of _segmenter.segment(trimmed)) {\n if (seg.isWordLike) count++;\n }\n return count;\n }\n // Fallback: split on whitespace\n return trimmed.split(/\\s+/).length;\n}\n\n/**\n * Toggles warning/exceeded CSS classes on a count element.\n * @param {HTMLElement} el\n * @param {number} current\n * @param {number} limit 0 = no limit\n */\nfunction _applyLimitClass(el, current, limit) {\n if (!limit) {\n el.classList.remove('an-count-warn', 'an-count-exceeded');\n return;\n }\n if (current > limit) {\n el.classList.add('an-count-exceeded');\n el.classList.remove('an-count-warn');\n } else if (current >= limit * 0.9) {\n el.classList.add('an-count-warn');\n el.classList.remove('an-count-exceeded');\n } else {\n el.classList.remove('an-count-warn', 'an-count-exceeded');\n }\n}\n\nexport class Statusbar {\n /**\n * @param {import('../Context.js').Context} context\n */\n constructor(context) {\n this.context = context;\n this.options = context.options;\n /** @type {HTMLElement|null} */\n this.el = null;\n this._disposers = [];\n /** @type {HTMLElement|null} */\n this._wordCountEl = null;\n /** @type {HTMLElement|null} */\n this._charCountEl = null;\n }\n\n // ---------------------------------------------------------------------------\n // Lifecycle\n // ---------------------------------------------------------------------------\n\n initialize() {\n this.el = createElement('div', { class: 'an-statusbar' });\n\n // Resize handle\n if (this.options.resizable !== false) {\n const handle = createElement('div', {\n class: 'an-resize-handle',\n title: 'Resize editor',\n 'aria-hidden': 'true',\n });\n this._bindResize(handle);\n this.el.appendChild(handle);\n }\n\n // Counters\n this._wordCountEl = createElement('span', { class: 'an-word-count' });\n this._charCountEl = createElement('span', { class: 'an-char-count' });\n const info = createElement('div', { class: 'an-status-info' });\n info.appendChild(this._wordCountEl);\n info.appendChild(this._charCountEl);\n this.el.appendChild(info);\n\n this._bindContentEvents();\n this.update();\n return this;\n }\n\n destroy() {\n this._disposers.forEach((d) => d());\n this._disposers = [];\n if (this._dragDisposers) {\n this._dragDisposers.forEach((d) => d());\n this._dragDisposers = null;\n }\n if (this.el && this.el.parentNode) {\n this.el.parentNode.removeChild(this.el);\n }\n this.el = null;\n }\n\n // ---------------------------------------------------------------------------\n // Resize logic\n // ---------------------------------------------------------------------------\n\n _bindResize(handle) {\n let startY = 0;\n let startH = 0;\n // Resize the container (flex column parent) so that the editable — which\n // has flex:1 / flex-basis:0 — automatically fills the remaining space.\n // Setting height directly on a flex:1 item has no effect because the flex\n // algorithm ignores the height property when flex-basis is non-auto.\n const containerEl = this.context.layoutInfo.container;\n\n const applyDelta = (clientY) => {\n const delta = clientY - startY;\n // Compute the true minimum: fixed elements (toolbar + statusbar) must fit\n // inside the container. Sum the offsetHeight of every child that is NOT\n // the editable area, then add a small floor so the editable stays visible.\n const MIN_EDITABLE = 40;\n const fixedH = Array.from(containerEl.children)\n .filter(child => !child.classList.contains('an-editable'))\n .reduce((sum, child) => sum + child.offsetHeight, 0);\n const trueMin = Math.max(this.options.minHeight || 100, fixedH + MIN_EDITABLE);\n containerEl.style.height = `${Math.max(trueMin, startH + delta)}px`;\n };\n\n // Mouse drag\n const onMouseMove = (event) => applyDelta(event.clientY);\n\n const onMouseUp = () => {\n document.removeEventListener('mousemove', onMouseMove);\n document.removeEventListener('mouseup', onMouseUp);\n this._dragDisposers = null;\n };\n\n const onMouseDown = (event) => {\n startY = event.clientY;\n startH = containerEl.offsetHeight;\n // Clear the editable's inline min-height so the flex layout can compress\n // it freely once the container has a fixed height. Without this, the\n // editable's min-height (set from options.height) overflows the container\n // when the user drags the handle to a size smaller than that value.\n this.context.layoutInfo.editable.style.minHeight = '';\n document.addEventListener('mousemove', onMouseMove);\n document.addEventListener('mouseup', onMouseUp);\n // Track drag-phase listeners so destroy() can remove them mid-drag\n this._dragDisposers = [\n () => document.removeEventListener('mousemove', onMouseMove),\n () => document.removeEventListener('mouseup', onMouseUp),\n ];\n event.preventDefault();\n };\n\n // Touch drag\n const onTouchMove = (event) => {\n const touch = event.touches[0];\n if (touch) { event.preventDefault(); applyDelta(touch.clientY); }\n };\n\n const onTouchEnd = () => {\n document.removeEventListener('touchmove', onTouchMove);\n document.removeEventListener('touchend', onTouchEnd);\n this._dragDisposers = null;\n };\n\n const onTouchStart = (event) => {\n const touch = event.touches[0];\n if (!touch) return;\n startY = touch.clientY;\n startH = containerEl.offsetHeight;\n // Same as onMouseDown: clear editable min-height so flex can compress it\n this.context.layoutInfo.editable.style.minHeight = '';\n document.addEventListener('touchmove', onTouchMove, { passive: false });\n document.addEventListener('touchend', onTouchEnd);\n this._dragDisposers = [\n () => document.removeEventListener('touchmove', onTouchMove),\n () => document.removeEventListener('touchend', onTouchEnd),\n ];\n };\n\n const d1 = on(handle, 'mousedown', onMouseDown);\n const d2 = on(handle, 'touchstart', onTouchStart);\n this._disposers.push(d1, d2);\n }\n\n // ---------------------------------------------------------------------------\n // Counter update\n // ---------------------------------------------------------------------------\n\n _bindContentEvents() {\n const editable = this.context.layoutInfo.editable;\n const updateDebounced = debounce(() => this.update(), 200);\n const d = on(editable, 'input', updateDebounced);\n this._disposers.push(d);\n }\n\n update() {\n if (!this._wordCountEl || !this._charCountEl) return;\n const editable = this.context.layoutInfo.editable;\n const text = editable.innerText || '';\n const words = _countWords(text);\n const chars = text.replace(/\\n/g, '').length;\n const maxWords = this.options.maxWords || 0;\n const maxChars = this.options.maxChars || 0;\n\n this._wordCountEl.textContent = maxWords\n ? `Words: ${words}/${maxWords}`\n : `Words: ${words}`;\n this._charCountEl.textContent = maxChars\n ? `Chars: ${chars}/${maxChars}`\n : `Chars: ${chars}`;\n\n // Apply warning / exceeded styles\n _applyLimitClass(this._wordCountEl, words, maxWords);\n _applyLimitClass(this._charCountEl, chars, maxChars);\n }\n\n /**\n * Returns the current word count of the editor content.\n * @returns {number}\n */\n getWordCount() {\n const editable = this.context.layoutInfo.editable;\n return _countWords(editable.innerText || '');\n }\n\n /**\n * Returns the current character count (excluding newlines) of the editor content.\n * @returns {number}\n */\n getCharCount() {\n const editable = this.context.layoutInfo.editable;\n return ((editable.innerText || '').replace(/\\n/g, '')).length;\n }\n}\n","/**\n * Clipboard.js - Handles paste events to strip unwanted formatting,\n * and paste/drop of image files.\n * Inspired by Summernote's Clipboard module\n */\n\nimport { on } from '../core/dom.js';\nimport { execCommand } from '../editing/Style.js';\nimport { sanitiseHTML } from '../core/sanitise.js';\nimport { isMarkdown, markdownToHTML } from '../core/markdown.js';\n\nexport class Clipboard {\n /**\n * @param {import('../Context.js').Context} context\n */\n constructor(context) {\n this.context = context;\n this.options = context.options;\n this._disposers = [];\n }\n\n initialize() {\n /** @type {Map<string, string>} Maps blob: URL (in DOM) → data: URL (serialisable) */\n this._blobRegistry = new Map();\n /** @type {boolean} Set to true by Ctrl+Shift+V shortcut to force one-shot plain paste */\n this._forcePlain = false;\n const editable = this.context.layoutInfo.editable;\n this._disposers.push(\n on(editable, 'paste', (e) => this._onPaste(e)),\n on(editable, 'dragover', (e) => this._onDragover(e)),\n on(editable, 'drop', (e) => this._onDrop(e)),\n );\n\n // Watch for removed images so their blob: URLs are revoked immediately,\n // preventing memory leaks during long editing sessions.\n this._mutationObserver = new MutationObserver((mutations) => {\n for (const mutation of mutations) {\n for (const node of mutation.removedNodes) {\n this._revokeRemovedBlobs(node);\n }\n }\n });\n this._mutationObserver.observe(editable, { childList: true, subtree: true });\n\n return this;\n }\n\n destroy() {\n this._disposers.forEach((d) => d());\n this._disposers = [];\n if (this._mutationObserver) {\n this._mutationObserver.disconnect();\n this._mutationObserver = null;\n }\n // Release any remaining object URLs\n if (this._blobRegistry) {\n this._blobRegistry.forEach((_, blobUrl) => URL.revokeObjectURL(blobUrl));\n this._blobRegistry.clear();\n }\n }\n\n /**\n * Revokes blob URLs for any <img> elements removed from the DOM.\n * @param {Node} node\n */\n _revokeRemovedBlobs(node) {\n if (!this._blobRegistry || !this._blobRegistry.size) return;\n const imgs = [];\n if (node.nodeName === 'IMG') {\n imgs.push(node);\n } else if (node.querySelectorAll) {\n imgs.push(...node.querySelectorAll('img'));\n }\n imgs.forEach((img) => {\n const src = img.getAttribute('src') || '';\n if (src.startsWith('blob:') && this._blobRegistry.has(src)) {\n URL.revokeObjectURL(src);\n this._blobRegistry.delete(src);\n }\n });\n }\n\n // ---------------------------------------------------------------------------\n // Paste handler\n // ---------------------------------------------------------------------------\n\n /**\n * Strips Microsoft Word / Office HTML artefacts from a pasted HTML string.\n * Removes conditional comments, Office namespace elements, MsoXxx classes,\n * mso-* inline style rules, and empty paragraphs left behind by Word.\n * @param {string} html\n * @returns {string}\n */\n _cleanWordHtml(html) {\n return html\n // Conditional comments <!--[if ...]>...<![endif]-->\n .replace(/<!--\\[if[\\s\\S]*?\\[endif\\]-->/gi, '')\n // XML data blobs <xml>...</xml>\n .replace(/<xml[\\s\\S]*?<\\/xml>/gi, '')\n // XML processing instructions <?xml ... ?>\n .replace(/<\\?xml[\\s\\S]*?\\?>/gi, '')\n // Office namespace elements: <o:p>, <w:sDt>, <m:oMath>, <v:shape> …\n .replace(/<\\/?(o|w|m|v|st1):[a-z][^>]*>/gi, '')\n // MsoNormal, MsoBodyText, etc. class attributes\n .replace(/\\s+class=\"Mso[^\"]*\"/gi, '')\n // mso-* properties inside inline style attributes\n .replace(/\\s+style=\"([^\"]*)\"/gi, (_m, style) => {\n const cleaned = style.split(';')\n .map((s) => s.trim())\n .filter((s) => s && !/^mso-/i.test(s) && !/^(tab-stops|margin-[a-z]+-alt)/i.test(s))\n .join('; ');\n return cleaned ? ` style=\"${cleaned}\"` : '';\n })\n // Empty paragraphs Word sprinkles everywhere\n .replace(/<p[^>]*>\\s*( )?\\s*<\\/p>/gi, '');\n }\n\n /**\n * Detects and strips noise from social media sites (Facebook, X/Twitter, LinkedIn, etc.).\n * These React-based pages produce HTML with utility class names like `x1n2onr6` / `r-bcqeeo`,\n * `data-testid`, `data-lexical-*`, etc. We keep the semantic structure but remove all the noise.\n * @param {string} html\n * @returns {string}\n */\n _cleanSocialHtml(html) {\n const doc = new DOMParser().parseFromString(`<body>${html}</body>`, 'text/html');\n // Unwrap purely presentational wrapper spans/divs with no semantic meaning\n const UNWRAP_TAGS = new Set(['span', 'div']);\n let changed = true;\n // Iteratively unwrap until stable (handles deeply nested span soup)\n while (changed) {\n changed = false;\n doc.querySelectorAll('span, div').forEach((el) => {\n if (!UNWRAP_TAGS.has(el.tagName.toLowerCase())) return;\n // Keep if it has a meaningful role (link, heading, list item are handled by parent)\n if (el.querySelector('a, strong, em, b, i, ul, ol, li, table, img, blockquote, pre, code, h1, h2, h3, h4, h5, h6')) return;\n // Unwrap — replace el with its children\n const parent = el.parentNode;\n if (!parent) return;\n while (el.firstChild) parent.insertBefore(el.firstChild, el);\n parent.removeChild(el);\n changed = true;\n });\n }\n // Strip class and all data-* attributes from every remaining element\n doc.querySelectorAll('*').forEach((el) => {\n el.removeAttribute('class');\n el.removeAttribute('id');\n Array.from(el.attributes)\n .filter((a) => a.name.startsWith('data-') || a.name.startsWith('aria-'))\n .forEach((a) => el.removeAttribute(a.name));\n });\n return doc.body.innerHTML;\n }\n\n /**\n * Strips presentational attributes (class, style, data-*, id) from all elements,\n * keeping only semantic structure and URL attributes.\n * Used when `pasteStripAttributes` option is true.\n * @param {string} html\n * @returns {string}\n */\n _stripAttributes(html) {\n const doc = new DOMParser().parseFromString(`<body>${html}</body>`, 'text/html');\n const KEEP_ATTRS = new Set(['href', 'src', 'alt', 'target', 'rel', 'colspan', 'rowspan', 'type']);\n doc.querySelectorAll('*').forEach((el) => {\n Array.from(el.attributes)\n .filter((a) => !KEEP_ATTRS.has(a.name))\n .forEach((a) => el.removeAttribute(a.name));\n });\n return doc.body.innerHTML;\n }\n\n /**\n * Forces the next paste operation to strip all HTML formatting.\n * Called by Editor when Ctrl+Shift+V is pressed.\n * @param {boolean} val\n */\n setForcePlain(val) {\n this._forcePlain = !!val;\n }\n\n _onPaste(event) {\n const clipboardData = event.clipboardData || window.clipboardData;\n if (!clipboardData) return;\n\n // Consume and reset the one-shot plain-paste flag\n const forcePlain = this._forcePlain;\n this._forcePlain = false;\n\n // 1. Image file in clipboard (screenshot, copy-image-from-browser, etc.)\n if (clipboardData.items) {\n const imageItems = Array.from(clipboardData.items).filter(\n (item) => item.kind === 'file' && item.type.startsWith('image/'),\n );\n if (imageItems.length > 0) {\n event.preventDefault();\n const files = imageItems.map((item) => item.getAsFile()).filter(Boolean);\n this._insertImageFiles(files);\n return;\n }\n }\n\n // Fire onPaste hook so consumers can observe / intercept\n if (typeof this.options.onPaste === 'function') {\n this.options.onPaste({\n text: clipboardData.getData('text/plain') || '',\n html: clipboardData.types.includes('text/html') ? clipboardData.getData('text/html') : null,\n });\n }\n\n // 2. Force plain-text only — strip all formatting\n if (forcePlain || this.options.pasteAsPlainText) {\n event.preventDefault();\n const text = clipboardData.getData('text/plain');\n const html = text\n .split(/\\r?\\n/)\n .map((line) => `<p>${this._escapeHTML(line) || '<br>'}</p>`)\n .join('');\n execCommand('insertHTML', html);\n this.context.invoke('editor.afterCommand');\n return;\n }\n\n // 3. Markdown paste — only when no HTML is on the clipboard (pure text source)\n if (this.options.markdownPaste !== false && !clipboardData.types.includes('text/html')) {\n const text = clipboardData.getData('text/plain');\n if (text && isMarkdown(text)) {\n event.preventDefault();\n const html = sanitiseHTML(markdownToHTML(text));\n execCommand('insertHTML', html);\n this.context.invoke('editor.afterCommand');\n return;\n }\n }\n\n // 4. Sanitise HTML on paste when pasteCleanHTML is true (default)\n if (this.options.pasteCleanHTML !== false && clipboardData.types.includes('text/html')) {\n event.preventDefault();\n const raw = clipboardData.getData('text/html');\n // Detect source type and apply appropriate pre-cleaner\n const isWordContent = /<[a-z]+:[a-z]/i.test(raw) || /class=\"Mso/i.test(raw) || /\\bmso-/i.test(raw);\n const isSocialContent = /\\bdata-testid\\b/.test(raw) || /class=\"[^\"]*\\b(?:x[a-z0-9]{6,}|r-[a-z0-9]{3,})\\b/.test(raw);\n let html = raw;\n if (isWordContent) html = this._cleanWordHtml(html);\n else if (isSocialContent) html = this._cleanSocialHtml(html);\n html = sanitiseHTML(html);\n if (this.options.pasteStripAttributes) html = this._stripAttributes(html);\n execCommand('insertHTML', html);\n this.context.invoke('editor.afterCommand');\n return;\n }\n\n // Otherwise let the browser handle paste natively\n }\n\n // ---------------------------------------------------------------------------\n // Drag & drop handlers\n // ---------------------------------------------------------------------------\n\n _onDragover(event) {\n if (!event.dataTransfer) return;\n const types = Array.from(event.dataTransfer.types || []);\n if (types.includes('Files')) {\n event.preventDefault();\n event.dataTransfer.dropEffect = 'copy';\n }\n }\n\n _onDrop(event) {\n const dt = event.dataTransfer;\n if (!dt || !dt.files || dt.files.length === 0) return;\n\n const imageFiles = Array.from(dt.files).filter((f) => f.type.startsWith('image/'));\n if (imageFiles.length === 0) return;\n\n event.preventDefault();\n event.stopPropagation();\n\n // Place the caret at the drop coordinates before inserting\n this._placeCaretAtPoint(event.clientX, event.clientY);\n this._insertImageFiles(imageFiles);\n }\n\n // ---------------------------------------------------------------------------\n // Image file processing — shared by paste and drop\n // ---------------------------------------------------------------------------\n\n /**\n * Inserts one or more image Files into the editor.\n * Delegates to `options.onImageUpload` when provided; otherwise compresses\n * and embeds as base64.\n * @param {File[]} files\n */\n _insertImageFiles(files) {\n if (!files || files.length === 0) return;\n\n if (typeof this.options.onImageUpload === 'function') {\n this.options.onImageUpload(files);\n return;\n }\n\n const maxBytes = (this.options.maxImageSize || 5) * 1024 * 1024;\n files.forEach((file) => {\n if (!file || !file.type.startsWith('image/')) return;\n if (file.size > maxBytes) {\n const message = `Image \"${file.name}\" exceeds the ${this.options.maxImageSize || 5} MB size limit.`;\n this.context.triggerEvent('imageError', { file, message });\n console.warn(`[AutumnNote] ${message}`);\n return;\n }\n\n const alt = file.name.replace(/\\.[^.]+$/, '');\n this._compressImage(file).then((dataUrl) => {\n // Keep the large data URL in a JS Map; insert a lightweight blob: URL\n // into the DOM so editable.innerHTML never contains the big base64 string.\n const blob = this._dataUrlToBlob(dataUrl);\n const blobUrl = URL.createObjectURL(blob);\n this._blobRegistry.set(blobUrl, dataUrl);\n this.context.invoke('editor.insertImage', blobUrl, alt);\n }).catch((err) => {\n const message = `Image \"${file.name}\" could not be processed.`;\n this.context.triggerEvent('imageError', { file, message, error: err });\n if (typeof process === 'undefined' || process.env?.NODE_ENV !== 'production') {\n console.warn('[AutumnNote]', message, err);\n }\n });\n });\n }\n\n /**\n * Replaces any blob: URLs created by this module with their original data URLs.\n * Called by Editor.getHTML() so the returned HTML is fully self-contained.\n * @param {string} html\n * @returns {string}\n */\n resolveImages(html) {\n if (!this._blobRegistry || !this._blobRegistry.size) return html;\n return html.replace(/blob:[^\"'> \\t\\n\\r]*/g, (url) => this._blobRegistry.get(url) || url);\n }\n\n /**\n * Converts a data URL to a Blob (no FileReader — synchronous).\n * @param {string} dataUrl\n * @returns {Blob}\n */\n _dataUrlToBlob(dataUrl) {\n const [header, b64] = dataUrl.split(',');\n const mime = header.match(/:(.*?);/)[1];\n const binary = atob(b64);\n const arr = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) arr[i] = binary.charCodeAt(i);\n return new Blob([arr], { type: mime });\n }\n\n /**\n * Compresses an image File using a Canvas.\n * - Resizes so the longest edge is at most MAX_DIM pixels.\n * - Encodes as WebP (if supported) or JPEG at quality 0.85.\n * Falls back to plain FileReader if canvas is unavailable.\n * @param {File} file\n * @returns {Promise<string>} data URL\n */\n _compressImage(file) {\n const MAX_DIM = 1920;\n const QUALITY = 0.85;\n\n return new Promise((resolve) => {\n const objectUrl = URL.createObjectURL(file);\n const img = new Image();\n\n img.onload = () => {\n URL.revokeObjectURL(objectUrl);\n\n let { width, height } = img;\n if (width > MAX_DIM || height > MAX_DIM) {\n if (width >= height) {\n height = Math.round((height * MAX_DIM) / width);\n width = MAX_DIM;\n } else {\n width = Math.round((width * MAX_DIM) / height);\n height = MAX_DIM;\n }\n }\n\n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n const ctx = canvas.getContext('2d');\n if (!ctx) {\n // Canvas context unavailable (e.g. device memory limit) — fall back to\n // embedding the original file without compression.\n const reader = new FileReader();\n reader.onload = (e) => resolve(/** @type {string} */ (e.target.result));\n reader.readAsDataURL(file);\n return;\n }\n ctx.drawImage(img, 0, 0, width, height);\n\n // Prefer WebP for better compression; fall back to JPEG\n const webp = canvas.toDataURL('image/webp', QUALITY);\n resolve(webp.startsWith('data:image/webp') ? webp : canvas.toDataURL('image/jpeg', QUALITY));\n };\n\n img.onerror = () => {\n URL.revokeObjectURL(objectUrl);\n // Fallback: embed original without compression\n const reader = new FileReader();\n reader.onload = (e) => resolve(/** @type {string} */ (e.target.result));\n reader.readAsDataURL(file);\n };\n\n img.src = objectUrl;\n });\n }\n\n /**\n * Positions the caret at the given viewport coordinates.\n * Supports both Chrome (caretRangeFromPoint) and Firefox (caretPositionFromPoint).\n * @param {number} x\n * @param {number} y\n */\n _placeCaretAtPoint(x, y) {\n let range;\n if (document.caretRangeFromPoint) {\n range = document.caretRangeFromPoint(x, y);\n } else if (document.caretPositionFromPoint) {\n const pos = document.caretPositionFromPoint(x, y);\n if (pos) {\n range = document.createRange();\n range.setStart(pos.offsetNode, pos.offset);\n range.collapse(true);\n }\n }\n if (!range) return;\n const sel = window.getSelection();\n if (sel) {\n sel.removeAllRanges();\n sel.addRange(range);\n }\n }\n\n // ---------------------------------------------------------------------------\n // Helpers\n // ---------------------------------------------------------------------------\n\n /**\n * Escapes HTML special characters.\n * @param {string} str\n * @returns {string}\n */\n _escapeHTML(str) {\n return str\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n }\n}\n","/**\n * Placeholder.js - Shows placeholder text when the editor is empty\n * Inspired by Summernote's Placeholder module\n */\n\nimport { on } from '../core/dom.js';\n\nexport class Placeholder {\n /**\n * @param {import('../Context.js').Context} context\n */\n constructor(context) {\n this.context = context;\n this.options = context.options;\n this._disposers = [];\n }\n\n initialize() {\n const editable = this.context.layoutInfo.editable;\n const placeholder = this.options.placeholder || '';\n if (placeholder) {\n editable.dataset.placeholder = placeholder;\n }\n\n const update = () => this._update();\n const d1 = on(editable, 'input', update);\n const d2 = on(editable, 'focus', update);\n const d3 = on(editable, 'blur', update);\n this._disposers.push(d1, d2, d3);\n this._update();\n return this;\n }\n\n destroy() {\n this._disposers.forEach((d) => d());\n this._disposers = [];\n }\n\n _update() {\n const editable = this.context.layoutInfo.editable;\n const isFocused = document.activeElement === editable;\n const isEmpty = !editable.textContent.trim() && !editable.querySelector('img, table, hr');\n editable.classList.toggle('an-placeholder', isEmpty && !isFocused);\n }\n}\n","/**\n * Codeview.js - HTML source code view / WYSIWYG toggle\n * Inspired by Summernote's Codeview module\n */\n\nimport { createElement } from '../core/dom.js';\nimport { sanitiseHTML } from '../core/sanitise.js';\n\nexport class Codeview {\n /**\n * @param {import('../Context.js').Context} context\n */\n constructor(context) {\n this.context = context;\n this.options = context.options;\n this._active = false;\n /** @type {HTMLTextAreaElement|null} */\n this._textarea = null;\n this._disposers = [];\n }\n\n initialize() {\n return this;\n }\n\n destroy() {\n this._disposers.forEach((d) => d());\n this._disposers = [];\n if (this._textarea && this._textarea.parentNode) {\n this._textarea.parentNode.removeChild(this._textarea);\n }\n this._textarea = null;\n }\n\n // ---------------------------------------------------------------------------\n // Public API\n // ---------------------------------------------------------------------------\n\n toggle() {\n if (this._active) {\n this.deactivate();\n } else {\n this.activate();\n }\n }\n\n isActive() {\n return this._active;\n }\n\n activate() {\n if (this._active) return;\n const { editable } = this.context.layoutInfo;\n const html = editable.innerHTML;\n\n this._textarea = createElement('textarea', {\n class: 'an-codeview',\n spellcheck: 'false',\n autocomplete: 'off',\n autocorrect: 'off',\n autocapitalize: 'off',\n });\n this._textarea.value = this._prettyPrint(html);\n\n editable.style.display = 'none';\n editable.parentNode.insertBefore(this._textarea, editable.nextSibling);\n\n this._active = true;\n this.context.invoke('toolbar.refresh');\n }\n\n deactivate() {\n if (!this._active || !this._textarea) return;\n const { editable } = this.context.layoutInfo;\n // Sanitise the HTML typed in the textarea before applying (allow iframes for video embeds)\n editable.innerHTML = sanitiseHTML(this._textarea.value, { allowIframes: true });\n this._textarea.parentNode.removeChild(this._textarea);\n this._textarea = null;\n editable.style.display = '';\n this._active = false;\n this.context.invoke('toolbar.refresh');\n this.context.invoke('editor.afterCommand');\n }\n\n // ---------------------------------------------------------------------------\n // Helpers\n // ---------------------------------------------------------------------------\n\n /**\n * Very simple HTML pretty-printer (indent nested tags).\n * Inline elements (a, span, strong, em, etc.) are kept on one line to\n * avoid injecting whitespace that would change rendered text.\n * @param {string} html\n * @returns {string}\n */\n _prettyPrint(html) {\n // Tags whose content must NOT be split with newlines (breaks text rendering)\n const INLINE_RE = /^<(a|abbr|b|bdo|br|button|cite|code|dfn|em|i|img|input|kbd|label|output|q|samp|select|small|span|strong|sub|sup|textarea|time|tt|u|var)([\\s>/])/i;\n let indent = 0;\n return html\n .replace(/>\\s*</g, (match, offset, str) => {\n // Check what comes after the '>' — if it starts an inline tag, keep on same line\n const remaining = str.slice(offset + 1);\n if (INLINE_RE.test(remaining.trimStart())) return '><';\n return '>\\n<';\n })\n .split('\\n')\n .map((line) => {\n const stripped = line.trim();\n if (!stripped) return '';\n if (/^<\\//.test(stripped)) indent = Math.max(0, indent - 1);\n const out = ' '.repeat(indent) + stripped;\n if (\n /^<[^/!][^>]*[^/]>/.test(stripped) &&\n !INLINE_RE.test(stripped) &&\n !/^<(br|hr|img|input|link|meta)/.test(stripped)\n ) {\n indent++;\n }\n return out;\n })\n .filter(Boolean)\n .join('\\n');\n }\n\n}\n\n","/**\n * Fullscreen.js - Toggles the editor in/out of fullscreen mode\n * Inspired by Summernote's Fullscreen module\n */\n\nimport { on } from '../core/dom.js';\nimport { key, isKey } from '../core/key.js';\n\nexport class Fullscreen {\n /**\n * @param {import('../Context.js').Context} context\n */\n constructor(context) {\n this.context = context;\n this._active = false;\n this._disposers = [];\n /** @type {string} cached editable height before fullscreen */\n this._prevHeight = '';\n }\n\n initialize() {\n // Press Escape to exit fullscreen\n const d = on(document, 'keydown', (event) => {\n if (this._active && isKey(event, key.ESCAPE)) {\n this.deactivate();\n }\n });\n this._disposers.push(d);\n return this;\n }\n\n destroy() {\n this._disposers.forEach((d) => d());\n this._disposers = [];\n if (this._active) this.deactivate();\n }\n\n // ---------------------------------------------------------------------------\n // Public API\n // ---------------------------------------------------------------------------\n\n toggle() {\n if (this._active) {\n this.deactivate();\n } else {\n this.activate();\n }\n }\n\n isActive() {\n return this._active;\n }\n\n activate() {\n if (this._active) return;\n const container = this.context.layoutInfo.container;\n // Save the container's explicit height (set by the resize handle) so it\n // can be restored when exiting fullscreen.\n this._prevHeight = container.style.height;\n\n container.classList.add('an-fullscreen');\n // Clear any resize-imposed height so the fullscreen CSS (inset:0) takes over.\n container.style.height = '';\n document.body.style.overflow = 'hidden';\n this._active = true;\n this.context.invoke('toolbar.refresh');\n }\n\n deactivate() {\n if (!this._active) return;\n const container = this.context.layoutInfo.container;\n\n container.classList.remove('an-fullscreen');\n // Restore whatever explicit height the user had set via the resize handle.\n container.style.height = this._prevHeight;\n document.body.style.overflow = '';\n this._active = false;\n this.context.invoke('toolbar.refresh');\n }\n}\n","/**\n * LinkDialog.js - Dialog for inserting / editing hyperlinks\n * Inspired by Summernote's LinkDialog — rewritten without jQuery\n */\n\nimport { createElement, on, trapFocus } from '../core/dom.js';\nimport { withSavedRange } from '../core/range.js';\n\nexport class LinkDialog {\n /**\n * @param {import('../Context.js').Context} context\n */\n constructor(context) {\n this.context = context;\n this.options = context.options;\n /** @type {HTMLElement|null} */\n this._dialog = null;\n this._disposers = [];\n this._savedRange = null;\n }\n\n // ---------------------------------------------------------------------------\n // Lifecycle\n // ---------------------------------------------------------------------------\n\n initialize() {\n this._dialog = this._buildDialog();\n document.body.appendChild(this._dialog);\n return this;\n }\n\n destroy() {\n this._disposers.forEach((d) => d());\n this._disposers = [];\n if (this._dialog && this._dialog.parentNode) {\n this._dialog.parentNode.removeChild(this._dialog);\n }\n this._dialog = null;\n }\n\n // ---------------------------------------------------------------------------\n // Public API\n // ---------------------------------------------------------------------------\n\n /**\n * Opens the link dialog.\n * Pre-fills with the currently selected link if present.\n */\n show() {\n withSavedRange((range) => {\n this._savedRange = range;\n });\n this._prefill();\n this._open();\n }\n\n // ---------------------------------------------------------------------------\n // Build dialog\n // ---------------------------------------------------------------------------\n\n _buildDialog() {\n const overlay = createElement('div', { class: 'an-dialog-overlay', role: 'dialog', 'aria-modal': 'true', 'aria-label': 'Insert link' });\n const box = createElement('div', { class: 'an-dialog-box' });\n\n const title = createElement('h3', { class: 'an-dialog-title' });\n title.textContent = 'Insert Link';\n\n // URL field\n const urlLabel = createElement('label', { class: 'an-label' });\n urlLabel.textContent = 'URL';\n const urlInput = createElement('input', {\n type: 'url',\n class: 'an-input',\n placeholder: 'https://',\n id: 'an-link-url',\n name: 'url',\n autocomplete: 'off',\n });\n this._urlInput = urlInput;\n\n // Text field\n const textLabel = createElement('label', { class: 'an-label' });\n textLabel.textContent = 'Display Text';\n const textInput = createElement('input', {\n type: 'text',\n class: 'an-input',\n placeholder: 'Link text',\n id: 'an-link-text',\n name: 'linkText',\n autocomplete: 'off',\n });\n this._textInput = textInput;\n\n // Open in new tab\n const tabLabel = createElement('label', { class: 'an-label an-label-inline' });\n const tabCheckbox = createElement('input', {\n type: 'checkbox',\n id: 'an-link-newtab',\n name: 'openInNewTab',\n });\n this._tabCheckbox = tabCheckbox;\n tabLabel.appendChild(tabCheckbox);\n tabLabel.appendChild(document.createTextNode(' Open in new tab'));\n\n // Buttons\n const btnRow = createElement('div', { class: 'an-dialog-actions' });\n const insertBtn = createElement('button', { type: 'button', class: 'an-btn an-btn-primary' });\n insertBtn.textContent = 'Insert';\n const cancelBtn = createElement('button', { type: 'button', class: 'an-btn' });\n cancelBtn.textContent = 'Cancel';\n btnRow.appendChild(insertBtn);\n btnRow.appendChild(cancelBtn);\n\n box.append(title, urlLabel, urlInput, textLabel, textInput, tabLabel, btnRow);\n overlay.appendChild(box);\n\n // Events\n const d1 = on(insertBtn, 'click', () => this._onInsert());\n const d2 = on(cancelBtn, 'click', () => this._close());\n const d3 = on(overlay, 'click', (e) => { if (e.target === overlay) this._close(); });\n const d4 = on(urlInput, 'keydown', (e) => { if (e.key === 'Enter') { e.preventDefault(); this._onInsert(); } });\n const d5 = on(textInput, 'keydown', (e) => { if (e.key === 'Enter') { e.preventDefault(); this._onInsert(); } });\n this._disposers.push(d1, d2, d3, d4, d5);\n\n return overlay;\n }\n\n // ---------------------------------------------------------------------------\n // Actions\n // ---------------------------------------------------------------------------\n\n _prefill() {\n // Try to find currently selected anchor\n const sel = window.getSelection();\n let anchor = null;\n if (sel && sel.rangeCount > 0) {\n let node = sel.getRangeAt(0).startContainer;\n while (node) {\n if (node.nodeName === 'A') { anchor = node; break; }\n node = node.parentNode;\n }\n }\n if (anchor) {\n this._urlInput.value = anchor.getAttribute('href') || '';\n this._textInput.value = anchor.textContent || '';\n this._tabCheckbox.checked = anchor.getAttribute('target') === '_blank';\n } else {\n this._urlInput.value = '';\n this._textInput.value = sel ? sel.toString() : '';\n this._tabCheckbox.checked = false;\n }\n }\n\n _onInsert() {\n let url = this._urlInput.value.trim();\n const text = this._textInput.value.trim();\n const newTab = this._tabCheckbox.checked;\n\n if (!url) {\n this._urlInput.focus();\n return;\n }\n\n // Auto-prefix with https:// if no protocol is present\n if (!/^[a-zA-Z][a-zA-Z\\d+\\-.]*:/.test(url)) {\n url = 'https://' + url;\n }\n\n // Block unsafe protocols\n try {\n const parsed = new URL(url);\n if (/^javascript:/i.test(parsed.protocol) || /^vbscript:/i.test(parsed.protocol) || /^data:/i.test(parsed.protocol)) {\n this._urlInput.focus();\n return;\n }\n } catch {\n // URL constructor failed — not a valid URL\n this._urlInput.focus();\n return;\n }\n\n // Restore selection then insert\n if (this._savedRange) {\n this._savedRange.select();\n }\n\n this.context.invoke('editor.insertLink', url, text, newTab);\n this._close();\n }\n\n _open() {\n if (this._dialog) {\n this._dialog.style.display = 'flex';\n this._removeTrap = trapFocus(this._dialog, () => this._close());\n setTimeout(() => this._urlInput && this._urlInput.focus(), 50);\n }\n }\n\n _close() {\n if (this._dialog) this._dialog.style.display = 'none';\n if (this._removeTrap) { this._removeTrap(); this._removeTrap = null; }\n this._savedRange = null;\n }\n}\n","/**\n * ImageDialog.js - Dialog for inserting images (by URL or file upload)\n * Inspired by Summernote's ImageDialog — rewritten without jQuery\n */\n\nimport { createElement, on, trapFocus } from '../core/dom.js';\nimport { withSavedRange } from '../core/range.js';\n\nexport class ImageDialog {\n /**\n * @param {import('../Context.js').Context} context\n */\n constructor(context) {\n this.context = context;\n this.options = context.options;\n /** @type {HTMLElement|null} */\n this._dialog = null;\n this._disposers = [];\n this._savedRange = null;\n }\n\n // ---------------------------------------------------------------------------\n // Lifecycle\n // ---------------------------------------------------------------------------\n\n initialize() {\n this._dialog = this._buildDialog();\n document.body.appendChild(this._dialog);\n return this;\n }\n\n destroy() {\n this._disposers.forEach((d) => d());\n this._disposers = [];\n if (this._dialog && this._dialog.parentNode) {\n this._dialog.parentNode.removeChild(this._dialog);\n }\n this._dialog = null;\n }\n\n // ---------------------------------------------------------------------------\n // Public API\n // ---------------------------------------------------------------------------\n\n show() {\n withSavedRange((range) => {\n this._savedRange = range;\n });\n this._urlInput.value = '';\n this._altInput.value = '';\n if (this._fileInput) this._fileInput.value = '';\n this._open();\n }\n\n // ---------------------------------------------------------------------------\n // Build dialog\n // ---------------------------------------------------------------------------\n\n _buildDialog() {\n const overlay = createElement('div', {\n class: 'an-dialog-overlay',\n role: 'dialog',\n 'aria-modal': 'true',\n 'aria-label': 'Insert image',\n });\n const box = createElement('div', { class: 'an-dialog-box' });\n\n const title = createElement('h3', { class: 'an-dialog-title' });\n title.textContent = 'Insert Image';\n\n // URL tab\n const urlLabel = createElement('label', { class: 'an-label' });\n urlLabel.textContent = 'Image URL';\n const urlInput = createElement('input', {\n type: 'url',\n class: 'an-input',\n placeholder: 'https://example.com/image.png',\n autocomplete: 'off',\n });\n this._urlInput = urlInput;\n\n // Alt text\n const altLabel = createElement('label', { class: 'an-label' });\n altLabel.textContent = 'Alt Text';\n const altInput = createElement('input', {\n type: 'text',\n class: 'an-input',\n placeholder: 'Describe the image',\n autocomplete: 'off',\n });\n this._altInput = altInput;\n\n box.append(title, urlLabel, urlInput, altLabel, altInput);\n\n // Alignment\n const alignLabel = createElement('label', { class: 'an-label' });\n alignLabel.textContent = 'Alignment';\n const alignRow = createElement('div', { class: 'an-align-row' });\n const alignOptions = [\n { value: '', label: 'None' },\n { value: 'left', label: 'Left' },\n { value: 'center', label: 'Center' },\n { value: 'right', label: 'Right' },\n ];\n alignOptions.forEach(({ value, label }) => {\n const radioId = `an-align-${value || 'none'}`;\n const radio = createElement('input', { type: 'radio', name: 'an-img-align', id: radioId, value });\n if (value === '') radio.checked = true;\n const lbl = createElement('label', { for: radioId, class: 'an-align-label' });\n lbl.textContent = label;\n alignRow.append(radio, lbl);\n });\n this._alignRow = alignRow;\n box.append(alignLabel, alignRow);\n if (this.options.allowImageUpload !== false) {\n const fileLabel = createElement('label', { class: 'an-label' });\n fileLabel.textContent = 'Or upload a file';\n const fileInput = createElement('input', {\n type: 'file',\n class: 'an-input',\n accept: 'image/*',\n });\n this._fileInput = fileInput;\n const d = on(fileInput, 'change', () => this._onFileChange());\n this._disposers.push(d);\n box.append(fileLabel, fileInput);\n }\n\n // Buttons\n const btnRow = createElement('div', { class: 'an-dialog-actions' });\n const insertBtn = createElement('button', { type: 'button', class: 'an-btn an-btn-primary' });\n insertBtn.textContent = 'Insert';\n const cancelBtn = createElement('button', { type: 'button', class: 'an-btn' });\n cancelBtn.textContent = 'Cancel';\n btnRow.appendChild(insertBtn);\n btnRow.appendChild(cancelBtn);\n\n box.append(btnRow);\n overlay.appendChild(box);\n\n const d1 = on(insertBtn, 'click', () => this._onInsert());\n const d2 = on(cancelBtn, 'click', () => this._close());\n const d3 = on(overlay, 'click', (e) => { if (e.target === overlay) this._close(); });\n const d4 = on(urlInput, 'keydown', (e) => { if (e.key === 'Enter') { e.preventDefault(); this._onInsert(); } });\n const d5 = on(altInput, 'keydown', (e) => { if (e.key === 'Enter') { e.preventDefault(); this._onInsert(); } });\n this._disposers.push(d1, d2, d3, d4, d5);\n\n return overlay;\n }\n\n // ---------------------------------------------------------------------------\n // Actions\n // ---------------------------------------------------------------------------\n\n _onFileChange() {\n const file = this._fileInput && this._fileInput.files && this._fileInput.files[0];\n if (!file || !file.type.startsWith('image/')) return;\n\n // Validate file size (max 5 MB by default)\n const maxSize = (this.options.maxImageSize || 5) * 1024 * 1024;\n if (file.size > maxSize) {\n const message = `Image file is too large. Maximum allowed size is ${this.options.maxImageSize || 5} MB.`;\n console.warn('[AutumnNote] ImageDialog:', message);\n this.context.triggerEvent('imageError', { file, message });\n this._fileInput.value = '';\n return;\n }\n\n const reader = new FileReader();\n reader.onload = (e) => {\n this._urlInput.value = e.target.result;\n };\n reader.readAsDataURL(file);\n }\n\n _onInsert() {\n const src = this._urlInput.value.trim();\n const alt = this._altInput.value.trim();\n const alignRadio = this._alignRow && this._alignRow.querySelector('input[name=\"an-img-align\"]:checked');\n const align = alignRadio ? alignRadio.value : '';\n\n if (!src) {\n this._urlInput.focus();\n return;\n }\n\n if (this._savedRange) {\n this._savedRange.select();\n }\n\n this.context.invoke('editor.insertImage', src, alt, align);\n this._close();\n }\n\n _open() {\n if (this._dialog) {\n this._dialog.style.display = 'flex';\n this._removeTrap = trapFocus(this._dialog, () => this._close());\n setTimeout(() => this._urlInput && this._urlInput.focus(), 50);\n }\n }\n\n _close() {\n if (this._dialog) this._dialog.style.display = 'none';\n if (this._removeTrap) { this._removeTrap(); this._removeTrap = null; }\n this._savedRange = null;\n }\n}\n","/**\n * VideoDialog.js - Dialog for inserting videos (YouTube, Vimeo, or direct file)\n * Supports:\n * • YouTube watch URLs → <iframe> embed\n * • YouTube short URLs → <iframe> embed\n * • Vimeo URLs → <iframe> embed\n * • Direct video URLs → <video> element (.mp4 / .webm / .ogg)\n */\n\nimport { createElement, on, trapFocus } from '../core/dom.js';\nimport { withSavedRange } from '../core/range.js';\n\nexport class VideoDialog {\n /** @param {import('../Context.js').Context} context */\n constructor(context) {\n this.context = context;\n this.options = context.options;\n /** @type {HTMLElement|null} */\n this._dialog = null;\n this._disposers = [];\n this._savedRange = null;\n }\n\n // ---------------------------------------------------------------------------\n // Lifecycle\n // ---------------------------------------------------------------------------\n\n initialize() {\n this._dialog = this._buildDialog();\n document.body.appendChild(this._dialog);\n return this;\n }\n\n destroy() {\n this._disposers.forEach((d) => d());\n this._disposers = [];\n if (this._dialog && this._dialog.parentNode) {\n this._dialog.parentNode.removeChild(this._dialog);\n }\n this._dialog = null;\n }\n\n // ---------------------------------------------------------------------------\n // Public API\n // ---------------------------------------------------------------------------\n\n show() {\n withSavedRange((range) => {\n this._savedRange = range;\n });\n this._urlInput.value = '';\n this._widthInput.value = '560';\n this._hintEl.textContent = '';\n this._open();\n }\n\n // ---------------------------------------------------------------------------\n // Build dialog\n // ---------------------------------------------------------------------------\n\n _buildDialog() {\n const overlay = createElement('div', {\n class: 'an-dialog-overlay',\n role: 'dialog',\n 'aria-modal': 'true',\n 'aria-label': 'Insert video',\n });\n const box = createElement('div', { class: 'an-dialog-box' });\n\n const title = createElement('h3', { class: 'an-dialog-title' });\n title.textContent = 'Insert Video';\n\n // URL input\n const urlLabel = createElement('label', { class: 'an-label' });\n urlLabel.textContent = 'Video URL';\n const urlInput = createElement('input', {\n type: 'url',\n class: 'an-input',\n placeholder: 'YouTube, Vimeo, or direct .mp4 URL',\n autocomplete: 'off',\n });\n this._urlInput = urlInput;\n\n // Hint (detected source)\n const hintEl = createElement('p', { class: 'an-dialog-hint' });\n this._hintEl = hintEl;\n\n // Width\n const widthLabel = createElement('label', { class: 'an-label' });\n widthLabel.textContent = 'Width (px)';\n const widthInput = createElement('input', {\n type: 'number',\n class: 'an-input',\n placeholder: '560',\n min: '80',\n max: '1920',\n value: '560',\n });\n this._widthInput = widthInput;\n\n // Buttons\n const btnRow = createElement('div', { class: 'an-dialog-actions' });\n const insertBtn = createElement('button', { type: 'button', class: 'an-btn an-btn-primary' });\n insertBtn.textContent = 'Insert';\n const cancelBtn = createElement('button', { type: 'button', class: 'an-btn' });\n cancelBtn.textContent = 'Cancel';\n btnRow.appendChild(insertBtn);\n btnRow.appendChild(cancelBtn);\n\n box.append(title, urlLabel, urlInput, hintEl, widthLabel, widthInput, btnRow);\n overlay.appendChild(box);\n\n // Live URL hint\n const d0 = on(urlInput, 'input', () => {\n const info = this._parseVideoUrl(urlInput.value.trim());\n hintEl.textContent = info ? `Detected: ${info.type}` : (urlInput.value ? 'Unknown format — will try direct video embed' : '');\n });\n\n const d1 = on(insertBtn, 'click', () => this._onInsert());\n const d2 = on(cancelBtn, 'click', () => this._close());\n const d3 = on(overlay, 'click', (e) => { if (e.target === overlay) this._close(); });\n const d4 = on(urlInput, 'keydown', (e) => { if (e.key === 'Enter') { e.preventDefault(); this._onInsert(); } });\n this._disposers.push(d0, d1, d2, d3, d4);\n\n return overlay;\n }\n\n // ---------------------------------------------------------------------------\n // Actions\n // ---------------------------------------------------------------------------\n\n _onInsert() {\n const rawUrl = this._urlInput.value.trim();\n const width = Math.max(80, parseInt(this._widthInput.value, 10) || 560);\n\n if (!rawUrl) {\n this._urlInput.focus();\n return;\n }\n\n const html = this._buildEmbedHtml(rawUrl, width);\n if (!html) {\n this._hintEl.textContent = 'Invalid URL — please enter a valid video link.';\n this._urlInput.focus();\n return;\n }\n\n if (this._savedRange) this._savedRange.select();\n this.context.invoke('editor.insertVideo', html);\n this._close();\n }\n\n _open() {\n if (this._dialog) {\n this._dialog.style.display = 'flex';\n this._removeTrap = trapFocus(this._dialog, () => this._close());\n setTimeout(() => this._urlInput && this._urlInput.focus(), 50);\n }\n }\n\n _close() {\n if (this._dialog) this._dialog.style.display = 'none';\n if (this._removeTrap) { this._removeTrap(); this._removeTrap = null; }\n this._savedRange = null;\n }\n\n // ---------------------------------------------------------------------------\n // URL parsing & HTML building\n // ---------------------------------------------------------------------------\n\n /**\n * Parses a video URL and returns { type, embedUrl } or null.\n * @param {string} url\n * @returns {{ type: string, embedUrl: string }|null}\n */\n _parseVideoUrl(url) {\n if (!url) return null;\n\n // Validate — block javascript: and other dangerous protocols\n try {\n const parsed = new URL(url);\n if (/^javascript:/i.test(parsed.protocol) || /^vbscript:/i.test(parsed.protocol)) return null;\n } catch { return null; }\n\n // YouTube watch: https://www.youtube.com/watch?v=ID\n const ytWatch = url.match(/(?:youtube\\.com\\/watch\\?(?:.*&)?v=|youtube\\.com\\/embed\\/)([a-zA-Z0-9_-]{11})/);\n if (ytWatch) return { type: 'YouTube', embedUrl: `https://www.youtube.com/embed/${ytWatch[1]}` };\n\n // YouTube short: https://youtu.be/ID\n const ytShort = url.match(/youtu\\.be\\/([a-zA-Z0-9_-]{11})/);\n if (ytShort) return { type: 'YouTube', embedUrl: `https://www.youtube.com/embed/${ytShort[1]}` };\n\n // YouTube Shorts: https://www.youtube.com/shorts/ID\n const ytShorts = url.match(/youtube\\.com\\/shorts\\/([a-zA-Z0-9_-]{11})/);\n if (ytShorts) return { type: 'YouTube Shorts', embedUrl: `https://www.youtube.com/embed/${ytShorts[1]}` };\n\n // Vimeo: https://vimeo.com/ID\n const vimeo = url.match(/vimeo\\.com\\/(\\d+)/);\n if (vimeo) return { type: 'Vimeo', embedUrl: `https://player.vimeo.com/video/${vimeo[1]}` };\n\n // Direct video file\n if (/\\.(mp4|webm|ogg|ogv|mov)(#.*|\\?.*)?$/i.test(url)) {\n return { type: 'Direct video', embedUrl: url };\n }\n\n return null;\n }\n\n /**\n * Builds the HTML string to insert.\n * @param {string} url\n * @param {number} width\n * @returns {string|null}\n */\n _buildEmbedHtml(url, width) {\n const info = this._parseVideoUrl(url);\n const height = Math.round(width * 9 / 16); // 16:9\n\n if (info && (info.type === 'YouTube' || info.type === 'YouTube Shorts' || info.type === 'Vimeo')) {\n const iframeTitle = `${info.type} video player`;\n return (\n `<div class=\"an-video-wrapper\" style=\"position:relative;display:block;width:${width}px;max-width:100%\">` +\n `<iframe src=\"${info.embedUrl}\" width=\"${width}\" height=\"${height}\" ` +\n `title=\"${iframeTitle}\" ` +\n `frameborder=\"0\" allowfullscreen ` +\n `allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" ` +\n `style=\"display:block;max-width:100%\"></iframe>` +\n `<div class=\"an-video-shield\"></div>` +\n `</div>`\n );\n }\n\n if (info && info.type === 'Direct video') {\n const src = info.embedUrl.replace(/\"/g, '%22');\n return (\n `<div class=\"an-video-wrapper\" style=\"position:relative;display:block;width:${width}px;max-width:100%\">` +\n `<video src=\"${src}\" width=\"${width}\" height=\"${height}\" controls ` +\n `style=\"display:block;max-width:100%\"></video>` +\n `<div class=\"an-video-shield\"></div>` +\n `</div>`\n );\n }\n\n // Unknown URL — let the user try as a direct video\n const safeSrc = (() => {\n try {\n const p = new URL(url);\n if (/^javascript:/i.test(p.protocol) || /^vbscript:/i.test(p.protocol)) return null;\n return url;\n } catch { return null; }\n })();\n if (!safeSrc) return null;\n\n const escapedSrc = safeSrc.replace(/\"/g, '%22');\n return (\n `<div class=\"an-video-wrapper\" style=\"position:relative;display:block;width:${width}px;max-width:100%\">` +\n `<video src=\"${escapedSrc}\" width=\"${width}\" height=\"${height}\" controls ` +\n `style=\"display:block;max-width:100%\"></video>` +\n `<div class=\"an-video-shield\"></div>` +\n `</div>`\n );\n }\n}\n","// ImageResizer.js - Interactive resize handles for selected images in the editor\nimport { on } from '../core/dom.js';\n\n/**\n * Eight handle positions. 'pos' is used as CSS class suffix and\n * to determine which axis/direction is being dragged.\n *\n * Pos length 2 → corner handle → maintain aspect ratio.\n * Pos length 1 → edge handle → single-axis resize.\n */\nconst HANDLE_DEFS = [\n { pos: 'nw', cursor: 'nw-resize' },\n { pos: 'n', cursor: 'n-resize' },\n { pos: 'ne', cursor: 'ne-resize' },\n { pos: 'e', cursor: 'e-resize' },\n { pos: 'se', cursor: 'se-resize' },\n { pos: 's', cursor: 's-resize' },\n { pos: 'sw', cursor: 'sw-resize' },\n { pos: 'w', cursor: 'w-resize' },\n];\n\nexport class ImageResizer {\n /** @param {import('../Context.js').Context} context */\n constructor(context) {\n this.context = context;\n /** @type {HTMLImageElement|null} */\n this._activeImg = null;\n this._overlay = null;\n this._disposers = [];\n this._positionRaf = null;\n }\n\n initialize() {\n this._overlay = this._buildOverlay();\n const container = this.context.layoutInfo.editable.closest('.an-container') || document.body;\n container.appendChild(this._overlay);\n this._container = container;\n\n const editable = this.context.layoutInfo.editable;\n\n // Debounce window resize — _updateOverlayPosition already has rAF gating but\n // every call cancels + re-schedules it; a debounce reduces that churn.\n let _resizeDebounce = null;\n const onWindowResize = () => {\n clearTimeout(_resizeDebounce);\n _resizeDebounce = setTimeout(() => this._updateOverlayPosition(), 100);\n };\n\n this._disposers.push(\n on(editable, 'click', (e) => this._onEditorClick(e)),\n // Also select on right-click so the highlight shows before the context menu\n on(editable, 'contextmenu', (e) => {\n const img = e.target.closest('img');\n if (img) this._select(img);\n }),\n on(document, 'click', (e) => this._onDocClick(e)),\n on(window, 'scroll', () => this._updateOverlayPosition(), { passive: true }),\n on(window, 'resize', onWindowResize),\n on(editable, 'scroll', () => this._updateOverlayPosition(), { passive: true }),\n );\n\n return this;\n }\n\n destroy() {\n this._disposers.forEach((d) => d());\n this._disposers = [];\n if (this._dragDisposers) {\n this._dragDisposers.forEach((d) => d());\n this._dragDisposers = null;\n }\n if (this._positionRaf) {\n cancelAnimationFrame(this._positionRaf);\n this._positionRaf = null;\n }\n this._deselect();\n if (this._overlay && this._overlay.parentNode) {\n this._overlay.parentNode.removeChild(this._overlay);\n }\n this._overlay = null;\n }\n\n // ---------------------------------------------------------------------------\n // Public API used by other modules\n // ---------------------------------------------------------------------------\n\n /** @returns {HTMLImageElement|null} */\n getActiveImage() {\n return this._activeImg;\n }\n\n /** Re-sync overlay position (call after external size changes). */\n updateOverlay() {\n this._updateOverlayPosition();\n }\n\n /** Programmatically clear the current image selection. */\n deselect() {\n this._deselect();\n }\n\n // ---------------------------------------------------------------------------\n // Internal\n // ---------------------------------------------------------------------------\n\n _buildOverlay() {\n const overlay = document.createElement('div');\n overlay.className = 'an-image-resizer';\n overlay.style.display = 'none';\n\n HANDLE_DEFS.forEach(({ pos }) => {\n const h = document.createElement('div');\n h.className = `an-resize-handle an-resize-${pos}`;\n h.dataset.handle = pos;\n // Attach handle listeners here so they're torn down in destroy() via _disposers\n this._disposers.push(\n on(h, 'mousedown', (e) => {\n e.preventDefault();\n e.stopPropagation();\n this._startResize(e, pos);\n }),\n );\n overlay.appendChild(h);\n });\n\n return overlay;\n }\n\n _onEditorClick(e) {\n const img = e.target.closest('img');\n if (img) {\n // Prevent browser from deselecting the current text selection / opening native resize\n e.preventDefault();\n this._select(img);\n }\n }\n\n _onDocClick(e) {\n if (!this._activeImg) return;\n if (e.target === this._activeImg) return;\n if (this._overlay && this._overlay.contains(e.target)) return;\n // Don't deselect while interacting with the context menu\n if (e.target.closest('.an-contextmenu')) return;\n this._deselect();\n }\n\n _select(img) {\n if (this._activeImg && this._activeImg !== img) {\n this._activeImg.classList.remove('an-image-selected');\n }\n this._activeImg = img;\n img.classList.add('an-image-selected');\n this._updateOverlayPosition();\n this._overlay.style.display = 'block';\n }\n\n _deselect() {\n if (this._activeImg) {\n this._activeImg.classList.remove('an-image-selected');\n this._activeImg = null;\n }\n if (this._overlay) this._overlay.style.display = 'none';\n }\n\n _updateOverlayPosition() {\n if (this._positionRaf) cancelAnimationFrame(this._positionRaf);\n this._positionRaf = requestAnimationFrame(() => {\n this._positionRaf = null;\n this._updateOverlayPositionNow();\n });\n }\n\n _updateOverlayPositionNow() {\n if (!this._activeImg || !this._overlay) return;\n const offsetParent = this._overlay.offsetParent || this._container;\n const containerRect = offsetParent.getBoundingClientRect();\n const rect = this._activeImg.getBoundingClientRect();\n const left = rect.left - containerRect.left + offsetParent.scrollLeft;\n const top = rect.top - containerRect.top + offsetParent.scrollTop;\n this._overlay.style.left = `${left}px`;\n this._overlay.style.top = `${top}px`;\n this._overlay.style.width = `${rect.width}px`;\n this._overlay.style.height = `${rect.height}px`;\n }\n\n _startResize(e, pos) {\n const img = this._activeImg;\n if (!img) return;\n\n const startX = e.clientX;\n const startY = e.clientY;\n const startW = img.offsetWidth || img.naturalWidth || 100;\n const startH = img.offsetHeight || img.naturalHeight || 100;\n const aspectRatio = startW / (startH || 1);\n const isCorner = pos.length === 2; // 'nw','ne','se','sw'\n\n const editable = this.context.layoutInfo.editable;\n let _raf = null; // rAF handle — ensures at most one write per paint frame\n\n const onMove = (me) => {\n if (_raf !== null) return; // frame already pending, discard this event\n const clientX = me.clientX;\n const clientY = me.clientY;\n _raf = requestAnimationFrame(() => {\n _raf = null;\n const dx = clientX - startX;\n const dy = clientY - startY;\n const maxW = editable.clientWidth || Infinity;\n let newW = startW;\n let newH = startH;\n\n if (pos.includes('e')) newW = Math.max(20, startW + dx);\n if (pos.includes('w')) newW = Math.max(20, startW - dx);\n if (pos.includes('s')) newH = Math.max(20, startH + dy);\n if (pos.includes('n')) newH = Math.max(20, startH - dy);\n\n newW = Math.min(newW, maxW);\n\n if (isCorner) {\n if (Math.abs(dx) >= Math.abs(dy)) {\n newH = Math.max(20, Math.round(newW / aspectRatio));\n } else {\n newW = Math.min(Math.max(20, Math.round(newH * aspectRatio)), maxW);\n newH = Math.max(20, Math.round(newW / aspectRatio));\n }\n }\n\n img.style.width = `${newW}px`;\n img.style.height = `${newH}px`;\n this._updateOverlayPosition();\n });\n };\n\n const onUp = () => {\n if (_raf !== null) { cancelAnimationFrame(_raf); _raf = null; }\n document.removeEventListener('mousemove', onMove);\n document.removeEventListener('mouseup', onUp);\n this._dragDisposers = null;\n this.context.invoke('editor.afterCommand');\n };\n\n document.addEventListener('mousemove', onMove);\n document.addEventListener('mouseup', onUp);\n // Track these so destroy() can clean them up if called during an active drag\n this._dragDisposers = [\n () => document.removeEventListener('mousemove', onMove),\n () => document.removeEventListener('mouseup', onUp),\n ];\n }\n}\n","// VideoResizer.js - Interactive resize handles for selected videos in the editor\n// Targets .an-video-wrapper divs (containing <iframe> or <video>)\nimport { on } from '../core/dom.js';\n\nconst HANDLE_DEFS = [\n { pos: 'nw', cursor: 'nw-resize' },\n { pos: 'n', cursor: 'n-resize' },\n { pos: 'ne', cursor: 'ne-resize' },\n { pos: 'e', cursor: 'e-resize' },\n { pos: 'se', cursor: 'se-resize' },\n { pos: 's', cursor: 's-resize' },\n { pos: 'sw', cursor: 'sw-resize' },\n { pos: 'w', cursor: 'w-resize' },\n];\n\nexport class VideoResizer {\n /** @param {import('../Context.js').Context} context */\n constructor(context) {\n this.context = context;\n /** @type {HTMLElement|null} — the .an-video-wrapper div */\n this._activeWrapper = null;\n this._overlay = null;\n this._disposers = [];\n this._positionRaf = null;\n }\n\n initialize() {\n this._overlay = this._buildOverlay();\n const container = this.context.layoutInfo.editable.closest('.an-container') || document.body;\n container.appendChild(this._overlay);\n this._container = container;\n\n const editable = this.context.layoutInfo.editable;\n\n let _resizeDebounce = null;\n const onWindowResize = () => {\n clearTimeout(_resizeDebounce);\n _resizeDebounce = setTimeout(() => this._updateOverlayPosition(), 100);\n };\n\n this._disposers.push(\n on(editable, 'click', (e) => this._onEditorClick(e)),\n on(editable, 'contextmenu', (e) => {\n const wrapper = this._findWrapper(e.target);\n if (wrapper) this._select(wrapper);\n }),\n on(document, 'click', (e) => this._onDocClick(e)),\n on(window, 'scroll', () => this._updateOverlayPosition(), { passive: true }),\n on(window, 'resize', onWindowResize),\n on(editable, 'scroll', () => this._updateOverlayPosition(), { passive: true }),\n );\n\n return this;\n }\n\n destroy() {\n this._disposers.forEach((d) => d());\n this._disposers = [];\n if (this._dragDisposers) {\n this._dragDisposers.forEach((d) => d());\n this._dragDisposers = null;\n }\n if (this._positionRaf) {\n cancelAnimationFrame(this._positionRaf);\n this._positionRaf = null;\n }\n this._deselect();\n if (this._overlay && this._overlay.parentNode) {\n this._overlay.parentNode.removeChild(this._overlay);\n }\n this._overlay = null;\n }\n\n // ---------------------------------------------------------------------------\n // Public API\n // ---------------------------------------------------------------------------\n\n /** @returns {HTMLElement|null} */\n getActiveWrapper() {\n return this._activeWrapper;\n }\n\n updateOverlay() {\n this._updateOverlayPosition();\n }\n\n deselect() {\n this._deselect();\n }\n\n // ---------------------------------------------------------------------------\n // Internal\n // ---------------------------------------------------------------------------\n\n /**\n * Walk up the DOM from `el` to find the nearest .an-video-wrapper,\n * or an iframe/video whose parent is .an-video-wrapper.\n * @param {EventTarget} el\n * @returns {HTMLElement|null}\n */\n _findWrapper(el) {\n if (!el || !(el instanceof Element)) return null;\n // Direct hit on wrapper\n if (el.classList && el.classList.contains('an-video-wrapper')) return el;\n // Child element (iframe, video, or nested)\n const w = el.closest('.an-video-wrapper');\n if (w) return w;\n return null;\n }\n\n _buildOverlay() {\n const overlay = document.createElement('div');\n overlay.className = 'an-video-resizer';\n overlay.style.display = 'none';\n\n HANDLE_DEFS.forEach(({ pos }) => {\n const h = document.createElement('div');\n h.className = `an-resize-handle an-resize-${pos}`;\n h.dataset.handle = pos;\n this._disposers.push(\n on(h, 'mousedown', (e) => {\n e.preventDefault();\n e.stopPropagation();\n this._startResize(e, pos);\n }),\n );\n overlay.appendChild(h);\n });\n\n return overlay;\n }\n\n _onEditorClick(e) {\n const wrapper = this._findWrapper(e.target);\n if (wrapper) {\n e.preventDefault();\n this._select(wrapper);\n }\n }\n\n _onDocClick(e) {\n if (!this._activeWrapper) return;\n if (this._activeWrapper.contains(e.target)) return;\n if (this._overlay && this._overlay.contains(e.target)) return;\n if (e.target.closest('.an-contextmenu')) return;\n this._deselect();\n }\n\n _select(wrapper) {\n if (this._activeWrapper && this._activeWrapper !== wrapper) {\n this._activeWrapper.classList.remove('an-video-selected');\n }\n this._activeWrapper = wrapper;\n wrapper.classList.add('an-video-selected');\n this._updateOverlayPosition();\n this._overlay.style.display = 'block';\n }\n\n _deselect() {\n if (this._activeWrapper) {\n this._activeWrapper.classList.remove('an-video-selected');\n this._activeWrapper = null;\n }\n if (this._overlay) this._overlay.style.display = 'none';\n }\n\n _updateOverlayPosition() {\n if (this._positionRaf) cancelAnimationFrame(this._positionRaf);\n this._positionRaf = requestAnimationFrame(() => {\n this._positionRaf = null;\n this._updateOverlayPositionNow();\n });\n }\n\n _updateOverlayPositionNow() {\n if (!this._activeWrapper || !this._overlay) return;\n const offsetParent = this._overlay.offsetParent || this._container;\n const containerRect = offsetParent.getBoundingClientRect();\n const rect = this._activeWrapper.getBoundingClientRect();\n const left = rect.left - containerRect.left + offsetParent.scrollLeft;\n const top = rect.top - containerRect.top + offsetParent.scrollTop;\n this._overlay.style.left = `${left}px`;\n this._overlay.style.top = `${top}px`;\n this._overlay.style.width = `${rect.width}px`;\n this._overlay.style.height = `${rect.height}px`;\n }\n\n _startResize(e, pos) {\n const wrapper = this._activeWrapper;\n if (!wrapper) return;\n\n const embed = wrapper.querySelector('iframe, video');\n const startX = e.clientX;\n const startY = e.clientY;\n const startW = wrapper.offsetWidth || 560;\n const startH = wrapper.offsetHeight || 315;\n const aspectRatio = startW / (startH || 1);\n const isCorner = pos.length === 2;\n\n const editable = this.context.layoutInfo.editable;\n let _raf = null; // rAF handle — at most one write per paint frame\n\n const onMove = (me) => {\n if (_raf !== null) return;\n const clientX = me.clientX;\n const clientY = me.clientY;\n _raf = requestAnimationFrame(() => {\n _raf = null;\n const dx = clientX - startX;\n const dy = clientY - startY;\n const maxW = editable.clientWidth || Infinity;\n let newW = startW;\n let newH = startH;\n\n if (pos.includes('e')) newW = Math.max(80, startW + dx);\n if (pos.includes('w')) newW = Math.max(80, startW - dx);\n if (pos.includes('s')) newH = Math.max(45, startH + dy);\n if (pos.includes('n')) newH = Math.max(45, startH - dy);\n\n newW = Math.min(newW, maxW);\n\n if (isCorner) {\n if (Math.abs(dx) >= Math.abs(dy)) {\n newH = Math.max(45, Math.round(newW / aspectRatio));\n } else {\n newW = Math.min(Math.max(80, Math.round(newH * aspectRatio)), maxW);\n newH = Math.max(45, Math.round(newW / aspectRatio));\n }\n }\n\n // Resize wrapper and inner embed via CSS only — attribute writes are redundant\n wrapper.style.width = `${newW}px`;\n wrapper.style.height = `${newH}px`;\n if (embed) {\n embed.style.width = `${newW}px`;\n embed.style.height = `${newH}px`;\n }\n this._updateOverlayPosition();\n });\n };\n\n const onUp = () => {\n if (_raf !== null) { cancelAnimationFrame(_raf); _raf = null; }\n document.removeEventListener('mousemove', onMove);\n document.removeEventListener('mouseup', onUp);\n this._dragDisposers = null;\n this.context.invoke('editor.afterCommand');\n };\n\n document.addEventListener('mousemove', onMove);\n document.addEventListener('mouseup', onUp);\n // Track these so destroy() can clean them up if called during an active drag\n this._dragDisposers = [\n () => document.removeEventListener('mousemove', onMove),\n () => document.removeEventListener('mouseup', onUp),\n ];\n }\n}\n","// LinkTooltip.js - Hover tooltip for links inside the editor\n// Displays a small action bar with: visit link, edit link, unlink\nimport { createElement, on } from '../core/dom.js';\n\nconst ICONS = {\n open: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\"/><polyline points=\"15 3 21 3 21 9\"/><line x1=\"10\" y1=\"14\" x2=\"21\" y2=\"3\"/></svg>`,\n edit: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7\"/><path d=\"M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z\"/></svg>`,\n unlink: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M18.84 12.25l1.72-1.71h-.02a5.004 5.004 0 0 0-.12-7.07 5.006 5.006 0 0 0-6.95 0l-1.72 1.71\"/><path d=\"M5.17 11.75l-1.71 1.71a5.004 5.004 0 0 0 .12 7.07 5.006 5.006 0 0 0 6.95 0l1.71-1.71\"/><line x1=\"8\" y1=\"2\" x2=\"8\" y2=\"5\"/><line x1=\"2\" y1=\"8\" x2=\"5\" y2=\"8\"/><line x1=\"16\" y1=\"19\" x2=\"16\" y2=\"22\"/><line x1=\"19\" y1=\"16\" x2=\"22\" y2=\"16\"/></svg>`,\n copy: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\"/><path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\"/></svg>`,\n};\n\n/** Delay in ms before showing / after hiding to avoid flicker */\nconst SHOW_DELAY = 120;\nconst HIDE_DELAY = 200;\n\nexport class LinkTooltip {\n /** @param {import('../Context.js').Context} context */\n constructor(context) {\n this.context = context;\n this._el = null;\n this._activeAnchor = null;\n this._showTimer = null;\n this._hideTimer = null;\n this._disposers = [];\n }\n\n initialize() {\n this._el = this._buildTooltip();\n document.body.appendChild(this._el);\n\n const editable = this.context.layoutInfo.editable;\n\n this._disposers.push(\n // Detect when pointer enters a link\n on(editable, 'mouseover', (e) => {\n const anchor = e.target.closest('a[href]');\n if (anchor && editable.contains(anchor)) {\n this._scheduleShow(anchor);\n }\n }),\n // Detect when pointer leaves the editable area entirely\n on(editable, 'mouseout', (e) => {\n const to = e.relatedTarget;\n if (!to || (!editable.contains(to) && !this._el.contains(to))) {\n this._scheduleHide();\n }\n }),\n );\n\n return this;\n }\n\n destroy() {\n this._clearTimers();\n this._disposers.forEach((d) => d());\n this._disposers = [];\n if (this._el && this._el.parentNode) this._el.parentNode.removeChild(this._el);\n this._el = null;\n }\n\n // ---------------------------------------------------------------------------\n // Build\n // ---------------------------------------------------------------------------\n\n _buildTooltip() {\n const el = createElement('div', { class: 'an-link-tooltip', role: 'toolbar', 'aria-label': 'Link actions' });\n el.style.display = 'none';\n\n // URL preview text (truncated)\n this._urlLabel = createElement('span', { class: 'an-link-tooltip-url' });\n el.appendChild(this._urlLabel);\n\n // Separator\n el.appendChild(createElement('div', { class: 'an-link-tooltip-sep' }));\n\n // Action buttons\n this._openBtn = this._makeBtn(ICONS.open, 'Open link', () => this._openLink());\n this._copyBtn = this._makeBtn(ICONS.copy, 'Copy URL', () => this._copyLink());\n this._editBtn = this._makeBtn(ICONS.edit, 'Edit link', () => this._editLink());\n this._unlinkBtn = this._makeBtn(ICONS.unlink, 'Remove link', () => this._unlink());\n\n el.appendChild(this._openBtn);\n el.appendChild(this._copyBtn);\n el.appendChild(this._editBtn);\n el.appendChild(this._unlinkBtn);\n\n // Keep tooltip alive while hovering it\n this._disposers.push(\n on(el, 'mouseenter', () => this._clearTimers()),\n on(el, 'mouseleave', () => this._scheduleHide()),\n );\n\n return el;\n }\n\n _makeBtn(icon, title, handler) {\n const btn = createElement('button', { type: 'button', class: 'an-link-tooltip-btn', title });\n btn.innerHTML = icon;\n this._disposers.push(on(btn, 'click', (e) => { e.preventDefault(); e.stopPropagation(); handler(); }));\n return btn;\n }\n\n // ---------------------------------------------------------------------------\n // Show / Hide logic\n // ---------------------------------------------------------------------------\n\n _scheduleShow(anchor) {\n if (this._activeAnchor === anchor && this._el.style.display !== 'none') return;\n clearTimeout(this._hideTimer);\n this._hideTimer = null;\n clearTimeout(this._showTimer);\n this._showTimer = setTimeout(() => {\n this._activeAnchor = anchor;\n this._show(anchor);\n }, SHOW_DELAY);\n }\n\n _scheduleHide() {\n clearTimeout(this._showTimer);\n this._showTimer = null;\n if (this._hideTimer) return;\n this._hideTimer = setTimeout(() => {\n this._hide();\n }, HIDE_DELAY);\n }\n\n _show(anchor) {\n const url = anchor.getAttribute('href') || '';\n this._urlLabel.textContent = this._truncateUrl(url);\n this._urlLabel.title = url;\n this._el.style.display = 'flex';\n this._positionNear(anchor);\n }\n\n _hide() {\n this._el.style.display = 'none';\n this._activeAnchor = null;\n this._clearTimers();\n }\n\n _clearTimers() {\n clearTimeout(this._showTimer);\n clearTimeout(this._hideTimer);\n this._showTimer = null;\n this._hideTimer = null;\n }\n\n _positionNear(anchor) {\n const rect = anchor.getBoundingClientRect();\n const tipW = this._el.offsetWidth || 260;\n const tipH = this._el.offsetHeight || 34;\n const margin = 6;\n\n // Prefer below the link; if no room, put above\n let top = rect.bottom + margin;\n let left = rect.left;\n\n if (top + tipH > window.innerHeight - margin) {\n top = rect.top - tipH - margin;\n }\n if (left + tipW > window.innerWidth - margin) {\n left = window.innerWidth - tipW - margin;\n }\n if (left < margin) left = margin;\n\n this._el.style.top = `${top}px`;\n this._el.style.left = `${left}px`;\n }\n\n _truncateUrl(url) {\n try {\n const u = new URL(url);\n const display = u.host + (u.pathname !== '/' ? u.pathname : '');\n return display.length > 48 ? display.slice(0, 48) + '…' : display;\n } catch {\n return url.length > 48 ? url.slice(0, 48) + '…' : url;\n }\n }\n\n // ---------------------------------------------------------------------------\n // Actions\n // ---------------------------------------------------------------------------\n\n _openLink() {\n const url = this._activeAnchor && this._activeAnchor.getAttribute('href');\n if (url) window.open(url, '_blank', 'noopener,noreferrer');\n this._hide();\n }\n\n _copyLink() {\n const url = this._activeAnchor && this._activeAnchor.getAttribute('href');\n if (url) {\n navigator.clipboard.writeText(url).catch(() => {\n // Fallback for environments where clipboard API is unavailable\n const ta = document.createElement('textarea');\n ta.value = url;\n ta.style.position = 'fixed';\n ta.style.opacity = '0';\n document.body.appendChild(ta);\n ta.select();\n document.execCommand('copy');\n document.body.removeChild(ta);\n });\n }\n // Brief visual feedback \n if (this._copyBtn) {\n this._copyBtn.classList.add('an-link-tooltip-btn--copied');\n setTimeout(() => this._copyBtn && this._copyBtn.classList.remove('an-link-tooltip-btn--copied'), 1000);\n }\n }\n\n _editLink() {\n const anchor = this._activeAnchor;\n if (!anchor) return;\n this._hide();\n\n // Place cursor inside the anchor, then open the link dialog (which pre-fills from selection)\n const sel = window.getSelection();\n const range = document.createRange();\n range.selectNodeContents(anchor);\n sel.removeAllRanges();\n sel.addRange(range);\n\n this.context.invoke('linkDialog.show');\n }\n\n _unlink() {\n const anchor = this._activeAnchor;\n if (!anchor) return;\n this._hide();\n\n // Select the anchor text, then remove the link\n const sel = window.getSelection();\n const range = document.createRange();\n range.selectNode(anchor);\n sel.removeAllRanges();\n sel.addRange(range);\n\n document.execCommand('unlink');\n this.context.invoke('editor.afterCommand');\n }\n}\n","// ImageTooltip.js - Hover tooltip for images inside the editor\n// Displays a horizontal action bar below (or above) the selected image,\n// similar in appearance and interaction to LinkTooltip.\nimport { createElement, on } from '../core/dom.js';\n\nconst ICONS = {\n floatLeft: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"2\" y=\"4\" width=\"8\" height=\"8\" rx=\"1\"/><line x1=\"12\" y1=\"6\" x2=\"22\" y2=\"6\"/><line x1=\"12\" y1=\"9\" x2=\"22\" y2=\"9\"/><line x1=\"12\" y1=\"12\" x2=\"22\" y2=\"12\"/><line x1=\"2\" y1=\"16\" x2=\"22\" y2=\"16\"/><line x1=\"2\" y1=\"20\" x2=\"18\" y2=\"20\"/></svg>`,\n floatRight: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"14\" y=\"4\" width=\"8\" height=\"8\" rx=\"1\"/><line x1=\"2\" y1=\"6\" x2=\"12\" y2=\"6\"/><line x1=\"2\" y1=\"9\" x2=\"12\" y2=\"9\"/><line x1=\"2\" y1=\"12\" x2=\"12\" y2=\"12\"/><line x1=\"2\" y1=\"16\" x2=\"22\" y2=\"16\"/><line x1=\"2\" y1=\"20\" x2=\"18\" y2=\"20\"/></svg>`,\n floatNone: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"3\" width=\"8\" height=\"8\" rx=\"1\"/><line x1=\"3\" y1=\"15\" x2=\"21\" y2=\"15\"/><line x1=\"3\" y1=\"19\" x2=\"17\" y2=\"19\"/></svg>`,\n alignCenter: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"7\" y=\"4\" width=\"10\" height=\"8\" rx=\"1\"/><line x1=\"3\" y1=\"16\" x2=\"21\" y2=\"16\"/><line x1=\"6\" y1=\"20\" x2=\"18\" y2=\"20\"/></svg>`,\n originalSize:`<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"15 3 21 3 21 9\"/><polyline points=\"9 21 3 21 3 15\"/><line x1=\"21\" y1=\"3\" x2=\"14\" y2=\"10\"/><line x1=\"3\" y1=\"21\" x2=\"10\" y2=\"14\"/></svg>`,\n deleteImg: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"3 6 5 6 21 6\"/><path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2\"/></svg>`,\n caption: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"3\" width=\"18\" height=\"11\" rx=\"2\"/><line x1=\"6\" y1=\"18\" x2=\"18\" y2=\"18\"/><line x1=\"9\" y1=\"21\" x2=\"15\" y2=\"21\"/></svg>`,\n rotateLeft: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8\"/><polyline points=\"3 3 3 8 8 8\"/></svg>`,\n rotateRight: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M21 12a9 9 0 1 1-9-9 9.75 9.75 0 0 1 6.74 2.74L21 8\"/><polyline points=\"21 3 21 8 16 8\"/></svg>`,\n};\n\nconst SHOW_DELAY = 100;\nconst HIDE_DELAY = 180;\n\nexport class ImageTooltip {\n /** @param {import('../Context.js').Context} context */\n constructor(context) {\n this.context = context;\n this._el = null;\n this._activeImg = null;\n this._showTimer = null;\n this._hideTimer = null;\n this._disposers = [];\n }\n\n initialize() {\n this._el = this._buildTooltip();\n document.body.appendChild(this._el);\n\n const editable = this.context.layoutInfo.editable;\n\n this._disposers.push(\n on(editable, 'mouseover', (e) => {\n const img = e.target.closest('img');\n // Skip when the image is inside a link — LinkTooltip takes priority there\n if (img && editable.contains(img) && !img.closest('a[href]')) {\n this._scheduleShow(img);\n }\n }, { passive: true }),\n on(editable, 'mouseout', (e) => {\n const to = e.relatedTarget;\n if (!to || (!editable.contains(to) && !this._el.contains(to))) {\n this._scheduleHide();\n }\n }, { passive: true }),\n // Hide when image is deselected by clicking elsewhere\n on(document, 'click', (e) => {\n if (this._activeImg && !this._activeImg.contains(e.target) && !this._el.contains(e.target)) {\n this._hide();\n }\n }),\n );\n\n return this;\n }\n\n destroy() {\n this._clearTimers();\n this._disposers.forEach((d) => d());\n this._disposers = [];\n if (this._el && this._el.parentNode) this._el.parentNode.removeChild(this._el);\n this._el = null;\n }\n\n // ---------------------------------------------------------------------------\n // Build\n // ---------------------------------------------------------------------------\n\n _buildTooltip() {\n const el = createElement('div', {\n class: 'an-link-tooltip an-image-tooltip',\n role: 'toolbar',\n 'aria-label': 'Image actions',\n });\n el.style.display = 'none';\n\n // Label showing \"Image\"\n this._label = createElement('span', { class: 'an-link-tooltip-url' });\n this._label.textContent = 'Image';\n el.appendChild(this._label);\n\n el.appendChild(createElement('div', { class: 'an-link-tooltip-sep' }));\n\n this._floatLeftBtn = this._makeBtn(ICONS.floatLeft, 'Float Left', () => this._setFloat('left'));\n this._floatNoneBtn = this._makeBtn(ICONS.floatNone, 'No Float', () => this._setFloat(''));\n this._alignCenterBtn = this._makeBtn(ICONS.alignCenter, 'Align Center', () => this._setCenter());\n this._floatRightBtn = this._makeBtn(ICONS.floatRight, 'Float Right', () => this._setFloat('right'));\n\n el.appendChild(this._floatLeftBtn);\n el.appendChild(this._floatNoneBtn);\n el.appendChild(this._alignCenterBtn);\n el.appendChild(this._floatRightBtn);\n\n el.appendChild(createElement('div', { class: 'an-link-tooltip-sep' }));\n\n this._originalBtn = this._makeBtn(ICONS.originalSize, 'Original Size', () => this._resetSize());\n\n el.appendChild(this._originalBtn);\n\n el.appendChild(createElement('div', { class: 'an-link-tooltip-sep' }));\n\n el.appendChild(this._makeBtn(ICONS.rotateLeft, 'Rotate Left', () => this._rotate(-90)));\n el.appendChild(this._makeBtn(ICONS.rotateRight, 'Rotate Right', () => this._rotate(90)));\n\n el.appendChild(createElement('div', { class: 'an-link-tooltip-sep' }));\n\n this._captionBtn = this._makeBtn(ICONS.caption, 'Add / Edit Caption', () => this._toggleCaption());\n el.appendChild(this._captionBtn);\n\n el.appendChild(createElement('div', { class: 'an-link-tooltip-sep' }));\n\n this._deleteBtn = this._makeBtn(ICONS.deleteImg, 'Delete Image', () => this._delete(), true);\n\n el.appendChild(this._deleteBtn);\n\n // Keep tooltip alive while hovering it\n this._disposers.push(\n on(el, 'mouseenter', () => this._clearTimers()),\n on(el, 'mouseleave', () => this._scheduleHide()),\n );\n\n return el;\n }\n\n /**\n * @param {string} icon\n * @param {string} title\n * @param {Function} handler\n * @param {boolean} [isDanger]\n */\n _makeBtn(icon, title, handler, isDanger = false) {\n const btn = createElement('button', {\n type: 'button',\n class: isDanger ? 'an-link-tooltip-btn an-link-tooltip-btn--danger' : 'an-link-tooltip-btn',\n title,\n });\n btn.innerHTML = icon;\n this._disposers.push(on(btn, 'click', (e) => {\n e.preventDefault();\n e.stopPropagation();\n handler();\n }));\n return btn;\n }\n\n // ---------------------------------------------------------------------------\n // Show / Hide\n // ---------------------------------------------------------------------------\n\n _scheduleShow(img) {\n if (this._activeImg === img && this._el.style.display !== 'none') return;\n clearTimeout(this._hideTimer);\n this._hideTimer = null;\n clearTimeout(this._showTimer);\n this._showTimer = setTimeout(() => {\n this._activeImg = img;\n this._show(img);\n }, SHOW_DELAY);\n }\n\n _scheduleHide() {\n clearTimeout(this._showTimer);\n this._showTimer = null;\n if (this._hideTimer) return;\n this._hideTimer = setTimeout(() => this._hide(), HIDE_DELAY);\n }\n\n _show(img) {\n this._el.style.display = 'flex';\n // Defer positioning: offsetWidth on a newly-visible element forces layout\n requestAnimationFrame(() => {\n if (this._activeImg) this._positionNear(this._activeImg);\n });\n }\n\n _hide() {\n this._el.style.display = 'none';\n this._activeImg = null;\n this._clearTimers();\n }\n\n _clearTimers() {\n clearTimeout(this._showTimer);\n clearTimeout(this._hideTimer);\n this._showTimer = null;\n this._hideTimer = null;\n }\n\n _positionNear(img) {\n const rect = img.getBoundingClientRect();\n const tipW = this._el.offsetWidth || 220;\n const tipH = this._el.offsetHeight || 32;\n const margin = 6;\n\n let top = rect.bottom + margin;\n let left = rect.left + (rect.width - tipW) / 2;\n\n if (top + tipH > window.innerHeight - margin) top = rect.top - tipH - margin;\n if (left + tipW > window.innerWidth - margin) left = window.innerWidth - tipW - margin;\n if (left < margin) left = margin;\n\n this._el.style.top = `${top}px`;\n this._el.style.left = `${left}px`;\n }\n\n // ---------------------------------------------------------------------------\n // Actions\n // ---------------------------------------------------------------------------\n\n _setFloat(value) {\n const img = this._activeImg;\n if (!img) return;\n const target = img.closest('figure.an-figure') || img;\n target.style.float = value;\n target.style.display = '';\n target.style.marginLeft = value === 'right' ? '12px' : '';\n target.style.marginRight = value === 'left' ? '12px' : '';\n this.context.invoke('editor.afterCommand');\n this.context.invoke('imageResizer.updateOverlay');\n requestAnimationFrame(() => { if (this._activeImg) this._positionNear(this._activeImg); });\n }\n\n _setCenter() {\n const img = this._activeImg;\n if (!img) return;\n const target = img.closest('figure.an-figure') || img;\n target.style.float = '';\n target.style.display = 'block';\n target.style.marginLeft = 'auto';\n target.style.marginRight = 'auto';\n this.context.invoke('editor.afterCommand');\n this.context.invoke('imageResizer.updateOverlay');\n requestAnimationFrame(() => { if (this._activeImg) this._positionNear(this._activeImg); });\n }\n\n _resetSize() {\n const img = this._activeImg;\n if (!img) return;\n img.style.width = '';\n img.style.height = '';\n this.context.invoke('editor.afterCommand');\n this.context.invoke('imageResizer.updateOverlay');\n requestAnimationFrame(() => { if (this._activeImg) this._positionNear(this._activeImg); });\n }\n\n /**\n * Rotate the active image by `delta` degrees (±90).\n * Reads the existing rotate() value from the transform style so\n * repeated clicks accumulate correctly.\n * @param {number} delta\n */\n _rotate(delta) {\n const img = this._activeImg;\n if (!img) return;\n // Parse current rotation angle from inline transform\n const current = img.style.transform || '';\n const match = current.match(/rotate\\((-?[\\d.]+)deg\\)/);\n const prev = match ? parseFloat(match[1]) : 0;\n const next = (prev + delta + 360) % 360; // normalise to [0, 360)\n // Preserve any other transform functions (e.g. scale), replace only rotate()\n const cleaned = current.replace(/rotate\\(-?[\\d.]+deg\\)/, '').trim();\n img.style.transform = cleaned\n ? `${cleaned} rotate(${next}deg)`\n : next === 0 ? '' : `rotate(${next}deg)`;\n this.context.invoke('editor.afterCommand');\n this.context.invoke('imageResizer.updateOverlay');\n requestAnimationFrame(() => { if (this._activeImg) this._positionNear(this._activeImg); });\n }\n\n _delete() {\n const img = this._activeImg;\n if (!img) return;\n this._hide();\n this.context.invoke('imageResizer.deselect');\n const figure = img.closest('figure.an-figure');\n if (figure && figure.parentNode) {\n figure.parentNode.removeChild(figure);\n } else if (img.parentNode) {\n img.parentNode.removeChild(img);\n }\n this.context.invoke('editor.afterCommand');\n }\n\n _toggleCaption() {\n const img = this._activeImg;\n if (!img) return;\n\n // If already inside a figure, move focus to the figcaption\n const existing = img.closest('figure.an-figure');\n if (existing) {\n const cap = existing.querySelector('figcaption.an-figcaption');\n if (cap) {\n this._hide();\n const range = document.createRange();\n range.selectNodeContents(cap);\n const sel = window.getSelection();\n if (sel) { sel.removeAllRanges(); sel.addRange(range); }\n }\n return;\n }\n\n // Wrap image in <figure><figcaption>\n const figure = document.createElement('figure');\n figure.className = 'an-figure';\n\n // Transfer existing alignment from <img> to <figure> (C4 fix)\n if (img.style.float) {\n figure.style.float = img.style.float;\n figure.style.marginLeft = img.style.marginLeft;\n figure.style.marginRight = img.style.marginRight;\n img.style.float = '';\n img.style.marginLeft = '';\n img.style.marginRight = '';\n } else if (img.style.display === 'block' && img.style.marginLeft === 'auto') {\n figure.style.display = 'block';\n figure.style.marginLeft = 'auto';\n figure.style.marginRight = 'auto';\n img.style.display = '';\n img.style.marginLeft = '';\n img.style.marginRight = '';\n }\n const figcaption = document.createElement('figcaption');\n figcaption.className = 'an-figcaption';\n figcaption.textContent = 'Caption';\n\n img.parentNode.insertBefore(figure, img);\n figure.appendChild(img);\n figure.appendChild(figcaption);\n\n // Select caption text immediately\n const range = document.createRange();\n range.selectNodeContents(figcaption);\n const sel = window.getSelection();\n if (sel) { sel.removeAllRanges(); sel.addRange(range); }\n\n this.context.invoke('editor.afterCommand');\n // Re-sync the resize overlay: wrapping img in <figure> changes its layout position.\n this.context.invoke('imageResizer.updateOverlay');\n this._hide();\n }\n}\n","// VideoTooltip.js - Hover tooltip for video wrappers inside the editor\n// Displays a horizontal action bar below (or above) the selected video,\n// similar in appearance and interaction to LinkTooltip.\nimport { createElement, on } from '../core/dom.js';\n\nconst ICONS = {\n floatLeft: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"2\" y=\"4\" width=\"8\" height=\"8\" rx=\"1\"/><line x1=\"12\" y1=\"6\" x2=\"22\" y2=\"6\"/><line x1=\"12\" y1=\"9\" x2=\"22\" y2=\"9\"/><line x1=\"12\" y1=\"12\" x2=\"22\" y2=\"12\"/><line x1=\"2\" y1=\"16\" x2=\"22\" y2=\"16\"/><line x1=\"2\" y1=\"20\" x2=\"18\" y2=\"20\"/></svg>`,\n floatRight: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"14\" y=\"4\" width=\"8\" height=\"8\" rx=\"1\"/><line x1=\"2\" y1=\"6\" x2=\"12\" y2=\"6\"/><line x1=\"2\" y1=\"9\" x2=\"12\" y2=\"9\"/><line x1=\"2\" y1=\"12\" x2=\"12\" y2=\"12\"/><line x1=\"2\" y1=\"16\" x2=\"22\" y2=\"16\"/><line x1=\"2\" y1=\"20\" x2=\"18\" y2=\"20\"/></svg>`,\n floatNone: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"3\" width=\"8\" height=\"8\" rx=\"1\"/><line x1=\"3\" y1=\"15\" x2=\"21\" y2=\"15\"/><line x1=\"3\" y1=\"19\" x2=\"17\" y2=\"19\"/></svg>`,\n alignCenter: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"7\" y=\"4\" width=\"10\" height=\"8\" rx=\"1\"/><line x1=\"3\" y1=\"16\" x2=\"21\" y2=\"16\"/><line x1=\"6\" y1=\"20\" x2=\"18\" y2=\"20\"/></svg>`,\n originalSize:`<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"15 3 21 3 21 9\"/><polyline points=\"9 21 3 21 3 15\"/><line x1=\"21\" y1=\"3\" x2=\"14\" y2=\"10\"/><line x1=\"3\" y1=\"21\" x2=\"10\" y2=\"14\"/></svg>`,\n deleteVideo: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"3 6 5 6 21 6\"/><path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2\"/></svg>`,\n preview: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polygon points=\"5 3 19 12 5 21 5 3\"/></svg>`,\n};\n\nconst SHOW_DELAY = 100;\nconst HIDE_DELAY = 180;\n\nexport class VideoTooltip {\n /** @param {import('../Context.js').Context} context */\n constructor(context) {\n this.context = context;\n this._el = null;\n this._activeWrapper = null;\n this._showTimer = null;\n this._hideTimer = null;\n this._disposers = [];\n this._previewMode = false;\n this._previewClickOff = null;\n }\n\n initialize() {\n this._el = this._buildTooltip();\n document.body.appendChild(this._el);\n\n const editable = this.context.layoutInfo.editable;\n\n this._disposers.push(\n on(editable, 'mouseover', (e) => {\n // The shield div sits on top of iframes — we detect hover via it or the wrapper\n const wrapper = e.target.closest('.an-video-wrapper');\n if (wrapper && editable.contains(wrapper)) {\n this._scheduleShow(wrapper);\n }\n }, { passive: true }),\n on(editable, 'mouseout', (e) => {\n const to = e.relatedTarget;\n if (!to || (!editable.contains(to) && !this._el.contains(to))) {\n this._scheduleHide();\n }\n }, { passive: true }),\n on(document, 'click', (e) => {\n if (\n this._activeWrapper &&\n !this._activeWrapper.contains(e.target) &&\n !this._el.contains(e.target)\n ) {\n this._hide();\n }\n }),\n );\n\n return this;\n }\n\n destroy() {\n if (this._previewMode) this._exitPreview();\n this._clearTimers();\n this._disposers.forEach((d) => d());\n this._disposers = [];\n if (this._el && this._el.parentNode) this._el.parentNode.removeChild(this._el);\n this._el = null;\n }\n\n // ---------------------------------------------------------------------------\n // Build\n // ---------------------------------------------------------------------------\n\n _buildTooltip() {\n const el = createElement('div', {\n class: 'an-link-tooltip an-video-tooltip',\n role: 'toolbar',\n 'aria-label': 'Video actions',\n });\n el.style.display = 'none';\n\n // Label\n this._label = createElement('span', { class: 'an-link-tooltip-url' });\n this._label.textContent = 'Video';\n el.appendChild(this._label);\n\n el.appendChild(createElement('div', { class: 'an-link-tooltip-sep' }));\n\n this._floatLeftBtn = this._makeBtn(ICONS.floatLeft, 'Float Left', () => this._setFloat('left'));\n this._floatNoneBtn = this._makeBtn(ICONS.floatNone, 'No Float', () => this._setFloat(''));\n this._alignCenterBtn = this._makeBtn(ICONS.alignCenter, 'Align Center', () => this._setCenter());\n this._floatRightBtn = this._makeBtn(ICONS.floatRight, 'Float Right', () => this._setFloat('right'));\n\n el.appendChild(this._floatLeftBtn);\n el.appendChild(this._floatNoneBtn);\n el.appendChild(this._alignCenterBtn);\n el.appendChild(this._floatRightBtn);\n\n el.appendChild(createElement('div', { class: 'an-link-tooltip-sep' }));\n\n this._originalBtn = this._makeBtn(ICONS.originalSize, 'Original Size', () => this._resetSize());\n\n el.appendChild(this._originalBtn);\n\n el.appendChild(createElement('div', { class: 'an-link-tooltip-sep' }));\n\n this._previewBtn = this._makeBtn(ICONS.preview, 'Preview Video', () => this._togglePreview());\n el.appendChild(this._previewBtn);\n\n el.appendChild(createElement('div', { class: 'an-link-tooltip-sep' }));\n\n this._deleteBtn = this._makeBtn(ICONS.deleteVideo, 'Delete Video', () => this._delete(), true);\n\n el.appendChild(this._deleteBtn);\n\n // Keep tooltip alive while hovering it\n this._disposers.push(\n on(el, 'mouseenter', () => this._clearTimers()),\n on(el, 'mouseleave', () => this._scheduleHide()),\n );\n\n return el;\n }\n\n /**\n * @param {string} icon\n * @param {string} title\n * @param {Function} handler\n * @param {boolean} [isDanger]\n */\n _makeBtn(icon, title, handler, isDanger = false) {\n const btn = createElement('button', {\n type: 'button',\n class: isDanger ? 'an-link-tooltip-btn an-link-tooltip-btn--danger' : 'an-link-tooltip-btn',\n title,\n });\n btn.innerHTML = icon;\n this._disposers.push(on(btn, 'click', (e) => {\n e.preventDefault();\n e.stopPropagation();\n handler();\n }));\n return btn;\n }\n\n // ---------------------------------------------------------------------------\n // Show / Hide\n // ---------------------------------------------------------------------------\n\n _scheduleShow(wrapper) {\n if (this._activeWrapper === wrapper && this._el.style.display !== 'none') return;\n clearTimeout(this._hideTimer);\n this._hideTimer = null;\n clearTimeout(this._showTimer);\n this._showTimer = setTimeout(() => {\n this._activeWrapper = wrapper;\n this._show(wrapper);\n }, SHOW_DELAY);\n }\n\n _scheduleHide() {\n // Keep tooltip alive while preview mode is active\n if (this._previewMode) return;\n clearTimeout(this._showTimer);\n this._showTimer = null;\n if (this._hideTimer) return;\n this._hideTimer = setTimeout(() => this._hide(), HIDE_DELAY);\n }\n\n _show(wrapper) {\n this._el.style.display = 'flex';\n // Defer: offsetWidth on a newly-visible element forces synchronous layout\n requestAnimationFrame(() => {\n if (this._activeWrapper) this._positionNear(this._activeWrapper);\n });\n }\n\n _hide() {\n if (this._previewMode) this._exitPreview();\n this._el.style.display = 'none';\n this._activeWrapper = null;\n this._clearTimers();\n }\n\n _clearTimers() {\n clearTimeout(this._showTimer);\n clearTimeout(this._hideTimer);\n this._showTimer = null;\n this._hideTimer = null;\n }\n\n _positionNear(wrapper) {\n const rect = wrapper.getBoundingClientRect();\n const tipW = this._el.offsetWidth || 220;\n const tipH = this._el.offsetHeight || 32;\n const margin = 6;\n\n let top = rect.bottom + margin;\n let left = rect.left + (rect.width - tipW) / 2;\n\n if (top + tipH > window.innerHeight - margin) top = rect.top - tipH - margin;\n if (left + tipW > window.innerWidth - margin) left = window.innerWidth - tipW - margin;\n if (left < margin) left = margin;\n\n this._el.style.top = `${top}px`;\n this._el.style.left = `${left}px`;\n }\n\n // ---------------------------------------------------------------------------\n // Actions\n // ---------------------------------------------------------------------------\n\n _setFloat(value) {\n const wrapper = this._activeWrapper;\n if (!wrapper) return;\n wrapper.style.float = value;\n wrapper.style.display = value ? 'inline-block' : '';\n wrapper.style.marginLeft = value === 'right' ? '12px' : '';\n wrapper.style.marginRight = value === 'left' ? '12px' : '';\n this.context.invoke('editor.afterCommand');\n this.context.invoke('videoResizer.updateOverlay');\n requestAnimationFrame(() => { if (this._activeWrapper) this._positionNear(this._activeWrapper); });\n }\n\n _setCenter() {\n const wrapper = this._activeWrapper;\n if (!wrapper) return;\n wrapper.style.float = '';\n wrapper.style.display = 'block';\n wrapper.style.marginLeft = 'auto';\n wrapper.style.marginRight = 'auto';\n this.context.invoke('editor.afterCommand');\n this.context.invoke('videoResizer.updateOverlay');\n requestAnimationFrame(() => { if (this._activeWrapper) this._positionNear(this._activeWrapper); });\n }\n\n _resetSize() {\n const wrapper = this._activeWrapper;\n if (!wrapper) return;\n const embed = wrapper.querySelector('iframe, video');\n wrapper.style.width = '';\n wrapper.style.height = '';\n if (embed) {\n embed.removeAttribute('width');\n embed.removeAttribute('height');\n embed.style.width = '';\n embed.style.height = '';\n }\n this.context.invoke('editor.afterCommand');\n this.context.invoke('videoResizer.updateOverlay');\n requestAnimationFrame(() => { if (this._activeWrapper) this._positionNear(this._activeWrapper); });\n }\n\n _delete() {\n const wrapper = this._activeWrapper;\n if (!wrapper) return;\n this._hide();\n this.context.invoke('videoResizer.deselect');\n if (wrapper.parentNode) wrapper.parentNode.removeChild(wrapper);\n this.context.invoke('editor.afterCommand');\n }\n\n // ---------------------------------------------------------------------------\n // Preview mode — temporarily disables the shield so the video is interactive\n // ---------------------------------------------------------------------------\n\n _togglePreview() {\n if (this._previewMode) {\n this._exitPreview();\n } else {\n this._enterPreview();\n }\n }\n\n _enterPreview() {\n const wrapper = this._activeWrapper;\n if (!wrapper) return;\n this._previewMode = true;\n\n // Hide the shield so the iframe / video receives pointer events directly\n const shield = wrapper.querySelector('.an-video-shield');\n if (shield) shield.style.display = 'none';\n\n // Hide the resize overlay — it would block interaction with the embed\n this.context.invoke('videoResizer.deselect');\n\n // Visual feedback: button turns primary-coloured\n this._previewBtn.classList.add('an-link-tooltip-btn--copied');\n this._previewBtn.title = 'Exit Preview';\n\n // Exit preview on mousedown outside the wrapper.\n // Using 'mousedown' (not 'click') so clicks inside an iframe\n // — which never bubble to the outer document — don't accidentally\n // leave preview mode stuck. For <video> elements, mousedown on the\n // video is inside the wrapper so contains() returns true → no exit.\n this._previewClickOff = (e) => {\n if (!wrapper.contains(e.target) && !this._el.contains(e.target)) {\n this._exitPreview();\n }\n };\n document.addEventListener('mousedown', this._previewClickOff, true);\n }\n\n _exitPreview() {\n this._previewMode = false;\n\n const wrapper = this._activeWrapper;\n if (wrapper) {\n // Restore the shield\n const shield = wrapper.querySelector('.an-video-shield');\n if (shield) shield.style.display = '';\n }\n\n // Reset button appearance\n this._previewBtn.classList.remove('an-link-tooltip-btn--copied');\n this._previewBtn.title = 'Preview Video';\n\n if (this._previewClickOff) {\n document.removeEventListener('mousedown', this._previewClickOff, true);\n this._previewClickOff = null;\n }\n }\n}\n","// TableTooltip.js - Hover tooltip for tables inside the editor\n// Shows a horizontal action bar above (or below) the hovered table,\n// similar in appearance and interaction to ImageTooltip / VideoTooltip.\nimport { createElement, on } from '../core/dom.js';\n\nconst SHOW_DELAY = 120;\nconst HIDE_DELAY = 200;\n\n// ---------------------------------------------------------------------------\n// Table helpers — visual column index (accounts for colspan)\n// ---------------------------------------------------------------------------\n\n/**\n * Returns the visual (logical) column index of a cell, taking colspan into\n * account for all preceding cells in the same row.\n * @param {HTMLTableCellElement} cell\n * @returns {number} 0-based visual column index, or -1 on failure\n */\nfunction getVisualColIndex(cell) {\n const row = cell.closest('tr');\n if (!row) return -1;\n let visualIdx = 0;\n for (const c of row.cells) {\n if (c === cell) return visualIdx;\n visualIdx += c.colSpan || 1;\n }\n return -1;\n}\n\n/**\n * Finds the first cell in a row whose visual start column equals visualIdx.\n * Returns null if no exact match (e.g. the column is spanned by a merged cell).\n * @param {HTMLTableRowElement} row\n * @param {number} visualIdx\n * @returns {HTMLTableCellElement|null}\n */\nfunction getCellAtVisualCol(row, visualIdx) {\n let vIdx = 0;\n for (const c of row.cells) {\n if (vIdx === visualIdx) return c;\n if (vIdx > visualIdx) break;\n vIdx += c.colSpan || 1;\n }\n return null;\n}\n\n/**\n * Finds the first cell whose visual range ends after visualIdx\n * (used for inserting a new column to the right of visualIdx).\n * @param {HTMLTableRowElement} row\n * @param {number} visualIdx\n * @returns {HTMLTableCellElement|null} reference cell for insertBefore, or null = append\n */\nfunction getCellAfterVisualCol(row, visualIdx) {\n let vIdx = 0;\n for (const c of row.cells) {\n vIdx += c.colSpan || 1;\n if (vIdx > visualIdx) {\n // next cell after the one that starts at / spans visualIdx\n const next = c.nextElementSibling;\n return (next && next.tagName === 'TD' || next && next.tagName === 'TH') ? next : null;\n }\n }\n return null;\n}\n\nconst ICONS = {\n rowAbove: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"1\"/><line x1=\"3\" y1=\"12\" x2=\"21\" y2=\"12\"/><path d=\"M12 3v7\"/><path d=\"M9 7l3-4 3 4\"/></svg>`,\n rowBelow: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"1\"/><line x1=\"3\" y1=\"12\" x2=\"21\" y2=\"12\"/><path d=\"M12 12v7\"/><path d=\"M9 17l3 4 3-4\"/></svg>`,\n deleteRow: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"1\"/><line x1=\"3\" y1=\"12\" x2=\"21\" y2=\"12\"/><line x1=\"15\" y1=\"15\" x2=\"21\" y2=\"21\"/><line x1=\"21\" y1=\"15\" x2=\"15\" y2=\"21\"/></svg>`,\n colLeft: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"1\"/><line x1=\"12\" y1=\"3\" x2=\"12\" y2=\"21\"/><path d=\"M3 12h7\"/><path d=\"M7 8l-4 4 4 4\"/></svg>`,\n colRight: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"1\"/><line x1=\"12\" y1=\"3\" x2=\"12\" y2=\"21\"/><path d=\"M12 12h9\"/><path d=\"M17 8l4 4-4 4\"/></svg>`,\n deleteCol: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"1\"/><line x1=\"12\" y1=\"3\" x2=\"12\" y2=\"21\"/><line x1=\"15\" y1=\"6\" x2=\"21\" y2=\"12\"/><line x1=\"21\" y1=\"6\" x2=\"15\" y2=\"12\"/></svg>`,\n mergeCells: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"2\" y=\"7\" width=\"8\" height=\"10\" rx=\"1\"/><rect x=\"14\" y=\"7\" width=\"8\" height=\"10\" rx=\"1\"/><path d=\"M10 12h4\"/><path d=\"M12 10l2 2-2 2\"/></svg>`,\n colWidth: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"7\" y1=\"4\" x2=\"7\" y2=\"20\"/><line x1=\"17\" y1=\"4\" x2=\"17\" y2=\"20\"/><line x1=\"7\" y1=\"12\" x2=\"17\" y2=\"12\"/><path d=\"M10 9l-3 3 3 3\"/><path d=\"M14 9l3 3-3 3\"/></svg>`,\n rowHeight: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"4\" y1=\"7\" x2=\"20\" y2=\"7\"/><line x1=\"4\" y1=\"17\" x2=\"20\" y2=\"17\"/><line x1=\"12\" y1=\"7\" x2=\"12\" y2=\"17\"/><path d=\"M9 10l3-3 3 3\"/><path d=\"M9 14l3 3 3-3\"/></svg>`,\n deleteTable: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"1\"/><line x1=\"3\" y1=\"9\" x2=\"21\" y2=\"9\"/><line x1=\"3\" y1=\"15\" x2=\"21\" y2=\"15\"/><line x1=\"9\" y1=\"3\" x2=\"9\" y2=\"21\"/><line x1=\"15\" y1=\"3\" x2=\"15\" y2=\"21\"/><line x1=\"16\" y1=\"16\" x2=\"22\" y2=\"22\" stroke=\"#ef4444\"/><line x1=\"22\" y1=\"16\" x2=\"16\" y2=\"22\" stroke=\"#ef4444\"/></svg>`,\n};\n\nexport class TableTooltip {\n /** @param {import('../Context.js').Context} context */\n constructor(context) {\n this.context = context;\n this._el = null;\n this._activeTable = null;\n this._activeCell = null; // last hovered td/th\n this._showTimer = null;\n this._hideTimer = null;\n this._disposers = [];\n this._sizePopover = null;\n this._sizeApply = null;\n this._sizeTitleEl = null;\n this._sizeInputEl = null;\n }\n\n initialize() {\n this._el = this._buildTooltip();\n document.body.appendChild(this._el);\n\n this._sizePopover = this._buildSizePopover();\n document.body.appendChild(this._sizePopover);\n\n const editable = this.context.layoutInfo.editable;\n\n this._disposers.push(\n on(editable, 'mouseover', (e) => {\n const table = e.target.closest('table');\n if (table && editable.contains(table)) {\n const cell = e.target.closest('td, th');\n if (cell) this._activeCell = cell;\n this._scheduleShow(table);\n }\n }, { passive: true }),\n on(editable, 'mouseout', (e) => {\n const to = e.relatedTarget;\n if (!to || (\n !editable.contains(to) &&\n !this._el.contains(to) &&\n !(this._sizePopover && this._sizePopover.contains(to))\n )) {\n this._scheduleHide();\n }\n }, { passive: true }),\n on(document, 'click', (e) => {\n if (this._activeTable &&\n !this._activeTable.contains(e.target) &&\n !this._el.contains(e.target) &&\n !(this._sizePopover && this._sizePopover.contains(e.target))) {\n this._hide();\n }\n }),\n );\n\n this._initResize();\n return this;\n }\n\n // ---------------------------------------------------------------------------\n // Column & row drag-resize\n // ---------------------------------------------------------------------------\n\n _initResize() {\n const editable = this.context.layoutInfo.editable;\n const HIT = 6; // px proximity threshold\n\n // Shared hover state\n let _nearCell = null;\n let _nearEdge = null; // 'col' | 'row' | null\n\n // Active drag state\n let _resizing = false;\n let _edge = null; // 'col' | 'row'\n let _startX = 0;\n let _startY = 0;\n let _startW = 0;\n let _startH = 0;\n let _colIdx = -1;\n let _colCells = null; // cells cached at drag-start — avoids querySelectorAll every frame\n let _row = null;\n let _table = null;\n let _rafDocMove = null; // pending rAF handle for resize drag\n let _rafEditorMove = null; // pending rAF handle for cursor detection\n\n const clearHover = () => {\n if (_nearCell) { _nearCell.style.cursor = ''; _nearCell = null; }\n _nearEdge = null;\n };\n\n const onEditorMove = (e) => {\n if (_resizing) return;\n // Throttle to one check per animation frame — getBoundingClientRect forces reflow\n if (_rafEditorMove !== null) return;\n const target = e.target;\n const clientX = e.clientX;\n const clientY = e.clientY;\n _rafEditorMove = requestAnimationFrame(() => {\n _rafEditorMove = null;\n const cell = target.closest('td, th');\n if (!cell || !editable.contains(cell)) { clearHover(); return; }\n if (_nearCell && _nearCell !== cell) _nearCell.style.cursor = '';\n const rect = cell.getBoundingClientRect();\n const onRight = Math.abs(clientX - rect.right) < HIT;\n const onBottom = Math.abs(clientY - rect.bottom) < HIT;\n if (onRight) {\n cell.style.cursor = 'col-resize';\n _nearCell = cell; _nearEdge = 'col';\n } else if (onBottom) {\n cell.style.cursor = 'row-resize';\n _nearCell = cell; _nearEdge = 'row';\n } else {\n clearHover();\n }\n });\n };\n\n const onEditorDown = (e) => {\n if (!_nearCell || !_nearEdge) return;\n _resizing = true;\n _edge = _nearEdge;\n _startX = e.clientX;\n _startY = e.clientY;\n _table = _nearCell.closest('table');\n if (_edge === 'col') {\n _startW = _nearCell.offsetWidth;\n _colIdx = getVisualColIndex(_nearCell);\n // Cache column cells once so onDocMove never runs querySelectorAll per frame\n _colCells = _colIdx >= 0\n ? Array.from(_table.querySelectorAll('tr'))\n .map(r => getCellAtVisualCol(r, _colIdx))\n .filter(Boolean)\n : [];\n document.body.style.cursor = 'col-resize';\n } else {\n _row = _nearCell.closest('tr');\n _startH = _row ? _row.offsetHeight : 40;\n document.body.style.cursor = 'row-resize';\n }\n document.body.style.userSelect = 'none';\n e.preventDefault();\n e.stopPropagation();\n };\n\n const onDocMove = (e) => {\n if (!_resizing) return;\n // Skip if a frame is already scheduled — avoids per-pixel style thrashing\n if (_rafDocMove !== null) return;\n const clientX = e.clientX;\n const clientY = e.clientY;\n _rafDocMove = requestAnimationFrame(() => {\n _rafDocMove = null;\n if (_edge === 'col') {\n const newW = Math.max(30, _startW + (clientX - _startX));\n for (const c of _colCells) {\n c.style.width = `${newW}px`;\n c.style.minWidth = `${newW}px`;\n }\n } else {\n const newH = Math.max(20, _startH + (clientY - _startY));\n if (_row) {\n for (const c of _row.cells) {\n c.style.height = `${newH}px`;\n c.style.minHeight = `${newH}px`;\n }\n }\n }\n });\n };\n\n const onDocUp = () => {\n if (!_resizing) return;\n // Cancel any in-flight rAF so stale writes don't land after mouseup\n if (_rafDocMove !== null) { cancelAnimationFrame(_rafDocMove); _rafDocMove = null; }\n _resizing = false;\n document.body.style.userSelect = '';\n document.body.style.cursor = '';\n _edge = null;\n _table = null;\n _row = null;\n _colIdx = -1;\n _colCells = null;\n this.context.invoke('editor.afterCommand');\n };\n\n this._disposers.push(\n on(editable, 'mousemove', onEditorMove),\n on(editable, 'mousedown', onEditorDown),\n on(document, 'mousemove', onDocMove),\n on(document, 'mouseup', onDocUp),\n );\n }\n\n destroy() {\n this._clearTimers();\n this._disposers.forEach((d) => d());\n this._disposers = [];\n if (this._el && this._el.parentNode) this._el.parentNode.removeChild(this._el);\n this._el = null;\n if (this._sizePopover && this._sizePopover.parentNode) {\n this._sizePopover.parentNode.removeChild(this._sizePopover);\n }\n this._sizePopover = null;\n }\n\n // ---------------------------------------------------------------------------\n // Build tooltip bar\n // ---------------------------------------------------------------------------\n\n _buildTooltip() {\n const el = createElement('div', {\n class: 'an-link-tooltip an-table-tooltip',\n role: 'toolbar',\n 'aria-label': 'Table actions',\n });\n el.style.display = 'none';\n\n // Label\n this._label = createElement('span', { class: 'an-link-tooltip-url' });\n this._label.textContent = 'Table';\n el.appendChild(this._label);\n\n el.appendChild(this._sep());\n\n // Row operations\n el.appendChild(this._makeBtn(ICONS.rowAbove, 'Add Row Above', () => this._addRow('above')));\n el.appendChild(this._makeBtn(ICONS.rowBelow, 'Add Row Below', () => this._addRow('below')));\n el.appendChild(this._makeBtn(ICONS.deleteRow, 'Delete Row', () => this._deleteRow()));\n\n el.appendChild(this._sep());\n\n // Column operations\n el.appendChild(this._makeBtn(ICONS.colLeft, 'Add Column Left', () => this._addColumn('left')));\n el.appendChild(this._makeBtn(ICONS.colRight, 'Add Column Right', () => this._addColumn('right')));\n el.appendChild(this._makeBtn(ICONS.deleteCol, 'Delete Column', () => this._deleteColumn()));\n\n el.appendChild(this._sep());\n\n // Merge cells\n el.appendChild(this._makeBtn(ICONS.mergeCells, 'Merge Cells', () => this._mergeCells()));\n\n el.appendChild(this._sep());\n\n // Resize\n el.appendChild(this._makeBtn(ICONS.colWidth, 'Column Width', () => this._openSizePopover('col')));\n el.appendChild(this._makeBtn(ICONS.rowHeight, 'Row Height', () => this._openSizePopover('row')));\n\n el.appendChild(this._sep());\n\n // Delete table (danger)\n el.appendChild(this._makeBtn(ICONS.deleteTable, 'Delete Table', () => this._deleteTable(), true));\n\n // Keep tooltip alive while hovering.\n // Don't schedule hide on mouseleave when the size popover is open —\n // the user is moving the mouse toward it.\n this._disposers.push(\n on(el, 'mouseenter', () => this._clearTimers()),\n on(el, 'mouseleave', () => {\n if (this._sizePopover && this._sizePopover.style.display !== 'none') return;\n this._scheduleHide();\n }),\n );\n\n return el;\n }\n\n _sep() {\n return createElement('div', { class: 'an-link-tooltip-sep' });\n }\n\n /**\n * @param {string} icon\n * @param {string} title\n * @param {Function} handler\n * @param {boolean} [isDanger]\n */\n _makeBtn(icon, title, handler, isDanger = false) {\n const btn = createElement('button', {\n type: 'button',\n class: isDanger\n ? 'an-link-tooltip-btn an-link-tooltip-btn--danger'\n : 'an-link-tooltip-btn',\n title,\n });\n btn.innerHTML = icon;\n this._disposers.push(on(btn, 'click', (e) => {\n e.preventDefault();\n e.stopPropagation();\n handler();\n }));\n return btn;\n }\n\n // ---------------------------------------------------------------------------\n // Show / Hide\n // ---------------------------------------------------------------------------\n\n _scheduleShow(table) {\n if (this._activeTable === table && this._el.style.display !== 'none') return;\n clearTimeout(this._hideTimer);\n this._hideTimer = null;\n clearTimeout(this._showTimer);\n this._showTimer = setTimeout(() => {\n this._activeTable = table;\n this._show();\n }, SHOW_DELAY);\n }\n\n _scheduleHide() {\n clearTimeout(this._showTimer);\n this._showTimer = null;\n if (this._hideTimer) return;\n this._hideTimer = setTimeout(() => this._hide(), HIDE_DELAY);\n }\n\n _show() {\n if (!this._activeTable) return;\n this._el.style.display = 'flex';\n // Defer: offsetWidth on a newly-visible element forces layout synchronously\n requestAnimationFrame(() => {\n if (this._activeTable) this._positionNear(this._activeTable);\n });\n }\n\n _hide() {\n this._el.style.display = 'none';\n this._activeTable = null;\n this._activeCell = null;\n this._clearTimers();\n this._hideSizePopover();\n }\n\n _clearTimers() {\n clearTimeout(this._showTimer);\n clearTimeout(this._hideTimer);\n this._showTimer = null;\n this._hideTimer = null;\n }\n\n _positionNear(table) {\n if (!table) return;\n const rect = table.getBoundingClientRect();\n const tipW = this._el.offsetWidth || 400;\n const tipH = this._el.offsetHeight || 30;\n const margin = 6;\n\n // Center horizontally over the table; prefer above it\n let left = rect.left + (rect.width - tipW) / 2;\n let top = rect.top - tipH - margin;\n\n if (top < margin) top = rect.bottom + margin;\n if (left + tipW > window.innerWidth - margin) left = window.innerWidth - tipW - margin;\n if (left < margin) left = margin;\n\n this._el.style.left = `${left}px`;\n this._el.style.top = `${top}px`;\n }\n\n // ---------------------------------------------------------------------------\n // Helper: get active cell (fallback to first td/th in table)\n // ---------------------------------------------------------------------------\n\n _getCell() {\n // Prefer the cell under the current text cursor (most intuitive for operations)\n const sel = window.getSelection();\n if (sel && sel.rangeCount) {\n let container = sel.getRangeAt(0).commonAncestorContainer;\n if (container.nodeType === 3) container = container.parentElement;\n const cellFromSel = container && container.closest && container.closest('td, th');\n if (cellFromSel && this._activeTable && this._activeTable.contains(cellFromSel)) {\n return cellFromSel;\n }\n }\n return this._activeCell\n || (this._activeTable && this._activeTable.querySelector('td, th'));\n }\n\n // ---------------------------------------------------------------------------\n // Table operations\n // ---------------------------------------------------------------------------\n\n _addRow(position) {\n const cell = this._getCell();\n if (!cell) return;\n const row = cell.closest('tr');\n if (!row) return;\n const colCount = Array.from(row.cells).reduce((sum, c) => sum + (c.colSpan || 1), 0);\n const newRow = document.createElement('tr');\n const refCells = Array.from(row.cells);\n for (let i = 0; i < colCount; i++) {\n const td = createElement('td', {}, ['\\u00a0']);\n const ref = refCells[i];\n if (ref && ref.style.width) td.style.width = ref.style.width;\n if (ref && ref.style.minWidth) td.style.minWidth = ref.style.minWidth;\n newRow.appendChild(td);\n }\n if (position === 'above') row.parentElement?.insertBefore(newRow, row);\n else row.insertAdjacentElement('afterend', newRow);\n // Defer positioning until the browser has painted the new layout\n requestAnimationFrame(() => this._positionNear(this._activeTable));\n this.context.invoke('editor.afterCommand');\n }\n\n _addColumn(position) {\n const cell = this._getCell();\n if (!cell) return;\n const table = cell.closest('table');\n if (!table) return;\n const visualColIdx = getVisualColIndex(cell);\n const rows = Array.from(table.querySelectorAll('tr'));\n // Batch reads first, then writes — prevents layout thrashing inside the loop\n const refs = rows.map(r => position === 'left'\n ? getCellAtVisualCol(r, visualColIdx)\n : getCellAfterVisualCol(r, visualColIdx));\n const isHeaders = rows.map(r => r.closest('thead') !== null);\n rows.forEach((r, i) => {\n r.insertBefore(createElement(isHeaders[i] ? 'th' : 'td', {}, ['\\u00a0']), refs[i]);\n });\n requestAnimationFrame(() => this._positionNear(this._activeTable));\n this.context.invoke('editor.afterCommand');\n }\n\n _deleteRow() {\n const cell = this._getCell();\n if (!cell) return;\n const row = cell.closest('tr');\n const table = cell.closest('table');\n if (!row || !table) return;\n // Guard: do not delete the last body row (thead rows are not counted)\n const tbody = table.querySelector('tbody');\n const bodyRows = tbody ? tbody.querySelectorAll('tr').length : table.querySelectorAll('tr').length;\n if (bodyRows <= 1 && row.closest('tbody')) return;\n this._activeCell = null;\n row.parentElement?.removeChild(row);\n requestAnimationFrame(() => this._positionNear(this._activeTable));\n this.context.invoke('editor.afterCommand');\n }\n\n _deleteColumn() {\n const cell = this._getCell();\n if (!cell) return;\n const table = cell.closest('table');\n if (!table) return;\n const row = cell.closest('tr');\n if (row && row.cells.length <= 1) return;\n const visualColIdx = getVisualColIndex(cell);\n this._activeCell = null;\n const rows = Array.from(table.querySelectorAll('tr'));\n // Batch reads before writes to avoid forced reflows inside the loop\n const cells = rows.map(r => getCellAtVisualCol(r, visualColIdx));\n cells.forEach((c, i) => { if (c) rows[i].removeChild(c); });\n requestAnimationFrame(() => this._positionNear(this._activeTable));\n this.context.invoke('editor.afterCommand');\n }\n\n _mergeCells() {\n const cell = this._getCell();\n if (!cell) return;\n const sel = window.getSelection();\n if (!sel || sel.rangeCount === 0) return;\n const range = sel.getRangeAt(0);\n const table = cell.closest('table');\n if (!table) return;\n\n // Collect all cells (in any row) that intersect the selection\n const allCells = Array.from(table.querySelectorAll('td, th'));\n const selected = allCells.filter((c) => {\n try { return range.intersectsNode(c); } catch { return false; }\n });\n if (selected.length < 2) return;\n\n // Determine if all selected cells are in the same row (horizontal merge)\n const rows = [...new Set(selected.map((c) => c.closest('tr')))];\n if (rows.length === 1) {\n // Horizontal merge within a single row\n const row = rows[0];\n const rowSelected = Array.from(row.cells).filter((c) => selected.includes(c));\n if (rowSelected.length < 2) return;\n const first = rowSelected[0];\n first.colSpan = rowSelected.reduce((sum, c) => sum + (c.colSpan || 1), 0);\n first.innerHTML = rowSelected.map((c) => c.innerHTML).join('');\n rowSelected.slice(1).forEach((c) => row.removeChild(c));\n } else {\n // Vertical merge across rows — merge into first selected cell (rowspan)\n const visualCols = [...new Set(selected.map((c) => getVisualColIndex(c)))];\n if (visualCols.length !== 1) return; // only support single-column vertical merge\n const first = selected[0];\n first.rowSpan = selected.reduce((sum, c) => sum + (c.rowSpan || 1), 0);\n first.innerHTML = selected.map((c) => c.innerHTML).join('');\n selected.slice(1).forEach((c) => {\n if (c.closest('tr')) c.closest('tr').removeChild(c);\n });\n }\n this.context.invoke('editor.afterCommand');\n }\n\n _deleteTable() {\n const table = this._activeTable;\n if (!table) return;\n this._hide();\n if (table.parentNode) table.parentNode.removeChild(table);\n this.context.invoke('editor.afterCommand');\n }\n\n // ---------------------------------------------------------------------------\n // Size popover (column width / row height)\n // ---------------------------------------------------------------------------\n\n _buildSizePopover() {\n const popover = createElement('div', { class: 'an-size-popover' });\n popover.style.display = 'none';\n\n const titleEl = createElement('div', { class: 'an-size-popover-title' });\n const body = createElement('div', { class: 'an-size-popover-body' });\n const inputEl = createElement('input', {\n type: 'number', class: 'an-size-input', min: '1', max: '2000', step: '1',\n });\n const unitEl = createElement('span', { class: 'an-size-unit' }, ['px']);\n body.appendChild(inputEl);\n body.appendChild(unitEl);\n\n const actionsEl = createElement('div', { class: 'an-size-popover-actions' });\n const cancelBtn = createElement('button', { type: 'button', class: 'an-btn' });\n cancelBtn.textContent = 'Cancel';\n const applyBtn = createElement('button', { type: 'button', class: 'an-btn an-btn-primary' });\n applyBtn.textContent = 'Apply';\n actionsEl.appendChild(cancelBtn);\n actionsEl.appendChild(applyBtn);\n\n popover.appendChild(titleEl);\n popover.appendChild(body);\n popover.appendChild(actionsEl);\n\n this._sizeTitleEl = titleEl;\n this._sizeInputEl = inputEl;\n this._sizeApply = null;\n\n const d1 = on(applyBtn, 'click', () => {\n const val = parseInt(this._sizeInputEl.value, 10);\n if (val > 0 && typeof this._sizeApply === 'function') this._sizeApply(val);\n this._hideSizePopover();\n });\n const d2 = on(cancelBtn, 'click', () => this._hideSizePopover());\n const d3 = on(inputEl, 'keydown', (e) => {\n if (e.key === 'Enter') { e.preventDefault(); applyBtn.click(); }\n if (e.key === 'Escape') this._hideSizePopover();\n });\n const d4 = on(document, 'click', (e) => {\n if (this._sizePopover &&\n this._sizePopover.style.display !== 'none' &&\n !this._sizePopover.contains(e.target) &&\n !this._el.contains(e.target)) {\n this._hideSizePopover();\n }\n });\n // Keep the tooltip/popover alive while the mouse is over the popover.\n const d5 = on(popover, 'mouseenter', () => this._clearTimers());\n const d6 = on(popover, 'mouseleave', () => this._scheduleHide());\n this._disposers.push(d1, d2, d3, d4, d5, d6);\n return popover;\n }\n\n _openSizePopover(type) {\n const cell = this._getCell();\n if (!cell || !this._sizePopover) return;\n const isCol = type === 'col';\n this._sizeTitleEl.textContent = isCol ? 'Column Width (px)' : 'Row Height (px)';\n this._sizeInputEl.value = isCol\n ? (cell.offsetWidth || 120)\n : (cell.closest('tr') ? (cell.closest('tr').offsetHeight || 40) : 40);\n\n this._sizeApply = (val) => {\n if (isCol) {\n const table = cell.closest('table');\n const visualColIdx = getVisualColIndex(cell);\n const rows = Array.from(table.querySelectorAll('tr'));\n // Batch reads, then writes\n const cells = rows.map(r => getCellAtVisualCol(r, visualColIdx));\n cells.forEach(c => {\n if (c) { c.style.width = `${val}px`; c.style.minWidth = `${val}px`; }\n });\n } else {\n const row = cell.closest('tr');\n if (row) {\n for (const c of row.cells) { c.style.height = `${val}px`; c.style.minHeight = `${val}px`; }\n }\n }\n this.context.invoke('editor.afterCommand');\n };\n\n this._sizePopover.style.display = 'block';\n requestAnimationFrame(() => {\n if (!this._sizePopover || !this._el) return;\n const tipRect = this._el.getBoundingClientRect();\n const pw = this._sizePopover.offsetWidth || 220;\n const ph = this._sizePopover.offsetHeight || 110;\n let left = tipRect.left;\n let top = tipRect.bottom + 6;\n if (left + pw > window.innerWidth - 8) left = window.innerWidth - pw - 8;\n if (top + ph > window.innerHeight - 8) top = tipRect.top - ph - 6;\n this._sizePopover.style.left = `${left}px`;\n this._sizePopover.style.top = `${top}px`;\n if (this._sizeInputEl) { this._sizeInputEl.focus(); this._sizeInputEl.select(); }\n });\n }\n\n _hideSizePopover() {\n if (this._sizePopover) this._sizePopover.style.display = 'none';\n this._sizeApply = null;\n }\n}\n","// CodeTooltip.js - Hover tooltip for <pre> code blocks inside the editor\n// Shows a horizontal action bar above (or below) the hovered code block,\n// consistent in appearance and interaction with ImageTooltip / TableTooltip.\nimport { createElement, on } from '../core/dom.js';\n\nconst SHOW_DELAY = 100;\nconst HIDE_DELAY = 180;\n\nconst ICONS = {\n copy: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\"/><path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\"/></svg>`,\n wrapOn: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\"/><path d=\"M3 12h15a3 3 0 0 1 0 6H3\"/><polyline points=\"6 15 3 18 6 21\"/></svg>`,\n toParagraph:`<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M13 4v16\"/><path d=\"M17 4v16\"/><path d=\"M9 4h8a4 4 0 0 1 0 8H9V4z\"/></svg>`,\n deleteCode: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"3 6 5 6 21 6\"/><path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2\"/></svg>`,\n};\n\nexport class CodeTooltip {\n /** @param {import('../Context.js').Context} context */\n constructor(context) {\n this.context = context;\n this._el = null;\n this._activePre = null;\n this._showTimer = null;\n this._hideTimer = null;\n this._disposers = [];\n this._copyBtn = null;\n this._langSelect = null;\n this._prismScript = null; // script element while Prism is loading\n }\n\n initialize() {\n this._el = this._buildTooltip();\n document.body.appendChild(this._el);\n this._ensurePrism();\n\n const editable = this.context.layoutInfo.editable;\n\n this._disposers.push(\n on(editable, 'mouseover', (e) => {\n const pre = e.target.closest('pre');\n if (pre && editable.contains(pre)) {\n this._scheduleShow(pre);\n }\n }),\n on(editable, 'mouseout', (e) => {\n const to = e.relatedTarget;\n if (!to || (!editable.contains(to) && !this._el.contains(to))) {\n this._scheduleHide();\n }\n }),\n on(document, 'click', (e) => {\n if (this._activePre &&\n !this._activePre.contains(e.target) &&\n !this._el.contains(e.target)) {\n this._hide();\n }\n }),\n );\n\n return this;\n }\n\n destroy() {\n this._clearTimers();\n this._disposers.forEach((d) => d());\n this._disposers = [];\n if (this._el && this._el.parentNode) this._el.parentNode.removeChild(this._el);\n this._el = null;\n }\n\n // ---------------------------------------------------------------------------\n // Build\n // ---------------------------------------------------------------------------\n\n _buildTooltip() {\n const el = createElement('div', {\n class: 'an-link-tooltip an-code-tooltip',\n role: 'toolbar',\n 'aria-label': 'Code block actions',\n });\n el.style.display = 'none';\n\n // Label\n this._label = createElement('span', { class: 'an-link-tooltip-url' });\n this._label.textContent = 'Code';\n el.appendChild(this._label);\n\n el.appendChild(this._sep());\n\n // Language selector\n this._langSelect = createElement('select', {\n class: 'an-code-lang-select',\n title: 'Syntax Language',\n 'aria-label': 'Syntax language',\n });\n const LANGUAGES = [\n ['', 'Plain text'], ['javascript', 'JavaScript'], ['typescript', 'TypeScript'],\n ['python', 'Python'], ['html', 'HTML'], ['css', 'CSS'], ['json', 'JSON'],\n ['xml', 'XML'], ['bash', 'Bash / Shell'], ['sql', 'SQL'],\n ['java', 'Java'], ['csharp', 'C#'], ['php', 'PHP'], ['ruby', 'Ruby'],\n ['go', 'Go'], ['rust', 'Rust'], ['cpp', 'C++'], ['c', 'C'],\n ['kotlin', 'Kotlin'], ['swift', 'Swift'],\n ];\n LANGUAGES.forEach(([value, label]) => {\n const opt = createElement('option', { value });\n opt.textContent = label;\n this._langSelect.appendChild(opt);\n });\n this._disposers.push(on(this._langSelect, 'change', () => this._onLangChange()));\n el.appendChild(this._langSelect);\n\n el.appendChild(this._sep());\n\n // Copy code\n this._copyBtn = this._makeBtn(ICONS.copy, 'Copy Code', () => this._copyCode());\n\n el.appendChild(this._copyBtn);\n\n el.appendChild(this._sep());\n\n // Toggle word-wrap\n this._wrapBtn = this._makeBtn(ICONS.wrapOn, 'Toggle Word Wrap', () => this._toggleWrap());\n el.appendChild(this._wrapBtn);\n\n el.appendChild(this._sep());\n\n // Convert to normal paragraph\n el.appendChild(this._makeBtn(ICONS.toParagraph, 'Convert to Paragraph', () => this._toParagraph()));\n\n el.appendChild(this._sep());\n\n // Delete block\n el.appendChild(this._makeBtn(ICONS.deleteCode, 'Delete Code Block', () => this._delete(), true));\n\n // Keep tooltip alive while hovering it\n this._disposers.push(\n on(el, 'mouseenter', () => this._clearTimers()),\n on(el, 'mouseleave', () => this._scheduleHide()),\n );\n\n return el;\n }\n\n _sep() {\n return createElement('div', { class: 'an-link-tooltip-sep' });\n }\n\n /**\n * @param {string} icon\n * @param {string} title\n * @param {Function} handler\n * @param {boolean} [isDanger]\n */\n _makeBtn(icon, title, handler, isDanger = false) {\n const btn = createElement('button', {\n type: 'button',\n class: isDanger ? 'an-link-tooltip-btn an-link-tooltip-btn--danger' : 'an-link-tooltip-btn',\n title,\n });\n btn.innerHTML = icon;\n this._disposers.push(on(btn, 'click', (e) => {\n e.preventDefault();\n e.stopPropagation();\n handler();\n }));\n return btn;\n }\n\n // ---------------------------------------------------------------------------\n // Show / Hide\n // ---------------------------------------------------------------------------\n\n _scheduleShow(pre) {\n if (this._activePre === pre && this._el.style.display !== 'none') return;\n clearTimeout(this._hideTimer);\n this._hideTimer = null;\n clearTimeout(this._showTimer);\n this._showTimer = setTimeout(() => {\n this._activePre = pre;\n this._syncWrapBtn();\n this._syncLangSelect();\n this._show(pre);\n }, SHOW_DELAY);\n }\n\n _scheduleHide() {\n clearTimeout(this._showTimer);\n this._showTimer = null;\n if (this._hideTimer) return;\n this._hideTimer = setTimeout(() => this._hide(), HIDE_DELAY);\n }\n\n _show(pre) {\n this._el.style.display = 'flex';\n this._positionNear(pre);\n }\n\n _hide() {\n this._el.style.display = 'none';\n this._activePre = null;\n this._clearTimers();\n }\n\n _clearTimers() {\n clearTimeout(this._showTimer);\n clearTimeout(this._hideTimer);\n this._showTimer = null;\n this._hideTimer = null;\n }\n\n _positionNear(pre) {\n const rect = pre.getBoundingClientRect();\n const tipW = this._el.offsetWidth || 260;\n const tipH = this._el.offsetHeight || 32;\n const margin = 6;\n\n // Prefer above the block; fall back to below\n let top = rect.top - tipH - margin;\n let left = rect.left + (rect.width - tipW) / 2;\n\n if (top < margin) top = rect.bottom + margin;\n if (left + tipW > window.innerWidth - margin) left = window.innerWidth - tipW - margin;\n if (left < margin) left = margin;\n\n // Tooltip uses position:fixed, so viewport coordinates are used directly.\n this._el.style.top = `${top}px`;\n this._el.style.left = `${left}px`;\n }\n\n // ---------------------------------------------------------------------------\n // Sync wrap-button active state\n // ---------------------------------------------------------------------------\n\n _syncWrapBtn() {\n if (!this._activePre || !this._wrapBtn) return;\n const wrapped = (this._activePre.style.whiteSpace || '').includes('pre-wrap')\n || window.getComputedStyle(this._activePre).whiteSpace === 'pre-wrap';\n this._wrapBtn.classList.toggle('active', wrapped);\n this._wrapBtn.title = wrapped ? 'Disable Word Wrap' : 'Enable Word Wrap';\n }\n\n _syncLangSelect() {\n if (!this._activePre || !this._langSelect) return;\n const codeEl = this._activePre.querySelector('code');\n const fromAttr = this._activePre.getAttribute('data-language') || '';\n const fromClass = codeEl ? (codeEl.className.match(/language-(\\S+)/) || [])[1] || '' : '';\n this._langSelect.value = fromAttr || fromClass || '';\n }\n\n // ---------------------------------------------------------------------------\n // Actions\n // ---------------------------------------------------------------------------\n\n _copyCode() {\n const pre = this._activePre;\n if (!pre) return;\n const text = pre.textContent || '';\n if (navigator.clipboard) {\n navigator.clipboard.writeText(text).then(() => this._flashCopied()).catch(() => {});\n } else {\n // Fallback for older browsers\n const ta = document.createElement('textarea');\n ta.value = text;\n ta.style.cssText = 'position:fixed;opacity:0;top:0;left:0';\n document.body.appendChild(ta);\n ta.select();\n try { document.execCommand('copy'); this._flashCopied(); } catch (_) {}\n document.body.removeChild(ta);\n }\n }\n\n _flashCopied() {\n if (!this._copyBtn) return;\n const original = this._copyBtn.innerHTML;\n this._copyBtn.innerHTML = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"/></svg>`;\n this._copyBtn.classList.add('an-link-tooltip-btn--copied');\n setTimeout(() => {\n if (this._copyBtn) {\n this._copyBtn.innerHTML = original;\n this._copyBtn.classList.remove('an-link-tooltip-btn--copied');\n }\n }, 1400);\n }\n\n _toggleWrap() {\n const pre = this._activePre;\n if (!pre) return;\n const isWrapped = pre.style.whiteSpace === 'pre-wrap';\n pre.style.whiteSpace = isWrapped ? 'pre' : 'pre-wrap';\n this._syncWrapBtn();\n this.context.invoke('editor.afterCommand');\n this._positionNear(pre);\n }\n\n _onLangChange() {\n const pre = this._activePre;\n if (!pre) return;\n const lang = this._langSelect.value;\n\n // Ensure a <code> child exists (Prism targets <pre><code class=\"language-xxx\">)\n let codeEl = pre.querySelector('code');\n if (!codeEl) {\n codeEl = document.createElement('code');\n codeEl.innerHTML = pre.innerHTML;\n pre.innerHTML = '';\n pre.appendChild(codeEl);\n }\n\n codeEl.className = lang ? `language-${lang}` : '';\n // Mirror language class on <pre> so Prism CSS theme targets it (pre[class*='language-'])\n pre.className = lang ? `language-${lang}` : '';\n if (lang) {\n pre.setAttribute('data-language', lang);\n } else {\n pre.removeAttribute('data-language');\n }\n\n // Trigger Prism if available.\n // contenteditable stores line breaks as <br> elements; Prism reads textContent\n // which drops <br> entirely, collapsing all lines into one. Convert first.\n const applyPrism = () => {\n codeEl.querySelectorAll('br').forEach((br) => br.replaceWith('\\n'));\n window.Prism.highlightElement(codeEl);\n this.context.invoke('editor.afterCommand');\n };\n\n if (lang) {\n if (typeof window.Prism !== 'undefined') {\n // Grammar already loaded — highlight immediately\n if (window.Prism.languages[lang]) {\n applyPrism();\n return;\n }\n // Grammar not in core bundle — load the component script first\n this._loadPrismComponent(lang, applyPrism);\n return;\n } else if (this._prismScript) {\n // Prism core is still loading — highlight once it arrives, then load grammar if needed\n this._prismScript.addEventListener('load', () => {\n if (window.Prism.languages[lang]) {\n applyPrism();\n } else {\n this._loadPrismComponent(lang, applyPrism);\n }\n }, { once: true });\n return;\n }\n }\n\n this.context.invoke('editor.afterCommand');\n }\n\n /**\n * Loads Prism.js + CSS from CDN when options.codeHighlight is true.\n * Called once at initialize time. Fire-and-forget; errors are silent.\n */\n _ensurePrism() {\n if (!this.context.options.codeHighlight || window.Prism) return;\n const cdn = this.context.options.codeHighlightCDN\n || 'https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0';\n const themeHref = `${cdn}/themes/prism-tomorrow.min.css`;\n const scriptSrc = `${cdn}/prism.min.js`;\n\n if (!document.querySelector(`link[href=\"${themeHref}\"]`)) {\n const link = document.createElement('link');\n link.rel = 'stylesheet';\n link.href = themeHref;\n document.head.appendChild(link);\n }\n\n const existingScript = document.querySelector(`script[src=\"${scriptSrc}\"]`);\n if (existingScript) {\n this._prismScript = window.Prism ? null : existingScript;\n return;\n }\n\n const script = document.createElement('script');\n script.dataset.manual = ''; // prevent auto-highlight on load\n script.src = scriptSrc;\n this._prismScript = script;\n script.addEventListener('load', () => { this._prismScript = null; }, { once: true });\n document.head.appendChild(script);\n }\n\n /**\n * Dynamically loads a Prism language component script if not already available.\n * Prism core only bundles: markup, css, clike, javascript.\n * All other grammars (bash, python, etc.) need a component file.\n * @param {string} lang – Prism language slug (e.g. 'bash', 'python')\n * @param {Function} cb – called once the grammar is ready\n */\n _loadPrismComponent(lang, cb) {\n const cdn = this.context.options.codeHighlightCDN\n || 'https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0';\n const src = `${cdn}/components/prism-${lang}.min.js`;\n // Avoid loading the same component twice\n if (document.querySelector(`script[src=\"${src}\"]`)) {\n // Already in DOM — might still be loading; poll briefly then call cb\n const poll = setInterval(() => {\n if (window.Prism && window.Prism.languages[lang]) {\n clearInterval(poll);\n cb();\n }\n }, 50);\n setTimeout(() => clearInterval(poll), 3000); // give up after 3s\n return;\n }\n const s = document.createElement('script');\n s.src = src;\n s.addEventListener('load', cb, { once: true });\n document.head.appendChild(s);\n }\n\n _toParagraph() {\n const pre = this._activePre;\n if (!pre) return;\n const editable = this.context.layoutInfo.editable;\n if (!editable) return;\n\n // Replace <pre> with <p> preserving lines as <br>\n const lines = (pre.textContent || '').split('\\n');\n const p = document.createElement('p');\n lines.forEach((line, i) => {\n if (i > 0) p.appendChild(document.createElement('br'));\n p.appendChild(document.createTextNode(line));\n });\n\n pre.parentNode.replaceChild(p, pre);\n this._hide();\n this.context.invoke('editor.afterCommand');\n }\n\n _delete() {\n const pre = this._activePre;\n if (!pre) return;\n this._hide();\n if (pre.parentNode) pre.parentNode.removeChild(pre);\n this.context.invoke('editor.afterCommand');\n }\n}\n","/**\n * EmojiDialog.js - Browse and insert Unicode emoji / symbols (UTF-8 / utf8mb4)\n * Click an emoji to insert it directly at the caret — no extra \"Insert\" step.\n */\n\nimport { createElement, on, trapFocus } from '../core/dom.js';\nimport { withSavedRange } from '../core/range.js';\n\n// ---------------------------------------------------------------------------\n// Emoji catalogue\n// ---------------------------------------------------------------------------\n\nconst EMOJI_CATS = [\n { id: 'smileys', label: 'Smileys' },\n { id: 'people', label: 'People' },\n { id: 'animals', label: 'Animals' },\n { id: 'food', label: 'Food' },\n { id: 'travel', label: 'Travel' },\n { id: 'objects', label: 'Objects' },\n { id: 'symbols', label: 'Symbols' },\n];\n\n// [emoji_char, search_keywords, category]\nconst EMOJI_LIST = [\n // Smileys & Emotions\n ['😀', 'grin smile happy face', 'smileys'],\n ['😃', 'happy smile big eyes', 'smileys'],\n ['😄', 'grinning smile laugh', 'smileys'],\n ['😁', 'beaming smile grin', 'smileys'],\n ['😆', 'laughing lol', 'smileys'],\n ['😅', 'sweat grin awkward', 'smileys'],\n ['🤣', 'rolling laugh rofl', 'smileys'],\n ['😂', 'tears laugh cry joy', 'smileys'],\n ['🙂', 'slight smile', 'smileys'],\n ['🙃', 'upside down smile', 'smileys'],\n ['😉', 'wink', 'smileys'],\n ['😊', 'blush smile happy', 'smileys'],\n ['😇', 'innocent halo angel', 'smileys'],\n ['🥰', 'hearts love adore', 'smileys'],\n ['😍', 'heart eyes love', 'smileys'],\n ['🤩', 'star eyes excited wow', 'smileys'],\n ['😘', 'kiss blow love', 'smileys'],\n ['😋', 'yum delicious tongue', 'smileys'],\n ['😛', 'tongue stuck out', 'smileys'],\n ['😜', 'wink tongue crazy', 'smileys'],\n ['🤪', 'zany crazy wild', 'smileys'],\n ['😝', 'squint tongue', 'smileys'],\n ['🤑', 'money mouth', 'smileys'],\n ['🤗', 'hugging hug', 'smileys'],\n ['🤔', 'thinking hmm', 'smileys'],\n ['🤨', 'raised eyebrow', 'smileys'],\n ['😐', 'neutral face', 'smileys'],\n ['😶', 'no mouth', 'smileys'],\n ['😏', 'smirk', 'smileys'],\n ['😒', 'unamused', 'smileys'],\n ['🙄', 'roll eyes', 'smileys'],\n ['😬', 'grimace', 'smileys'],\n ['😔', 'pensive sad', 'smileys'],\n ['😪', 'sleepy tired', 'smileys'],\n ['😴', 'sleeping zzz', 'smileys'],\n ['🤤', 'drool', 'smileys'],\n ['😷', 'mask sick', 'smileys'],\n ['🤒', 'sick thermometer', 'smileys'],\n ['🤕', 'hurt bandage', 'smileys'],\n ['🤢', 'nausea sick', 'smileys'],\n ['🤮', 'vomit sick', 'smileys'],\n ['🤧', 'sneeze cold', 'smileys'],\n ['🥵', 'hot sweat', 'smileys'],\n ['🥶', 'cold freeze', 'smileys'],\n ['😵', 'dizzy dead', 'smileys'],\n ['🤯', 'mind blown', 'smileys'],\n ['🤠', 'cowboy hat', 'smileys'],\n ['🥳', 'party celebrate', 'smileys'],\n ['😎', 'cool sunglasses', 'smileys'],\n ['🤓', 'nerd glasses', 'smileys'],\n ['🧐', 'monocle curious', 'smileys'],\n ['😕', 'confused', 'smileys'],\n ['😟', 'worried', 'smileys'],\n ['🙁', 'frown sad', 'smileys'],\n ['☹️', 'sad frown', 'smileys'],\n ['😮', 'surprised open mouth', 'smileys'],\n ['😲', 'astonished', 'smileys'],\n ['🥺', 'pleading begging puppy eyes', 'smileys'],\n ['😢', 'cry sad tear', 'smileys'],\n ['😭', 'sob cry loudly', 'smileys'],\n ['😱', 'scream horror fear', 'smileys'],\n ['😡', 'angry red pouting', 'smileys'],\n ['😠', 'angry mad', 'smileys'],\n ['🤬', 'cursing swear', 'smileys'],\n ['😈', 'devil evil smile', 'smileys'],\n ['👿', 'devil angry evil', 'smileys'],\n ['💀', 'skull death', 'smileys'],\n ['☠️', 'skull crossbones', 'smileys'],\n ['💩', 'poop', 'smileys'],\n ['🤡', 'clown', 'smileys'],\n ['👻', 'ghost boo', 'smileys'],\n ['👽', 'alien ufo', 'smileys'],\n ['🤖', 'robot', 'smileys'],\n\n // People & Body\n ['👋', 'wave hello hi hand', 'people'],\n ['🤚', 'raised back hand', 'people'],\n ['✋', 'raised hand stop', 'people'],\n ['🖖', 'vulcan salute spock', 'people'],\n ['👌', 'ok perfect fine', 'people'],\n ['✌️', 'peace victory fingers', 'people'],\n ['🤞', 'fingers crossed luck', 'people'],\n ['🤟', 'love you gesture', 'people'],\n ['🤘', 'sign of horns rock', 'people'],\n ['🤙', 'call me hand', 'people'],\n ['👈', 'point left', 'people'],\n ['👉', 'point right', 'people'],\n ['👆', 'point up', 'people'],\n ['👇', 'point down', 'people'],\n ['☝️', 'index pointing up', 'people'],\n ['👍', 'thumbs up like good', 'people'],\n ['👎', 'thumbs down dislike bad', 'people'],\n ['✊', 'raised fist punch', 'people'],\n ['👊', 'oncoming fist punch', 'people'],\n ['👏', 'clap applause', 'people'],\n ['🙌', 'celebrate raise hands', 'people'],\n ['🤝', 'handshake deal', 'people'],\n ['🙏', 'pray hope please thanks', 'people'],\n ['💅', 'nail polish', 'people'],\n ['💪', 'flexed bicep strong muscle', 'people'],\n ['👀', 'eyes look see', 'people'],\n ['👁️', 'eye', 'people'],\n ['👅', 'tongue', 'people'],\n ['👶', 'baby', 'people'],\n ['🧒', 'child', 'people'],\n ['👦', 'boy', 'people'],\n ['👧', 'girl', 'people'],\n ['🧑', 'person adult', 'people'],\n ['👨', 'man', 'people'],\n ['👩', 'woman', 'people'],\n ['🧔', 'beard man', 'people'],\n ['🧓', 'older person', 'people'],\n ['👴', 'old man', 'people'],\n ['👵', 'old woman', 'people'],\n ['❤️', 'heart love red', 'people'],\n ['🧡', 'orange heart love', 'people'],\n ['💛', 'yellow heart love', 'people'],\n ['💚', 'green heart love', 'people'],\n ['💙', 'blue heart love', 'people'],\n ['💜', 'purple heart love', 'people'],\n ['🖤', 'black heart', 'people'],\n ['🤍', 'white heart', 'people'],\n ['🤎', 'brown heart', 'people'],\n ['💔', 'broken heart', 'people'],\n ['❣️', 'exclamation heart', 'people'],\n ['💕', 'two hearts love', 'people'],\n ['💞', 'revolving hearts', 'people'],\n ['💓', 'beating heart', 'people'],\n ['💗', 'growing heart', 'people'],\n ['💖', 'sparkling heart', 'people'],\n ['💘', 'heart arrow', 'people'],\n ['💝', 'heart ribbon', 'people'],\n ['💬', 'speech bubble comment chat', 'people'],\n ['💭', 'thought bubble', 'people'],\n ['💯', '100 hundred percent perfect', 'people'],\n ['💢', 'anger symbol mad', 'people'],\n ['💤', 'zzz sleep', 'people'],\n\n // Animals & Nature\n ['🐶', 'dog puppy', 'animals'],\n ['🐱', 'cat kitten', 'animals'],\n ['🐭', 'mouse', 'animals'],\n ['🐹', 'hamster', 'animals'],\n ['🐰', 'rabbit bunny', 'animals'],\n ['🦊', 'fox', 'animals'],\n ['🐻', 'bear', 'animals'],\n ['🐼', 'panda', 'animals'],\n ['🐨', 'koala', 'animals'],\n ['🐯', 'tiger', 'animals'],\n ['🦁', 'lion', 'animals'],\n ['🐮', 'cow', 'animals'],\n ['🐷', 'pig', 'animals'],\n ['🐸', 'frog', 'animals'],\n ['🐵', 'monkey', 'animals'],\n ['🙈', 'see no evil monkey', 'animals'],\n ['🙉', 'hear no evil monkey', 'animals'],\n ['🙊', 'speak no evil monkey', 'animals'],\n ['🐔', 'chicken hen', 'animals'],\n ['🐧', 'penguin', 'animals'],\n ['🐦', 'bird', 'animals'],\n ['🦆', 'duck', 'animals'],\n ['🦅', 'eagle', 'animals'],\n ['🦉', 'owl', 'animals'],\n ['🦇', 'bat', 'animals'],\n ['🐺', 'wolf', 'animals'],\n ['🐴', 'horse', 'animals'],\n ['🦄', 'unicorn', 'animals'],\n ['🐝', 'bee', 'animals'],\n ['🦋', 'butterfly', 'animals'],\n ['🐌', 'snail', 'animals'],\n ['🐞', 'ladybug', 'animals'],\n ['🐢', 'turtle', 'animals'],\n ['🐍', 'snake', 'animals'],\n ['🦎', 'lizard', 'animals'],\n ['🐊', 'crocodile', 'animals'],\n ['🐟', 'fish', 'animals'],\n ['🐠', 'tropical fish', 'animals'],\n ['🦈', 'shark', 'animals'],\n ['🐬', 'dolphin', 'animals'],\n ['🐳', 'whale', 'animals'],\n ['🐙', 'octopus', 'animals'],\n ['🦑', 'squid', 'animals'],\n ['🦀', 'crab', 'animals'],\n ['🌸', 'cherry blossom flower', 'animals'],\n ['🌺', 'hibiscus flower', 'animals'],\n ['🌻', 'sunflower', 'animals'],\n ['🌹', 'rose flower', 'animals'],\n ['🌷', 'tulip flower', 'animals'],\n ['🍀', 'four leaf clover luck', 'animals'],\n ['🌿', 'herb leaf green', 'animals'],\n ['🌱', 'seedling sprout', 'animals'],\n ['🌲', 'evergreen tree pine', 'animals'],\n ['🌳', 'deciduous tree', 'animals'],\n ['🌴', 'palm tree', 'animals'],\n ['🍄', 'mushroom', 'animals'],\n ['🌾', 'sheaf wheat', 'animals'],\n ['🐾', 'paw prints animal', 'animals'],\n\n // Food & Drink\n ['🍎', 'apple red', 'food'],\n ['🍊', 'orange tangerine', 'food'],\n ['🍋', 'lemon yellow', 'food'],\n ['🍇', 'grapes', 'food'],\n ['🍓', 'strawberry', 'food'],\n ['🫐', 'blueberry', 'food'],\n ['🍒', 'cherry', 'food'],\n ['🍑', 'peach', 'food'],\n ['🥭', 'mango', 'food'],\n ['🍍', 'pineapple', 'food'],\n ['🥥', 'coconut', 'food'],\n ['🥝', 'kiwi', 'food'],\n ['🍅', 'tomato', 'food'],\n ['🥑', 'avocado', 'food'],\n ['🍆', 'eggplant aubergine', 'food'],\n ['🥕', 'carrot', 'food'],\n ['🌽', 'corn', 'food'],\n ['🥦', 'broccoli', 'food'],\n ['🥬', 'leafy green', 'food'],\n ['🧄', 'garlic', 'food'],\n ['🥜', 'peanut nut', 'food'],\n ['🍞', 'bread loaf', 'food'],\n ['🥐', 'croissant', 'food'],\n ['🧀', 'cheese', 'food'],\n ['🍳', 'egg fry cooking', 'food'],\n ['🥚', 'egg', 'food'],\n ['🥞', 'pancake', 'food'],\n ['🧇', 'waffle', 'food'],\n ['🥓', 'bacon', 'food'],\n ['🥩', 'meat steak', 'food'],\n ['🍗', 'chicken leg', 'food'],\n ['🌭', 'hotdog', 'food'],\n ['🍔', 'burger hamburger', 'food'],\n ['🍟', 'fries french', 'food'],\n ['🍕', 'pizza', 'food'],\n ['🌮', 'taco', 'food'],\n ['🌯', 'burrito wrap', 'food'],\n ['🍜', 'noodles ramen', 'food'],\n ['🍝', 'spaghetti pasta', 'food'],\n ['🍣', 'sushi', 'food'],\n ['🍱', 'bento box', 'food'],\n ['🍦', 'ice cream soft serve', 'food'],\n ['🍩', 'donut', 'food'],\n ['🍪', 'cookie', 'food'],\n ['🎂', 'birthday cake', 'food'],\n ['🍰', 'cake slice', 'food'],\n ['🧁', 'cupcake', 'food'],\n ['🍫', 'chocolate', 'food'],\n ['🍬', 'candy', 'food'],\n ['🍭', 'lollipop', 'food'],\n ['☕', 'coffee hot', 'food'],\n ['🍵', 'tea hot', 'food'],\n ['🧋', 'bubble tea boba', 'food'],\n ['🥤', 'cup straw drink', 'food'],\n ['🍷', 'wine red', 'food'],\n ['🍸', 'cocktail martini', 'food'],\n ['🍺', 'beer mug', 'food'],\n ['🍻', 'clinking beer mugs', 'food'],\n ['🥂', 'champagne toast celebrate', 'food'],\n ['🧃', 'juice box', 'food'],\n ['🧊', 'ice cube', 'food'],\n\n // Travel & Places\n ['🚀', 'rocket space', 'travel'],\n ['🛸', 'ufo flying saucer', 'travel'],\n ['✈️', 'airplane plane fly', 'travel'],\n ['🚁', 'helicopter', 'travel'],\n ['🚂', 'train locomotive', 'travel'],\n ['🚄', 'bullet train fast', 'travel'],\n ['🚇', 'subway metro', 'travel'],\n ['🚌', 'bus', 'travel'],\n ['🚑', 'ambulance', 'travel'],\n ['🚒', 'fire truck', 'travel'],\n ['🚓', 'police car', 'travel'],\n ['🚕', 'taxi cab', 'travel'],\n ['🚗', 'car automobile red', 'travel'],\n ['🚙', 'suv car', 'travel'],\n ['🚚', 'truck delivery', 'travel'],\n ['🚜', 'tractor farm', 'travel'],\n ['🏎️', 'racing car fast', 'travel'],\n ['🏍️', 'motorcycle', 'travel'],\n ['🚲', 'bicycle bike', 'travel'],\n ['🛴', 'scooter kick', 'travel'],\n ['⛵', 'sailboat boat', 'travel'],\n ['🚢', 'ship cruise', 'travel'],\n ['🏠', 'house home', 'travel'],\n ['🏢', 'office building', 'travel'],\n ['🏥', 'hospital', 'travel'],\n ['🏦', 'bank', 'travel'],\n ['🏪', 'store shop convenience', 'travel'],\n ['🏫', 'school', 'travel'],\n ['🏰', 'castle european', 'travel'],\n ['🏯', 'japanese castle', 'travel'],\n ['🗼', 'tokyo tower', 'travel'],\n ['🗽', 'statue liberty new york', 'travel'],\n ['⛪', 'church', 'travel'],\n ['🕌', 'mosque', 'travel'],\n ['⛩️', 'shinto shrine', 'travel'],\n ['⛲', 'fountain', 'travel'],\n ['⛺', 'tent camping', 'travel'],\n ['🌁', 'fog foggy bridge', 'travel'],\n ['🌃', 'night city stars', 'travel'],\n ['🏙️', 'cityscape city buildings', 'travel'],\n ['🌅', 'sunrise morning', 'travel'],\n ['🌈', 'rainbow colorful', 'travel'],\n ['⛰️', 'mountain', 'travel'],\n ['🏔️', 'snow mountain', 'travel'],\n ['🗻', 'mount fuji', 'travel'],\n ['🏕️', 'camping tent', 'travel'],\n ['🗺️', 'world map', 'travel'],\n ['🧭', 'compass navigation', 'travel'],\n ['🌍', 'earth europe africa globe', 'travel'],\n ['🌎', 'earth americas globe', 'travel'],\n ['🌏', 'earth asia globe', 'travel'],\n ['🌐', 'globe internet web', 'travel'],\n\n // Objects\n ['💎', 'diamond gem jewel', 'objects'],\n ['💍', 'ring engagement', 'objects'],\n ['👑', 'crown royal king queen', 'objects'],\n ['🎩', 'top hat magic', 'objects'],\n ['💼', 'briefcase work business', 'objects'],\n ['👜', 'handbag purse', 'objects'],\n ['🎒', 'backpack bag school', 'objects'],\n ['👓', 'glasses eyewear', 'objects'],\n ['🕶️', 'sunglasses cool', 'objects'],\n ['💡', 'light bulb idea', 'objects'],\n ['🔦', 'flashlight torch', 'objects'],\n ['🕯️', 'candle light', 'objects'],\n ['🔋', 'battery charge', 'objects'],\n ['💻', 'laptop computer', 'objects'],\n ['🖥️', 'desktop monitor computer', 'objects'],\n ['📱', 'phone mobile cell', 'objects'],\n ['⌨️', 'keyboard type', 'objects'],\n ['🖱️', 'mouse computer click', 'objects'],\n ['📺', 'television tv', 'objects'],\n ['📷', 'camera photo', 'objects'],\n ['📹', 'video camera', 'objects'],\n ['🎥', 'movie camera film', 'objects'],\n ['☎️', 'telephone phone', 'objects'],\n ['⏰', 'alarm clock wake', 'objects'],\n ['⌚', 'watch time', 'objects'],\n ['🔑', 'key', 'objects'],\n ['🗝️', 'old key', 'objects'],\n ['🔒', 'lock closed', 'objects'],\n ['🔓', 'unlock open', 'objects'],\n ['🔨', 'hammer tool', 'objects'],\n ['🔧', 'wrench tool', 'objects'],\n ['🔩', 'bolt nut', 'objects'],\n ['⚙️', 'gear setting', 'objects'],\n ['🧲', 'magnet attract', 'objects'],\n ['📚', 'books stack library', 'objects'],\n ['📖', 'book open read', 'objects'],\n ['📝', 'memo write note', 'objects'],\n ['✏️', 'pencil write edit', 'objects'],\n ['📌', 'pushpin tack', 'objects'],\n ['📎', 'paperclip attach', 'objects'],\n ['📊', 'bar chart graph', 'objects'],\n ['📈', 'chart up growth trend', 'objects'],\n ['📉', 'chart down loss decline', 'objects'],\n ['📅', 'calendar date', 'objects'],\n ['📦', 'package box', 'objects'],\n ['📫', 'mailbox closed', 'objects'],\n ['📧', 'email envelope', 'objects'],\n ['🎁', 'gift present', 'objects'],\n ['🎀', 'ribbon bow', 'objects'],\n ['🎉', 'party celebrate confetti', 'objects'],\n ['🎊', 'confetti celebrate', 'objects'],\n ['🔮', 'crystal ball magic fortune', 'objects'],\n ['🪄', 'magic wand', 'objects'],\n ['🎯', 'target bullseye dart', 'objects'],\n ['🎲', 'dice game board', 'objects'],\n ['🎮', 'video game controller', 'objects'],\n ['🎭', 'theater masks drama', 'objects'],\n ['🎨', 'art palette paint', 'objects'],\n ['🎬', 'clapper film movie', 'objects'],\n ['🎤', 'microphone sing karaoke', 'objects'],\n ['🎧', 'headphones music listen', 'objects'],\n ['🎵', 'music note', 'objects'],\n ['🎶', 'music notes', 'objects'],\n ['🎸', 'guitar electric', 'objects'],\n ['🎹', 'piano keyboard music', 'objects'],\n ['🥁', 'drum percussion', 'objects'],\n ['🎷', 'saxophone jazz', 'objects'],\n ['🎺', 'trumpet', 'objects'],\n ['🎻', 'violin', 'objects'],\n ['⚽', 'soccer ball football', 'objects'],\n ['🏀', 'basketball', 'objects'],\n ['🏈', 'american football', 'objects'],\n ['⚾', 'baseball', 'objects'],\n ['🎾', 'tennis', 'objects'],\n ['🏐', 'volleyball', 'objects'],\n ['🏆', 'trophy winner award', 'objects'],\n ['🥇', 'gold medal first', 'objects'],\n ['🏅', 'sports medal', 'objects'],\n\n // Symbols\n ['✅', 'check green done success', 'symbols'],\n ['❌', 'cross x no cancel', 'symbols'],\n ['⭕', 'circle red', 'symbols'],\n ['⛔', 'no entry stop', 'symbols'],\n ['🚫', 'prohibited no banned', 'symbols'],\n ['⚠️', 'warning caution danger', 'symbols'],\n ['❗', 'exclamation red important', 'symbols'],\n ['❓', 'question mark', 'symbols'],\n ['‼️', 'double exclamation', 'symbols'],\n ['💯', '100 hundred percent perfect', 'symbols'],\n ['🔴', 'red circle dot', 'symbols'],\n ['🟠', 'orange circle', 'symbols'],\n ['🟡', 'yellow circle', 'symbols'],\n ['🟢', 'green circle', 'symbols'],\n ['🔵', 'blue circle', 'symbols'],\n ['🟣', 'purple circle', 'symbols'],\n ['⚫', 'black circle', 'symbols'],\n ['⚪', 'white circle', 'symbols'],\n ['🟤', 'brown circle', 'symbols'],\n ['🔺', 'red triangle up', 'symbols'],\n ['🔻', 'red triangle down', 'symbols'],\n ['🔷', 'blue diamond large', 'symbols'],\n ['🔶', 'orange diamond large', 'symbols'],\n ['🔹', 'blue diamond small', 'symbols'],\n ['🔸', 'orange diamond small', 'symbols'],\n ['⭐', 'star yellow', 'symbols'],\n ['🌟', 'glowing star shine', 'symbols'],\n ['✨', 'sparkles shine', 'symbols'],\n ['💫', 'dizzy star spin', 'symbols'],\n ['⚡', 'lightning bolt energy power', 'symbols'],\n ['🔥', 'fire hot flame', 'symbols'],\n ['💥', 'explosion boom', 'symbols'],\n ['❄️', 'snowflake cold ice winter', 'symbols'],\n ['🌊', 'wave water ocean sea', 'symbols'],\n ['💨', 'wind blow dash', 'symbols'],\n ['🌀', 'cyclone tornado spiral', 'symbols'],\n ['♻️', 'recycle loop green', 'symbols'],\n ['✔️', 'check tick done', 'symbols'],\n ['➕', 'plus add', 'symbols'],\n ['➖', 'minus subtract', 'symbols'],\n ['➗', 'divide division', 'symbols'],\n ['✖️', 'multiply times cross', 'symbols'],\n ['▶️', 'play button right', 'symbols'],\n ['⏸️', 'pause', 'symbols'],\n ['⏹️', 'stop square', 'symbols'],\n ['⏩', 'fast forward', 'symbols'],\n ['⏪', 'rewind fast backward', 'symbols'],\n ['🔔', 'bell notification', 'symbols'],\n ['🔕', 'bell slash mute', 'symbols'],\n ['🔊', 'speaker volume high', 'symbols'],\n ['🔇', 'mute silent no sound', 'symbols'],\n ['📢', 'loudspeaker announcement', 'symbols'],\n ['📣', 'megaphone cheer', 'symbols'],\n ['🏳️', 'white flag', 'symbols'],\n ['🏴', 'black flag', 'symbols'],\n ['🚩', 'red flag', 'symbols'],\n ['🏁', 'checkered flag finish race', 'symbols'],\n ['🆕', 'new badge', 'symbols'],\n ['🆓', 'free badge', 'symbols'],\n ['🆒', 'cool badge', 'symbols'],\n ['🔝', 'top arrow', 'symbols'],\n ['🔙', 'back arrow', 'symbols'],\n ['ℹ️', 'information info', 'symbols'],\n ['📍', 'pin location map', 'symbols'],\n ['🔗', 'link chain', 'symbols'],\n ['©️', 'copyright', 'symbols'],\n ['®️', 'registered trademark', 'symbols'],\n ['™️', 'trademark', 'symbols'],\n ['#️⃣', 'hash number', 'symbols'],\n ['0️⃣', 'zero number', 'symbols'],\n ['1️⃣', 'one number', 'symbols'],\n ['2️⃣', 'two number', 'symbols'],\n ['3️⃣', 'three number', 'symbols'],\n ['4️⃣', 'four number', 'symbols'],\n ['5️⃣', 'five number', 'symbols'],\n];\n\n// ---------------------------------------------------------------------------\n// Dialog class\n// ---------------------------------------------------------------------------\n\nexport class EmojiDialog {\n /**\n * @param {import('../Context.js').Context} context\n */\n constructor(context) {\n this.context = context;\n /** @type {HTMLElement|null} */\n this._dialog = null;\n this._disposers = [];\n this._savedRange = null;\n this._activeCat = 'all';\n }\n\n // ---------------------------------------------------------------------------\n // Lifecycle\n // ---------------------------------------------------------------------------\n\n initialize() {\n // Dialog grid is built lazily on first show() to avoid rendering ~500 DOM nodes at load time.\n return this;\n }\n\n destroy() {\n this._disposers.forEach((d) => d());\n this._disposers = [];\n if (this._dialog && this._dialog.parentNode) {\n this._dialog.parentNode.removeChild(this._dialog);\n }\n this._dialog = null;\n }\n\n // ---------------------------------------------------------------------------\n // Public API\n // ---------------------------------------------------------------------------\n\n show() {\n if (!this._dialog) {\n this._dialog = this._buildDialog();\n document.body.appendChild(this._dialog);\n }\n withSavedRange((range) => {\n this._savedRange = range;\n });\n this._activeCat = 'all';\n this._searchInput.value = '';\n this._updateCatTabs();\n this._filterEmojis('', 'all');\n this._open();\n }\n\n // ---------------------------------------------------------------------------\n // Build dialog\n // ---------------------------------------------------------------------------\n\n _buildDialog() {\n const overlay = createElement('div', {\n class: 'an-dialog-overlay',\n role: 'dialog',\n 'aria-modal': 'true',\n 'aria-label': 'Insert emoji',\n });\n const box = createElement('div', { class: 'an-dialog-box an-emoji-box' });\n\n // Title row\n const titleRow = createElement('div', { class: 'an-icon-title-row' });\n const title = createElement('h3', { class: 'an-dialog-title' });\n title.textContent = 'Insert Emoji';\n const closeBtn = createElement('button', { type: 'button', class: 'an-icon-close', 'aria-label': 'Close' });\n closeBtn.innerHTML = '×';\n titleRow.append(title, closeBtn);\n\n // Search\n const searchInput = createElement('input', {\n type: 'search',\n class: 'an-input an-icon-search',\n placeholder: 'Search emojis…',\n autocomplete: 'off',\n });\n this._searchInput = searchInput;\n\n // Category tabs\n const catBar = createElement('div', { class: 'an-icon-cats' });\n const allTab = createElement('button', { type: 'button', class: 'an-icon-cat active', 'data-cat': 'all' });\n allTab.textContent = 'All';\n catBar.appendChild(allTab);\n EMOJI_CATS.forEach(({ id, label }) => {\n const tab = createElement('button', { type: 'button', class: 'an-icon-cat', 'data-cat': id });\n tab.textContent = label;\n catBar.appendChild(tab);\n });\n this._catBar = catBar;\n\n // Emoji grid — one button per emoji, click = immediate insert\n const grid = createElement('div', { class: 'an-emoji-grid' });\n EMOJI_LIST.forEach(([char, keywords, cat]) => {\n const cell = createElement('button', {\n type: 'button',\n class: 'an-emoji-cell',\n 'data-char': char,\n 'data-keywords': keywords,\n 'data-cat': cat,\n title: keywords.split(' ').slice(0, 2).join(' '),\n });\n cell.textContent = char;\n grid.appendChild(cell);\n });\n this._grid = grid;\n\n // Cancel only — clicking an emoji inserts immediately\n const btnRow = createElement('div', { class: 'an-dialog-actions' });\n const cancelBtn = createElement('button', { type: 'button', class: 'an-btn' });\n cancelBtn.textContent = 'Cancel';\n btnRow.appendChild(cancelBtn);\n\n box.append(titleRow, searchInput, catBar, grid, btnRow);\n overlay.appendChild(box);\n\n // Events\n const d1 = on(closeBtn, 'click', () => this._close());\n const d2 = on(cancelBtn, 'click', () => this._close());\n const d3 = on(overlay, 'click', (e) => { if (e.target === overlay) this._close(); });\n const d4 = on(searchInput, 'input', () => this._filterEmojis(searchInput.value, this._activeCat));\n const d5 = on(catBar, 'click', (e) => {\n const tab = e.target.closest('[data-cat]');\n if (tab) {\n this._activeCat = tab.dataset.cat;\n this._updateCatTabs();\n this._filterEmojis(this._searchInput.value, this._activeCat);\n }\n });\n const d6 = on(grid, 'click', (e) => {\n const cell = e.target.closest('.an-emoji-cell');\n if (cell) this._onEmojiClick(cell.dataset.char);\n });\n this._disposers.push(d1, d2, d3, d4, d5, d6);\n return overlay;\n }\n\n // ---------------------------------------------------------------------------\n // Filter\n // ---------------------------------------------------------------------------\n\n _updateCatTabs() {\n this._catBar.querySelectorAll('.an-icon-cat').forEach((tab) => {\n tab.classList.toggle('active', tab.dataset.cat === this._activeCat);\n });\n }\n\n _filterEmojis(query, cat) {\n const q = (query || '').trim().toLowerCase();\n let count = 0;\n this._grid.querySelectorAll('.an-emoji-cell').forEach((cell) => {\n const matchCat = !cat || cat === 'all' || cell.dataset.cat === cat;\n const matchQuery = !q || cell.dataset.keywords.includes(q) || cell.dataset.char === q;\n const visible = matchCat && matchQuery;\n cell.style.display = visible ? '' : 'none';\n if (visible) count++;\n });\n let empty = this._grid.querySelector('.an-icon-empty');\n if (!empty) {\n empty = createElement('div', { class: 'an-icon-empty' });\n empty.textContent = 'No emojis found';\n this._grid.appendChild(empty);\n }\n empty.style.display = count > 0 ? 'none' : '';\n }\n\n // ---------------------------------------------------------------------------\n // Insert\n // ---------------------------------------------------------------------------\n\n _onEmojiClick(char) {\n const savedRange = this._savedRange;\n const editable = this.context.layoutInfo.editable;\n\n // 1. Restore selection while dialog is still mounted (same pattern as ImageDialog)\n if (savedRange) savedRange.select();\n\n const sel = window.getSelection();\n let range = sel && sel.rangeCount > 0 ? sel.getRangeAt(0) : null;\n if (!range) {\n range = document.createRange();\n range.selectNodeContents(editable);\n range.collapse(false);\n }\n\n // 2. Insert emoji as a plain text node — no ZWS or execCommand needed.\n // Text nodes are natively navigable so the caret lands cleanly after.\n range.deleteContents();\n const textNode = document.createTextNode(char);\n range.insertNode(textNode);\n\n // 3. Place caret immediately after the emoji character\n range.setStartAfter(textNode);\n range.collapse(true);\n if (sel) {\n sel.removeAllRanges();\n sel.addRange(range);\n }\n\n // 4. Close and restore editor focus\n this._close();\n editable.focus();\n this.context.invoke('editor.afterCommand');\n }\n\n // ---------------------------------------------------------------------------\n // Open / Close\n // ---------------------------------------------------------------------------\n\n _open() {\n if (this._dialog) {\n this._dialog.style.display = 'flex';\n this._removeTrap = trapFocus(this._dialog, () => this._close());\n setTimeout(() => this._searchInput && this._searchInput.focus(), 50);\n }\n }\n\n _close() {\n if (this._dialog) this._dialog.style.display = 'none';\n if (this._removeTrap) { this._removeTrap(); this._removeTrap = null; }\n this._savedRange = null;\n }\n}\n","/**\n * IconDialog.js - Browse and insert FontAwesome Free icons\n */\n\nimport { createElement, on, trapFocus } from '../core/dom.js';\nimport { withSavedRange } from '../core/range.js';\n\n// ---------------------------------------------------------------------------\n// Icon catalogue — FA 6 Free Solid slug names, grouped by category\n// ---------------------------------------------------------------------------\n\nconst ICON_CATEGORIES = [\n { id: 'popular', label: 'Popular' },\n { id: 'interface', label: 'Interface' },\n { id: 'navigation', label: 'Navigation' },\n { id: 'media', label: 'Media' },\n { id: 'communication', label: 'Communication' },\n { id: 'files', label: 'Files' },\n { id: 'people', label: 'People' },\n { id: 'objects', label: 'Objects' },\n];\n\n// Each entry: [slug, category]\nconst ICON_LIST = [\n // Popular\n ['house', 'popular'],\n ['star', 'popular'],\n ['heart', 'popular'],\n ['check', 'popular'],\n ['xmark', 'popular'],\n ['plus', 'popular'],\n ['minus', 'popular'],\n ['magnifying-glass', 'popular'],\n ['gear', 'popular'],\n ['bell', 'popular'],\n ['user', 'popular'],\n ['envelope', 'popular'],\n ['phone', 'popular'],\n ['calendar', 'popular'],\n ['clock', 'popular'],\n ['lock', 'popular'],\n ['eye', 'popular'],\n ['eye-slash', 'popular'],\n ['trash', 'popular'],\n ['pen', 'popular'],\n ['bookmark', 'popular'],\n ['flag', 'popular'],\n ['thumbs-up', 'popular'],\n ['thumbs-down', 'popular'],\n ['circle-info', 'popular'],\n ['triangle-exclamation', 'popular'],\n ['circle-check', 'popular'],\n ['circle-xmark', 'popular'],\n ['share', 'popular'],\n ['download', 'popular'],\n ['upload', 'popular'],\n ['tag', 'popular'],\n // Interface\n ['bars', 'interface'],\n ['ellipsis', 'interface'],\n ['ellipsis-vertical', 'interface'],\n ['list', 'interface'],\n ['table-cells', 'interface'],\n ['table-list', 'interface'],\n ['grip', 'interface'],\n ['filter', 'interface'],\n ['sort', 'interface'],\n ['arrows-rotate', 'interface'],\n ['rotate', 'interface'],\n ['rotate-left', 'interface'],\n ['rotate-right', 'interface'],\n ['copy', 'interface'],\n ['floppy-disk', 'interface'],\n ['print', 'interface'],\n ['link', 'interface'],\n ['code', 'interface'],\n ['expand', 'interface'],\n ['compress', 'interface'],\n ['cloud', 'interface'],\n ['lock-open', 'interface'],\n ['key', 'interface'],\n ['shield', 'interface'],\n ['shield-halved', 'interface'],\n ['sliders', 'interface'],\n ['toggle-on', 'interface'],\n ['square-check', 'interface'],\n ['circle-plus', 'interface'],\n ['circle-minus', 'interface'],\n // Navigation\n ['arrow-right', 'navigation'],\n ['arrow-left', 'navigation'],\n ['arrow-up', 'navigation'],\n ['arrow-down', 'navigation'],\n ['chevron-right', 'navigation'],\n ['chevron-left', 'navigation'],\n ['chevron-up', 'navigation'],\n ['chevron-down', 'navigation'],\n ['angle-right', 'navigation'],\n ['angle-left', 'navigation'],\n ['angle-up', 'navigation'],\n ['angle-down', 'navigation'],\n ['angles-right', 'navigation'],\n ['angles-left', 'navigation'],\n ['location-dot', 'navigation'],\n ['compass', 'navigation'],\n ['map', 'navigation'],\n ['map-pin', 'navigation'],\n ['route', 'navigation'],\n ['circle-arrow-right', 'navigation'],\n ['circle-arrow-left', 'navigation'],\n ['arrow-trend-up', 'navigation'],\n ['arrow-trend-down', 'navigation'],\n ['right-from-bracket', 'navigation'],\n ['right-to-bracket', 'navigation'],\n // Media\n ['play', 'media'],\n ['pause', 'media'],\n ['stop', 'media'],\n ['forward', 'media'],\n ['backward', 'media'],\n ['forward-step', 'media'],\n ['backward-step', 'media'],\n ['volume-high', 'media'],\n ['volume-low', 'media'],\n ['volume-xmark', 'media'],\n ['volume-off', 'media'],\n ['music', 'media'],\n ['headphones', 'media'],\n ['microphone', 'media'],\n ['microphone-slash', 'media'],\n ['film', 'media'],\n ['camera', 'media'],\n ['camera-rotate', 'media'],\n ['video', 'media'],\n ['image', 'media'],\n ['images', 'media'],\n ['photo-film', 'media'],\n ['podcast', 'media'],\n ['radio', 'media'],\n // Communication\n ['comment', 'communication'],\n ['comments', 'communication'],\n ['comment-dots', 'communication'],\n ['message', 'communication'],\n ['paper-plane', 'communication'],\n ['reply', 'communication'],\n ['reply-all', 'communication'],\n ['at', 'communication'],\n ['hashtag', 'communication'],\n ['wifi', 'communication'],\n ['signal', 'communication'],\n ['rss', 'communication'],\n ['share-nodes', 'communication'],\n ['inbox', 'communication'],\n ['phone-volume', 'communication'],\n ['mobile', 'communication'],\n ['mobile-screen', 'communication'],\n ['laptop', 'communication'],\n ['desktop', 'communication'],\n ['tower-broadcast', 'communication'],\n // Files\n ['file', 'files'],\n ['file-lines', 'files'],\n ['folder', 'files'],\n ['folder-open', 'files'],\n ['folder-plus', 'files'],\n ['folder-minus', 'files'],\n ['file-image', 'files'],\n ['file-pdf', 'files'],\n ['file-code', 'files'],\n ['file-zipper', 'files'],\n ['file-audio', 'files'],\n ['file-video', 'files'],\n ['file-arrow-up', 'files'],\n ['file-arrow-down', 'files'],\n ['database', 'files'],\n ['box', 'files'],\n ['box-open', 'files'],\n ['hard-drive', 'files'],\n ['server', 'files'],\n // People\n ['user', 'people'],\n ['users', 'people'],\n ['user-group', 'people'],\n ['user-plus', 'people'],\n ['user-minus', 'people'],\n ['user-check', 'people'],\n ['user-xmark', 'people'],\n ['user-tie', 'people'],\n ['user-shield', 'people'],\n ['user-secret', 'people'],\n ['person', 'people'],\n ['person-running', 'people'],\n ['person-walking', 'people'],\n ['child', 'people'],\n ['handshake', 'people'],\n ['hand', 'people'],\n ['hands-holding', 'people'],\n ['people-group', 'people'],\n // Objects\n ['pencil', 'objects'],\n ['paintbrush', 'objects'],\n ['eraser', 'objects'],\n ['scissors', 'objects'],\n ['wrench', 'objects'],\n ['screwdriver', 'objects'],\n ['hammer', 'objects'],\n ['toolbox', 'objects'],\n ['graduation-cap', 'objects'],\n ['book', 'objects'],\n ['book-open', 'objects'],\n ['glasses', 'objects'],\n ['microscope', 'objects'],\n ['flask', 'objects'],\n ['stethoscope', 'objects'],\n ['hospital', 'objects'],\n ['building', 'objects'],\n ['city', 'objects'],\n ['car', 'objects'],\n ['truck', 'objects'],\n ['plane', 'objects'],\n ['train', 'objects'],\n ['bicycle', 'objects'],\n ['bus', 'objects'],\n ['rocket', 'objects'],\n ['briefcase', 'objects'],\n ['cart-shopping', 'objects'],\n ['bag-shopping', 'objects'],\n ['credit-card', 'objects'],\n ['money-bill', 'objects'],\n ['chart-bar', 'objects'],\n ['chart-line', 'objects'],\n ['chart-pie', 'objects'],\n ['bolt', 'objects'],\n ['sun', 'objects'],\n ['moon', 'objects'],\n ['snowflake', 'objects'],\n ['fire', 'objects'],\n ['droplet', 'objects'],\n ['leaf', 'objects'],\n ['tree', 'objects'],\n ['earth-americas', 'objects'],\n ['globe', 'objects'],\n ['award', 'objects'],\n ['trophy', 'objects'],\n ['gift', 'objects'],\n ['puzzle-piece', 'objects'],\n];\n\nexport class IconDialog {\n /**\n * @param {import('../Context.js').Context} context\n */\n constructor(context) {\n this.context = context;\n /** @type {HTMLElement|null} */\n this._dialog = null;\n this._disposers = [];\n this._savedRange = null;\n this._selectedIcon = null;\n this._activeCat = 'all';\n }\n\n // ---------------------------------------------------------------------------\n // Lifecycle\n // ---------------------------------------------------------------------------\n\n initialize() {\n this._ensureFontAwesome();\n // Dialog grid is built lazily on first show() to avoid rendering ~250 icon cells at load time.\n return this;\n }\n\n /**\n * Injects FA 6 Free CSS from CDN if it is not already on the page.\n * This guarantees icon glyphs render in the grid, preview, and in the\n * editor content after insertion — regardless of whether the host page\n * loaded FA itself.\n */\n _ensureFontAwesome() {\n // Already present (icon element or stylesheet link)?\n if (document.getElementById('an-fontawesome-css')) return;\n const links = Array.from(document.querySelectorAll('link[rel=\"stylesheet\"]'))\n .map((l) => l.href || '').join(' ');\n if (/fontawesome|font-awesome/.test(links)) return;\n if (document.querySelector('.fa-solid, .fas, .far, .fab')) return;\n\n const link = document.createElement('link');\n link.id = 'an-fontawesome-css';\n link.rel = 'stylesheet';\n link.href = 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css';\n link.crossOrigin = 'anonymous';\n link.referrerPolicy = 'no-referrer';\n document.head.appendChild(link);\n }\n\n destroy() {\n this._disposers.forEach((d) => d());\n this._disposers = [];\n if (this._dialog && this._dialog.parentNode) {\n this._dialog.parentNode.removeChild(this._dialog);\n }\n this._dialog = null;\n }\n\n // ---------------------------------------------------------------------------\n // Public API\n // ---------------------------------------------------------------------------\n\n show() {\n if (!this._dialog) {\n this._dialog = this._buildDialog();\n document.body.appendChild(this._dialog);\n }\n withSavedRange((range) => {\n this._savedRange = range;\n });\n this._selectedIcon = null;\n this._activeCat = 'all';\n this._searchInput.value = '';\n // Clear previously selected icon highlight and disable Insert button\n this._grid.querySelectorAll('.an-icon-cell.active').forEach((c) => c.classList.remove('active'));\n this._insertBtn.setAttribute('disabled', '');\n this._updateCatTabs();\n this._filterIcons('', 'all');\n this._updatePreview(null);\n this._open();\n }\n\n // ---------------------------------------------------------------------------\n // Build dialog\n // ---------------------------------------------------------------------------\n\n _buildDialog() {\n const overlay = createElement('div', {\n class: 'an-dialog-overlay',\n role: 'dialog',\n 'aria-modal': 'true',\n 'aria-label': 'Insert FA icon',\n });\n\n const box = createElement('div', { class: 'an-dialog-box an-icon-box' });\n\n // Title row\n const titleRow = createElement('div', { class: 'an-icon-title-row' });\n const title = createElement('h3', { class: 'an-dialog-title' });\n title.textContent = 'Insert FA Icon';\n const closeBtn = createElement('button', { type: 'button', class: 'an-icon-close', 'aria-label': 'Close' });\n closeBtn.innerHTML = '×';\n titleRow.append(title, closeBtn);\n\n // Search\n const searchInput = createElement('input', {\n type: 'search',\n class: 'an-input an-icon-search',\n placeholder: 'Search icons…',\n autocomplete: 'off',\n });\n this._searchInput = searchInput;\n\n // Category tabs\n const catBar = createElement('div', { class: 'an-icon-cats' });\n const allTab = createElement('button', { type: 'button', class: 'an-icon-cat active', 'data-cat': 'all' });\n allTab.textContent = 'All';\n catBar.appendChild(allTab);\n ICON_CATEGORIES.forEach(({ id, label }) => {\n const tab = createElement('button', { type: 'button', class: 'an-icon-cat', 'data-cat': id });\n tab.textContent = label;\n catBar.appendChild(tab);\n });\n this._catBar = catBar;\n\n // Icon grid\n const grid = createElement('div', { class: 'an-icon-grid' });\n ICON_LIST.forEach(([name, cat]) => {\n const cell = createElement('button', { type: 'button', class: 'an-icon-cell', 'data-name': name, 'data-cat': cat, title: name });\n const icon = createElement('i', { class: 'fa-solid fa-' + name, 'aria-hidden': 'true' });\n const label = createElement('span');\n label.textContent = name;\n cell.append(icon, label);\n grid.appendChild(cell);\n });\n this._grid = grid;\n\n // Options row: style + size + color\n const optRow = createElement('div', { class: 'an-icon-options' });\n\n const styleLabel = createElement('label', { class: 'an-label' });\n styleLabel.textContent = 'Style';\n const styleSelect = createElement('select', { class: 'an-input an-icon-option-select' });\n [['fa-solid', 'Solid'], ['fa-regular', 'Regular'], ['fa-light', 'Light (Pro)']].forEach(([v, t]) => {\n const opt = createElement('option', { value: v });\n opt.textContent = t;\n styleSelect.appendChild(opt);\n });\n styleSelect.value = 'fa-solid';\n this._styleSelect = styleSelect;\n\n const sizeLabel = createElement('label', { class: 'an-label' });\n sizeLabel.textContent = 'Size';\n const sizeSelect = createElement('select', { class: 'an-input an-icon-option-select' });\n [['', 'Inherit'], ['0.75em', '0.75em'], ['1em', '1em'], ['1.25em', '1.25em'], ['1.5em', '1.5em'], ['2em', '2em'], ['3em', '3em']].forEach(([v, t]) => {\n const opt = createElement('option', { value: v });\n if (v === '1em') opt.selected = true;\n opt.textContent = t;\n sizeSelect.appendChild(opt);\n });\n this._sizeSelect = sizeSelect;\n\n const colorLabel = createElement('label', { class: 'an-label' });\n colorLabel.textContent = 'Color';\n const colorInput = createElement('input', { type: 'color', class: 'an-icon-color', value: '#000000' });\n this._colorInput = colorInput;\n\n const useColorLabel = createElement('label', { class: 'an-label an-label-inline an-icon-use-color' });\n const useColorCb = createElement('input', { type: 'checkbox', checked: '' });\n this._useColorCb = useColorCb;\n useColorLabel.append(useColorCb, document.createTextNode(' Use color'));\n\n optRow.append(styleLabel, styleSelect, sizeLabel, sizeSelect, colorLabel, colorInput, useColorLabel);\n\n // Preview\n const preview = createElement('div', { class: 'an-icon-preview' });\n const previewHint = createElement('span', { class: 'an-icon-preview-hint' });\n previewHint.textContent = 'Select an icon';\n preview.appendChild(previewHint);\n this._preview = preview;\n\n // Actions\n const btnRow = createElement('div', { class: 'an-dialog-actions' });\n const insertBtn = createElement('button', { type: 'button', class: 'an-btn an-btn-primary', disabled: '' });\n insertBtn.textContent = 'Insert FA Icon';\n const cancelBtn = createElement('button', { type: 'button', class: 'an-btn' });\n cancelBtn.textContent = 'Cancel';\n btnRow.append(insertBtn, cancelBtn);\n this._insertBtn = insertBtn;\n\n box.append(titleRow, searchInput, catBar, grid, optRow, preview, btnRow);\n overlay.appendChild(box);\n\n // -------------------------------------------------------------------------\n // Events\n // -------------------------------------------------------------------------\n\n const d1 = on(closeBtn, 'click', () => this._close());\n const d2 = on(cancelBtn, 'click', () => this._close());\n const d3 = on(insertBtn, 'click', () => this._onInsert());\n const d4 = on(overlay, 'click', (e) => { if (e.target === overlay) this._close(); });\n const d5 = on(searchInput, 'input', () => this._filterIcons(searchInput.value, this._activeCat));\n const d6 = on(catBar, 'click', (e) => {\n const tab = e.target.closest('[data-cat]');\n if (tab) {\n this._activeCat = tab.dataset.cat;\n this._updateCatTabs();\n this._filterIcons(this._searchInput.value, this._activeCat);\n }\n });\n const d7 = on(grid, 'click', (e) => {\n const cell = e.target.closest('.an-icon-cell');\n if (cell) this._selectIcon(cell.dataset.name);\n });\n const d8 = on(styleSelect, 'change', () => this._updatePreview(this._selectedIcon));\n const d9 = on(sizeSelect, 'change', () => this._updatePreview(this._selectedIcon));\n const d10 = on(colorInput, 'input', () => this._updatePreview(this._selectedIcon));\n const d11 = on(useColorCb, 'change', () => this._updatePreview(this._selectedIcon));\n\n this._disposers.push(d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11);\n\n return overlay;\n }\n\n // ---------------------------------------------------------------------------\n // Filter / select\n // ---------------------------------------------------------------------------\n\n _updateCatTabs() {\n this._catBar.querySelectorAll('.an-icon-cat').forEach((tab) => {\n tab.classList.toggle('active', tab.dataset.cat === this._activeCat);\n });\n }\n\n _filterIcons(query, cat) {\n const q = (query || '').trim().toLowerCase();\n let visibleCount = 0;\n this._grid.querySelectorAll('.an-icon-cell').forEach((cell) => {\n const name = cell.dataset.name;\n const cellCat = cell.dataset.cat;\n const matchesCat = !cat || cat === 'all' || cellCat === cat;\n const matchesQuery = !q || name.includes(q);\n const visible = matchesCat && matchesQuery;\n cell.style.display = visible ? '' : 'none';\n if (visible) visibleCount++;\n });\n // Show empty state if needed\n let empty = this._grid.querySelector('.an-icon-empty');\n if (!empty) {\n empty = createElement('div', { class: 'an-icon-empty' });\n empty.textContent = 'No icons found';\n this._grid.appendChild(empty);\n }\n empty.style.display = visibleCount > 0 ? 'none' : '';\n }\n\n _selectIcon(name) {\n this._selectedIcon = name;\n // Highlight selected cell\n this._grid.querySelectorAll('.an-icon-cell').forEach((cell) => {\n cell.classList.toggle('active', cell.dataset.name === name);\n });\n // Enable insert button\n this._insertBtn.removeAttribute('disabled');\n // Update preview\n this._updatePreview(name);\n }\n\n _updatePreview(name) {\n if (!this._preview) return;\n if (!name) {\n this._preview.innerHTML = '<span class=\"an-icon-preview-hint\">Select an icon</span>';\n return;\n }\n const cls = (this._styleSelect && this._styleSelect.value) || 'fa-solid';\n const size = (this._sizeSelect && this._sizeSelect.value) || '1em';\n const useColor = this._useColorCb ? this._useColorCb.checked : false;\n const color = (useColor && this._colorInput) ? this._colorInput.value : '';\n const styleAttr = [\n size ? `font-size:${size}` : '',\n color ? `color:${color}` : '',\n ].filter(Boolean).join(';');\n // Use innerHTML — atomic, no partial-update risk\n this._preview.innerHTML =\n `<i class=\"${cls} fa-${name}\" aria-hidden=\"true\"${\n styleAttr ? ` style=\"${styleAttr}\"` : ''\n }></i>` +\n `<div class=\"an-icon-preview-name\">${cls} fa-${name}</div>`;\n }\n\n // ---------------------------------------------------------------------------\n // Insert\n // ---------------------------------------------------------------------------\n\n _onInsert() {\n if (!this._selectedIcon) return;\n\n const cls = (this._styleSelect && this._styleSelect.value) || 'fa-solid';\n const size = (this._sizeSelect && this._sizeSelect.value) || '';\n const useColor = this._useColorCb ? this._useColorCb.checked : false;\n const color = (useColor && this._colorInput) ? this._colorInput.value : '';\n const styleParts = [\n size ? `font-size:${size}` : '',\n color ? `color:${color}` : '',\n ].filter(Boolean);\n\n const iconEl = document.createElement('i');\n iconEl.className = `${cls} fa-${this._selectedIcon}`;\n iconEl.setAttribute('aria-hidden', 'true');\n iconEl.setAttribute('contenteditable', 'false');\n if (styleParts.length) iconEl.setAttribute('style', styleParts.join(';'));\n\n const savedRange = this._savedRange;\n const editable = this.context.layoutInfo.editable;\n\n // ---- Same ordering as ImageDialog (the proven pattern) ----\n // 1. Restore the selection while the dialog is still mounted\n if (savedRange) savedRange.select();\n\n // 2. Get the now-live range from the selection\n const sel = window.getSelection();\n let range = sel && sel.rangeCount > 0 ? sel.getRangeAt(0) : null;\n if (!range) {\n range = document.createRange();\n range.selectNodeContents(editable);\n range.collapse(false);\n }\n\n // 3. Insert the <i> node directly — never via execCommand/insertHTML\n // (execCommand leaves the caret inside the inserted element)\n range.deleteContents();\n range.insertNode(iconEl);\n\n // 4. Place cursor after the icon.\n // Keep a text anchor (\\u200B) after the icon so ArrowLeft/ArrowRight and\n // caret placement at end-of-line stay stable across browsers.\n let caretTextNode = iconEl.nextSibling;\n if (!caretTextNode || caretTextNode.nodeType !== Node.TEXT_NODE) {\n caretTextNode = document.createTextNode('\\u200B');\n iconEl.parentNode.insertBefore(caretTextNode, iconEl.nextSibling);\n } else if (!caretTextNode.textContent) {\n // Split text-node insertions can leave an empty text node after icon.\n // Fill it with ZWS so caret-after-icon remains stable at end-of-line.\n caretTextNode.textContent = '\\u200B';\n }\n\n const caretOffset = ((caretTextNode.textContent || '').startsWith('\\u200B')) ? 1 : 0;\n const caretRange = document.createRange();\n caretRange.setStart(caretTextNode, Math.min(caretOffset, caretTextNode.textContent.length));\n caretRange.collapse(true);\n if (sel) {\n sel.removeAllRanges();\n sel.addRange(caretRange);\n }\n\n // 5. Close dialog last — same as ImageDialog\n this._close();\n\n // 6. Restore editor focus (needed for toolbar refresh via afterCommand)\n editable.focus();\n if (sel) {\n // Some browsers reset selection when refocusing editable after closing dialog.\n sel.removeAllRanges();\n sel.addRange(caretRange);\n }\n this.context.invoke('editor.afterCommand');\n }\n\n // ---------------------------------------------------------------------------\n // Open / Close\n // ---------------------------------------------------------------------------\n\n _open() {\n if (this._dialog) {\n this._dialog.style.display = 'flex';\n this._removeTrap = trapFocus(this._dialog, () => this._close());\n setTimeout(() => this._searchInput && this._searchInput.focus(), 50);\n }\n }\n\n _close() {\n if (this._dialog) this._dialog.style.display = 'none';\n if (this._removeTrap) { this._removeTrap(); this._removeTrap = null; }\n this._savedRange = null;\n this._selectedIcon = null;\n }\n}\n","// ContextMenu.js - Right-click context menu for editor actions\nimport { createElement, on } from '../core/dom.js';\nimport { sanitiseHTML } from '../core/sanitise.js';\n\n// SVG icon map — 16×16 Heroicons-style paths\nconst ICONS = {\n undo: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M3 7v6h6\"/><path d=\"M21 17a9 9 0 0 0-9-9 9 9 0 0 0-6 2.3L3 13\"/></svg>`,\n redo: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M21 7v6h-6\"/><path d=\"M3 17a9 9 0 0 1 9-9 9 9 0 0 1 6 2.3L21 13\"/></svg>`,\n cut: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"6\" cy=\"20\" r=\"3\"/><circle cx=\"6\" cy=\"4\" r=\"3\"/><line x1=\"19\" y1=\"5\" x2=\"6\" y2=\"19\"/><line x1=\"19\" y1=\"19\" x2=\"13.5\" y2=\"13.5\"/></svg>`,\n copy: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\"/><path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\"/></svg>`,\n paste: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2\"/><rect x=\"8\" y=\"2\" width=\"8\" height=\"4\" rx=\"1\"/></svg>`,\n bold: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M6 4h8a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z\"/><path d=\"M6 12h9a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z\"/></svg>`,\n italic: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"19\" y1=\"4\" x2=\"10\" y2=\"4\"/><line x1=\"14\" y1=\"20\" x2=\"5\" y2=\"20\"/><line x1=\"15\" y1=\"4\" x2=\"9\" y2=\"20\"/></svg>`,\n underline: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M6 3v7a6 6 0 0 0 6 6 6 6 0 0 0 6-6V3\"/><line x1=\"4\" y1=\"21\" x2=\"20\" y2=\"21\"/></svg>`,\n link: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71\"/><path d=\"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71\"/></svg>`,\n image: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\"/><circle cx=\"8.5\" cy=\"8.5\" r=\"1.5\"/><polyline points=\"21 15 16 10 5 21\"/></svg>`,\n video: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polygon points=\"23 7 16 12 23 17 23 7\"/><rect x=\"1\" y=\"5\" width=\"15\" height=\"14\" rx=\"2\"/></svg>`,\n // Image format operations\n floatLeft: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"2\" y=\"4\" width=\"8\" height=\"8\" rx=\"1\"/><line x1=\"12\" y1=\"6\" x2=\"22\" y2=\"6\"/><line x1=\"12\" y1=\"9\" x2=\"22\" y2=\"9\"/><line x1=\"12\" y1=\"12\" x2=\"22\" y2=\"12\"/><line x1=\"2\" y1=\"16\" x2=\"22\" y2=\"16\"/><line x1=\"2\" y1=\"20\" x2=\"18\" y2=\"20\"/></svg>`,\n floatRight: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"14\" y=\"4\" width=\"8\" height=\"8\" rx=\"1\"/><line x1=\"2\" y1=\"6\" x2=\"12\" y2=\"6\"/><line x1=\"2\" y1=\"9\" x2=\"12\" y2=\"9\"/><line x1=\"2\" y1=\"12\" x2=\"12\" y2=\"12\"/><line x1=\"2\" y1=\"16\" x2=\"22\" y2=\"16\"/><line x1=\"2\" y1=\"20\" x2=\"18\" y2=\"20\"/></svg>`,\n floatNone: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"3\" width=\"8\" height=\"8\" rx=\"1\"/><line x1=\"3\" y1=\"15\" x2=\"21\" y2=\"15\"/><line x1=\"3\" y1=\"19\" x2=\"17\" y2=\"19\"/></svg>`,\n originalSize:`<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"15 3 21 3 21 9\"/><polyline points=\"9 21 3 21 3 15\"/><line x1=\"21\" y1=\"3\" x2=\"14\" y2=\"10\"/><line x1=\"3\" y1=\"21\" x2=\"10\" y2=\"14\"/></svg>`,\n deleteImg: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"3 6 5 6 21 6\"/><path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2\"/></svg>`,\n // Video format operations\n videoAlign: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polygon points=\"23 7 16 12 23 17 23 7\"/><rect x=\"1\" y=\"5\" width=\"15\" height=\"14\" rx=\"2\"/></svg>`,\n deleteVideo: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"3 6 5 6 21 6\"/><path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2\"/></svg>`,\n // Format painter operations\n copyFormat: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7\"/><path d=\"M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z\"/></svg>`,\n pasteFormat: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2\"/><rect x=\"8\" y=\"2\" width=\"8\" height=\"4\" rx=\"1\"/><path d=\"m9 14 2 2 4-4\"/></svg>`,\n removeFormat:`<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"m7 21-4.3-4.3c-1-1-1-2.5 0-3.4l9.6-9.6c1-1 2.5-1 3.4 0l5.6 5.6c1 1 1 2.5 0 3.4L13 21\"/><path d=\"M22 21H7\"/><path d=\"m5 11 9 9\"/></svg>`,\n // Table\n table: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"1\"/><line x1=\"3\" y1=\"9\" x2=\"21\" y2=\"9\"/><line x1=\"3\" y1=\"15\" x2=\"21\" y2=\"15\"/><line x1=\"9\" y1=\"3\" x2=\"9\" y2=\"21\"/><line x1=\"15\" y1=\"3\" x2=\"15\" y2=\"21\"/></svg>`,\n};\n\nconst defaultItems = [\n { name: 'undo', label: 'Undo', icon: ICONS.undo, action: (ctx) => ctx.invoke('editor.undo') },\n { name: 'redo', label: 'Redo', icon: ICONS.redo, action: (ctx) => ctx.invoke('editor.redo') },\n { separator: true },\n { name: 'cut', label: 'Cut', icon: ICONS.cut, action: () => document.execCommand('cut') },\n { name: 'copy', label: 'Copy', icon: ICONS.copy, action: () => document.execCommand('copy') },\n { name: 'paste', label: 'Paste', icon: ICONS.paste, action: (ctx) => {\n if (!navigator.clipboard) return;\n const editable = ctx.layoutInfo && ctx.layoutInfo.editable;\n if (!editable) return;\n // Prefer read() to get rich HTML; fall back to readText() for plain text\n const doInsert = (html, text) => {\n editable.focus();\n if (html) {\n const clean = sanitiseHTML(html);\n document.execCommand('insertHTML', false, clean);\n } else if (text) {\n document.execCommand('insertText', false, text);\n }\n ctx.invoke('editor.afterCommand');\n };\n if (typeof navigator.clipboard.read === 'function') {\n navigator.clipboard.read().then((items) => {\n for (const item of items) {\n if (item.types.includes('text/html')) {\n item.getType('text/html').then((blob) => blob.text()).then((html) => doInsert(html, null));\n return;\n }\n }\n // No HTML item — fall through to plain text\n navigator.clipboard.readText().then((text) => doInsert(null, text)).catch(() => {});\n }).catch(() => {\n // read() denied → try readText() as fallback\n navigator.clipboard.readText().then((text) => doInsert(null, text)).catch(() => {});\n });\n } else if (typeof navigator.clipboard.readText === 'function') {\n navigator.clipboard.readText().then((text) => doInsert(null, text)).catch(() => {});\n }\n } },\n { separator: true },\n { name: 'bold', label: 'Bold', icon: ICONS.bold, action: (ctx) => ctx.invoke('editor.bold') },\n { name: 'italic', label: 'Italic', icon: ICONS.italic, action: (ctx) => ctx.invoke('editor.italic') },\n { name: 'underline', label: 'Underline', icon: ICONS.underline, action: (ctx) => ctx.invoke('editor.underline') },\n { separator: true },\n { name: 'copyFormat', label: 'Copy Format', icon: ICONS.copyFormat, action: (ctx) => ctx.invoke('contextMenu.copyFormat') },\n { name: 'pasteFormat', label: 'Paste Format', icon: ICONS.pasteFormat, action: (ctx) => ctx.invoke('contextMenu.pasteFormat'), disabled: (ctx) => !ctx.invoke('contextMenu.hasCopiedFormat') },\n { name: 'removeFormat', label: 'Remove Format', icon: ICONS.removeFormat, action: (ctx) => ctx.invoke('contextMenu.removeFormat') },\n { separator: true },\n { name: 'link', label: 'Insert Link', icon: ICONS.link, action: (ctx) => ctx.invoke('linkDialog.show') },\n { name: 'image', label: 'Insert Image', icon: ICONS.image, action: (ctx) => ctx.invoke('imageDialog.show') },\n { name: 'video', label: 'Insert Video', icon: ICONS.video, action: (ctx) => ctx.invoke('videoDialog.show') },\n { name: 'table', label: 'Insert Table', icon: ICONS.table, tableGrid: true },\n];\n\nexport class ContextMenu {\n /** @param {import('../Context.js').Context} context */\n constructor(context) {\n this.context = context;\n this.options = context.options || {};\n this._items = (this.options.contextMenu && this.options.contextMenu.items) || defaultItems;\n this.el = null;\n this._disposers = [];\n this._menuDisposers = []; // disposers for dynamically-rendered menu buttons\n this._lastX = 0;\n this._lastY = 0;\n this._copiedFormat = null;\n this._savedRange = null;\n }\n\n initialize() {\n this.el = createElement('div', { class: 'an-contextmenu', role: 'menu', 'aria-hidden': 'true' });\n this.el.style.display = 'none';\n document.body.appendChild(this.el);\n\n this._renderItems(this._items);\n\n const editable = this.context.layoutInfo && this.context.layoutInfo.editable;\n if (editable) {\n this._disposers.push(on(editable, 'contextmenu', (e) => this._onContextMenu(e)));\n }\n\n this._disposers.push(on(document, 'click', (e) => this._maybeHide(e)));\n this._disposers.push(on(document, 'keydown', (e) => { if (e.key === 'Escape') this.hide(); }));\n this._disposers.push(on(window, 'scroll', () => this.hide(), { passive: true }));\n\n return this;\n }\n\n destroy() {\n this._menuDisposers.forEach((d) => { try { d(); } catch (e) {} });\n this._menuDisposers = [];\n this._disposers.forEach((d) => { try { d(); } catch (e) {} });\n this._disposers = [];\n if (this.el && this.el.parentNode) this.el.parentNode.removeChild(this.el);\n this.el = null;\n }\n\n _renderItems(items) {\n // Clean up previously registered per-item listeners\n this._menuDisposers.forEach((d) => d());\n this._menuDisposers = [];\n\n if (!this.el) return;\n this.el.innerHTML = '';\n\n items.forEach((it) => {\n if (it.separator || it.sep) {\n this.el.appendChild(createElement('div', { class: 'an-context-sep' }));\n return;\n }\n\n // Back-navigation header\n if (it.back) {\n const backBtn = createElement('button', { type: 'button', class: 'an-context-back' });\n const iconSpan = createElement('span', { class: 'an-context-icon', 'aria-hidden': 'true' });\n iconSpan.innerHTML = ICONS.back;\n backBtn.appendChild(iconSpan);\n backBtn.appendChild(createElement('span', { class: 'an-context-label' }, [it.label || 'Back']));\n const off = on(backBtn, 'click', (e) => {\n e.stopPropagation();\n this._renderItems(it.navigate());\n this._reposition();\n });\n this._menuDisposers.push(off);\n this.el.appendChild(backBtn);\n return;\n }\n\n // Submenu-navigate item (shows ▶ chevron, re-renders without closing)\n if (it.navigate) {\n const btn = createElement('button', { type: 'button', class: 'an-context-item an-context-submenu', 'data-name': it.name || '' });\n if (it.icon) {\n const iconSpan = createElement('span', { class: 'an-context-icon', 'aria-hidden': 'true' });\n iconSpan.innerHTML = it.icon;\n btn.appendChild(iconSpan);\n }\n btn.appendChild(createElement('span', { class: 'an-context-label' }, [it.label || it.name]));\n const chevron = createElement('span', { class: 'an-context-chevron', 'aria-hidden': 'true' });\n chevron.innerHTML = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"9 18 15 12 9 6\"/></svg>`;\n btn.appendChild(chevron);\n const off = on(btn, 'click', (e) => {\n e.stopPropagation();\n this._renderItems(it.navigate());\n this._reposition();\n });\n this._menuDisposers.push(off);\n this.el.appendChild(btn);\n return;\n }\n\n // Table grid picker item — expands an inline grid panel when clicked\n if (it.tableGrid) {\n const GRID_ROWS = 8, GRID_COLS = 8;\n const wrapper = createElement('div', { class: 'an-context-table-wrap' });\n\n const headerBtn = createElement('button', { type: 'button', class: 'an-context-item an-context-submenu', 'data-name': it.name || 'table' });\n if (it.icon) {\n const iconSpan = createElement('span', { class: 'an-context-icon', 'aria-hidden': 'true' });\n iconSpan.innerHTML = it.icon;\n headerBtn.appendChild(iconSpan);\n }\n headerBtn.appendChild(createElement('span', { class: 'an-context-label' }, [it.label || 'Insert Table']));\n const chevron = createElement('span', { class: 'an-context-chevron', 'aria-hidden': 'true' });\n chevron.innerHTML = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"9 18 15 12 9 6\"/></svg>`;\n headerBtn.appendChild(chevron);\n\n const panel = createElement('div', { class: 'an-context-table-grid-panel' });\n panel.style.display = 'none';\n\n const gridEl = createElement('div', { class: 'an-table-grid' });\n gridEl.style.gridTemplateColumns = `repeat(${GRID_COLS}, 16px)`;\n const labelEl = createElement('div', { class: 'an-table-label' });\n labelEl.textContent = 'Insert Table';\n\n const cells = [];\n for (let r = 1; r <= GRID_ROWS; r++) {\n for (let c = 1; c <= GRID_COLS; c++) {\n const cell = createElement('div', { class: 'an-table-cell', 'data-row': String(r), 'data-col': String(c) });\n cell.style.width = '16px';\n cell.style.height = '16px';\n cells.push(cell);\n gridEl.appendChild(cell);\n }\n }\n\n const setHighlight = (rows, cols) => {\n cells.forEach((cell) => {\n cell.classList.toggle('active', +cell.dataset.row <= rows && +cell.dataset.col <= cols);\n });\n labelEl.textContent = (rows && cols) ? `${cols} × ${rows}` : 'Insert Table';\n };\n\n panel.appendChild(gridEl);\n panel.appendChild(labelEl);\n\n let expanded = false;\n const offHeader = on(headerBtn, 'click', (e) => {\n e.stopPropagation();\n expanded = !expanded;\n panel.style.display = expanded ? '' : 'none';\n chevron.style.transform = expanded ? 'rotate(90deg)' : '';\n this._reposition();\n });\n this._menuDisposers.push(offHeader);\n\n const offMove = on(gridEl, 'mousemove', (e) => {\n const cell = e.target.closest('[data-row]');\n if (!cell) return;\n setHighlight(+cell.dataset.row, +cell.dataset.col);\n });\n const offLeave = on(gridEl, 'mouseleave', () => setHighlight(0, 0));\n const offClick = on(gridEl, 'click', (e) => {\n const cell = e.target.closest('[data-row]');\n if (!cell) return;\n const rows = +cell.dataset.row;\n const cols = +cell.dataset.col;\n const editable = this.context.layoutInfo && this.context.layoutInfo.editable;\n if (editable && this._savedRange) {\n editable.focus();\n const sel = window.getSelection();\n sel.removeAllRanges();\n sel.addRange(this._savedRange.cloneRange());\n }\n this.hide();\n this.context.invoke('editor.insertTable', cols, rows);\n });\n this._menuDisposers.push(offMove, offLeave, offClick);\n\n wrapper.appendChild(headerBtn);\n wrapper.appendChild(panel);\n this.el.appendChild(wrapper);\n return;\n }\n\n // Regular item\n const btn = createElement('button', { type: 'button', class: 'an-context-item', 'data-name': it.name || '' });\n if (typeof it.disabled === 'function' ? it.disabled(this.context) : !!it.disabled) btn.disabled = true;\n if (it.icon) {\n const iconSpan = createElement('span', { class: 'an-context-icon', 'aria-hidden': 'true' });\n iconSpan.innerHTML = it.icon;\n btn.appendChild(iconSpan);\n }\n btn.appendChild(createElement('span', { class: 'an-context-label' }, [it.label || it.name]));\n const off = on(btn, 'click', (e) => {\n e.stopPropagation();\n this.hide();\n try { it.action(this.context); } catch (err) { console.error(err); }\n });\n this._menuDisposers.push(off);\n this.el.appendChild(btn);\n });\n }\n\n _onContextMenu(event) {\n const editable = this.context.layoutInfo && this.context.layoutInfo.editable;\n if (!editable) return;\n if (!editable.contains(event.target)) return;\n event.preventDefault();\n this._lastX = event.clientX;\n this._lastY = event.clientY;\n const winSel = window.getSelection();\n this._savedRange = (winSel && winSel.rangeCount > 0) ? winSel.getRangeAt(0).cloneRange() : null;\n this._renderItems(this._items);\n this.showAt(event.clientX, event.clientY);\n }\n\n _maybeHide(event) {\n if (!this.el) return;\n if (!this.el.contains(event.target)) this.hide();\n }\n\n showAt(x, y) {\n if (!this.el) return;\n this.el.style.display = 'block';\n this._reposition(x, y);\n this.el.setAttribute('aria-hidden', 'false');\n }\n\n _reposition(x, y) {\n if (!this.el) return;\n const rx = x !== undefined ? x : this._lastX;\n const ry = y !== undefined ? y : this._lastY;\n const rect = this.el.getBoundingClientRect();\n let left = rx;\n let top = ry;\n if (left + rect.width > window.innerWidth) left = window.innerWidth - rect.width - 8;\n if (top + rect.height > window.innerHeight) top = window.innerHeight - rect.height - 8;\n this.el.style.left = `${left}px`;\n this.el.style.top = `${top}px`;\n }\n\n hide() {\n if (!this.el) return;\n this.el.style.display = 'none';\n this.el.setAttribute('aria-hidden', 'true');\n }\n\n // ---------------------------------------------------------------------------\n // Format operations (Copy Format / Paste Format / Remove Format)\n // ---------------------------------------------------------------------------\n\n /** Returns true if a format has been copied — used to disable Paste Format. */\n hasCopiedFormat() { return !!this._copiedFormat; }\n\n /** Snapshot inline styles at the selection anchor node. */\n copyFormat() {\n const range = this._savedRange;\n if (!range) return;\n const editable = this.context.layoutInfo && this.context.layoutInfo.editable;\n let node = range.startContainer;\n if (node.nodeType === Node.TEXT_NODE) node = node.parentElement;\n if (!node || !editable || !editable.contains(node)) return;\n\n // Walk up to collect explicitly-set inline properties from the nearest styled ancestor\n const cs = window.getComputedStyle(node);\n\n // Detect if an explicit font-family / font-size is set on an element (not just inherited)\n const explicitFontFamily = this._findExplicitStyle(node, editable, 'fontFamily');\n const explicitFontSize = this._findExplicitStyle(node, editable, 'fontSize');\n\n this._copiedFormat = {\n bold: parseInt(cs.fontWeight, 10) >= 700,\n italic: cs.fontStyle === 'italic' || cs.fontStyle === 'oblique',\n underline: (cs.textDecorationLine || '').includes('underline'),\n strikethrough: (cs.textDecorationLine || '').includes('line-through'),\n fontFamily: explicitFontFamily,\n fontSize: explicitFontSize,\n color: this._isDefaultColor(cs.color) ? null : cs.color,\n backgroundColor: cs.backgroundColor,\n };\n }\n\n /** Walk up the tree looking for a property explicitly set in inline style. Returns null if only inherited. */\n _findExplicitStyle(node, boundary, prop) {\n let el = node;\n while (el && el !== boundary && el !== document.body) {\n if (el.style && el.style[prop]) return el.style[prop];\n // also check font element attributes\n if (el.nodeName === 'FONT') {\n if (prop === 'fontFamily' && el.getAttribute('face')) return el.getAttribute('face');\n if (prop === 'fontSize' && el.getAttribute('size')) {\n // font size attribute is 1-7; skip these since we need px\n return null;\n }\n }\n el = el.parentElement;\n }\n return null;\n }\n\n /** Checks if a computed color looks like the default browser text color (black). */\n _isDefaultColor(color) {\n return !color || color === 'rgb(0, 0, 0)' || color === 'rgba(0, 0, 0, 0)' || color === 'transparent';\n }\n\n /** Apply the most-recently copied format to the saved selection. */\n pasteFormat() {\n if (!this._copiedFormat || !this._savedRange) return;\n const fmt = this._copiedFormat;\n const editable = this.context.layoutInfo && this.context.layoutInfo.editable;\n if (!editable) return;\n\n // CRITICAL: focus the editable FIRST, then restore selection.\n // Calling focus() after addRange() can wipe the selection in Chrome/Firefox.\n editable.focus();\n const sel = window.getSelection();\n sel.removeAllRanges();\n sel.addRange(this._savedRange.cloneRange());\n\n // Strip existing inline formatting so we start from a clean state.\n // After removeFormat, bold/italic/underline/strikethrough are guaranteed off.\n document.execCommand('removeFormat');\n\n // Apply each format positively — no toggle-check needed after removeFormat.\n if (fmt.bold) document.execCommand('bold');\n if (fmt.italic) document.execCommand('italic');\n if (fmt.underline) document.execCommand('underline');\n if (fmt.strikethrough) document.execCommand('strikeThrough');\n\n if (fmt.color) document.execCommand('foreColor', false, fmt.color);\n\n const isTransparent = (c) => !c || c === 'rgba(0, 0, 0, 0)' || c === 'transparent';\n if (!isTransparent(fmt.backgroundColor)) {\n document.execCommand('hiliteColor', false, fmt.backgroundColor);\n }\n\n // Font family — apply BEFORE font-size DOM manipulation so the selection is still intact.\n if (fmt.fontFamily) {\n document.execCommand('fontName', false, fmt.fontFamily);\n }\n\n // Font size — use a unique data-marker to avoid touching pre-existing font[size=\"7\"] nodes.\n if (fmt.fontSize) {\n const marker = `fs-${Date.now()}`;\n // Snapshot pre-existing font[size=\"7\"] BEFORE execCommand so we don't accidentally\n // replace nodes that were already in the document (the comment below was aspirational\n // but the original code never actually excluded them — this Set approach is the fix).\n const preExisting = new Set(editable.querySelectorAll('font[size=\"7\"]'));\n document.execCommand('fontSize', false, '7');\n // Mark only the NEWLY created font[size=\"7\"] elements.\n editable.querySelectorAll('font[size=\"7\"]').forEach((el) => {\n if (!preExisting.has(el)) el.setAttribute('data-an-tmp', marker);\n });\n editable.querySelectorAll(`[data-an-tmp=\"${marker}\"]`).forEach((el) => {\n const span = document.createElement('span');\n span.style.fontSize = fmt.fontSize;\n el.parentNode.insertBefore(span, el);\n while (el.firstChild) span.appendChild(el.firstChild);\n el.parentNode.removeChild(el);\n });\n }\n\n this.context.invoke('editor.afterCommand');\n }\n\n /** Strip all inline formatting from the saved selection. */\n removeFormat() {\n if (!this._savedRange) return;\n const editable = this.context.layoutInfo && this.context.layoutInfo.editable;\n if (!editable) return;\n\n editable.focus();\n const sel = window.getSelection();\n sel.removeAllRanges();\n sel.addRange(this._savedRange.cloneRange());\n\n document.execCommand('removeFormat');\n\n const range = sel.getRangeAt(0);\n const root = range.commonAncestorContainer;\n const rootEl = root.nodeType === Node.TEXT_NODE ? root.parentElement : root;\n const iter = document.createNodeIterator(rootEl, NodeFilter.SHOW_ELEMENT);\n let el;\n while ((el = iter.nextNode())) {\n if (!editable.contains(el) || el === editable) continue;\n try { if (range.intersectsNode(el)) el.removeAttribute('style'); } catch { /* ignore */ }\n }\n\n this.context.invoke('editor.afterCommand');\n }\n}\n\nexport default ContextMenu;\n","/**\n * ShortcutsDialog.js - Modal dialog listing all keyboard shortcuts.\n * Opened via the toolbar '?' button or Shift+? inside the editor.\n */\n\nimport { createElement, on, trapFocus } from '../core/dom.js';\n\nconst SHORTCUTS = [\n {\n category: 'Text Formatting',\n items: [\n { keys: 'Ctrl + B', action: 'Bold' },\n { keys: 'Ctrl + I', action: 'Italic' },\n { keys: 'Ctrl + U', action: 'Underline' },\n { keys: 'Ctrl + K', action: 'Insert / edit link' },\n ],\n },\n {\n category: 'History',\n items: [\n { keys: 'Ctrl + Z', action: 'Undo' },\n { keys: 'Ctrl + Y / Ctrl + Shift + Z', action: 'Redo' },\n ],\n },\n {\n category: 'Selection & Navigation',\n items: [\n { keys: 'Ctrl + A', action: 'Select all content' },\n { keys: 'Tab', action: 'Indent list item / insert spaces' },\n { keys: 'Shift + Tab', action: 'Outdent list item' },\n ],\n },\n {\n category: 'Clipboard',\n items: [\n { keys: 'Ctrl + Shift + V', action: 'Paste as plain text' },\n ],\n },\n {\n category: 'Find & Replace',\n items: [\n { keys: 'Ctrl + F', action: 'Find in document' },\n { keys: 'Ctrl + H', action: 'Find & Replace' },\n ],\n },\n {\n category: 'Editor',\n items: [\n { keys: 'Shift + ?', action: 'Show this keyboard shortcuts dialog' },\n ],\n },\n];\n\nexport class ShortcutsDialog {\n /** @param {import('../Context.js').Context} context */\n constructor(context) {\n this.context = context;\n this._dialog = null;\n this._closeBtn = null;\n this._disposers = [];\n }\n\n initialize() {\n this._dialog = this._buildDialog();\n document.body.appendChild(this._dialog);\n return this;\n }\n\n destroy() {\n this._disposers.forEach((d) => d());\n this._disposers = [];\n if (this._dialog && this._dialog.parentNode) {\n this._dialog.parentNode.removeChild(this._dialog);\n }\n this._dialog = null;\n }\n\n show() {\n if (this._dialog) {\n this._dialog.style.display = 'flex';\n this._removeTrap = trapFocus(this._dialog, () => this._close());\n setTimeout(() => this._closeBtn && this._closeBtn.focus(), 50);\n }\n }\n\n _close() {\n if (this._dialog) this._dialog.style.display = 'none';\n if (this._removeTrap) { this._removeTrap(); this._removeTrap = null; }\n }\n\n _buildDialog() {\n const overlay = createElement('div', {\n class: 'an-dialog-overlay',\n role: 'dialog',\n 'aria-modal': 'true',\n 'aria-label': 'Keyboard Shortcuts',\n });\n\n const box = createElement('div', { class: 'an-dialog-box an-shortcuts-box' });\n\n // Title row with close button\n const titleRow = createElement('div', { class: 'an-icon-title-row' });\n const title = createElement('h3', { class: 'an-dialog-title' });\n title.textContent = 'Keyboard Shortcuts';\n const closeBtn = createElement('button', {\n type: 'button',\n class: 'an-icon-close',\n 'aria-label': 'Close',\n });\n closeBtn.textContent = '×';\n this._closeBtn = closeBtn;\n titleRow.append(title, closeBtn);\n box.appendChild(titleRow);\n\n SHORTCUTS.forEach(({ category, items }) => {\n const catEl = createElement('div', { class: 'an-shortcuts-cat' });\n catEl.textContent = category;\n box.appendChild(catEl);\n\n const table = createElement('div', { class: 'an-shortcuts-table' });\n items.forEach(({ keys, action }) => {\n const row = createElement('div', { class: 'an-shortcuts-row' });\n const keyEl = createElement('span', { class: 'an-shortcuts-key' });\n keyEl.textContent = keys;\n const actEl = createElement('span', { class: 'an-shortcuts-action' });\n actEl.textContent = action;\n row.append(keyEl, actEl);\n table.appendChild(row);\n });\n box.appendChild(table);\n });\n\n overlay.appendChild(box);\n\n const d1 = on(closeBtn, 'click', () => this._close());\n const d2 = on(overlay, 'click', (e) => { if (e.target === overlay) this._close(); });\n this._disposers.push(d1, d2);\n\n return overlay;\n }\n}\n","/**\n * FindReplace.js - Find & Replace dialog\n *\n * Opens via Ctrl+F (find only) or Ctrl+H (find + replace).\n * Uses TreeWalker to locate text matches and wraps them with <mark> elements\n * for highlighting. Supports case-sensitive search, Prev/Next navigation and\n * single / replace-all replacement.\n */\n\nimport { createElement, on, trapFocus } from '../core/dom.js';\n\nexport class FindReplace {\n /** @param {import('../Context.js').Context} context */\n constructor(context) {\n this.context = context;\n\n /** @type {HTMLElement|null} */\n this._dialog = null;\n /** @type {HTMLInputElement|null} */\n this._findInput = null;\n /** @type {HTMLInputElement|null} */\n this._replaceInput = null;\n /** @type {HTMLInputElement|null} */\n this._caseCheckbox = null;\n /** @type {HTMLElement|null} */\n this._counterEl = null;\n /** @type {HTMLElement|null} */\n this._closeBtn = null;\n\n /** Live matches — each entry is { mark: HTMLElement } after highlighting */\n this._matches = [];\n this._currentIndex = -1;\n this._caseSensitive = false;\n /** @type {'find'|'replace'} */\n this._mode = 'find';\n\n this._disposers = [];\n this._removeTrap = null;\n this._focusTimer = null;\n }\n\n // ---------------------------------------------------------------------------\n // Lifecycle\n // ---------------------------------------------------------------------------\n\n initialize() {\n this._dialog = this._buildDialog();\n document.body.appendChild(this._dialog);\n return this;\n }\n\n destroy() {\n clearTimeout(this._focusTimer);\n this._focusTimer = null;\n this._clearHighlights();\n this._disposers.forEach((d) => d());\n this._disposers = [];\n if (this._dialog && this._dialog.parentNode) {\n this._dialog.parentNode.removeChild(this._dialog);\n }\n this._dialog = null;\n }\n\n // ---------------------------------------------------------------------------\n // Public API\n // ---------------------------------------------------------------------------\n\n /**\n * Opens the dialog in 'find' or 'replace' mode.\n * @param {'find'|'replace'} [mode='find']\n */\n show(mode = 'find') {\n this._mode = mode;\n this._updateMode();\n this._open();\n // Pre-select whatever was previously typed so the user can retype immediately\n clearTimeout(this._focusTimer);\n this._focusTimer = setTimeout(() => {\n if (this._findInput) {\n this._findInput.select();\n this._findInput.focus();\n }\n }, 50);\n }\n\n // ---------------------------------------------------------------------------\n // Open / close\n // ---------------------------------------------------------------------------\n\n _open() {\n if (!this._dialog) return;\n // If already visible, just focus the search input — don't re-trap.\n if (this._dialog.style.display === 'flex') {\n if (this._findInput) this._findInput.focus();\n return;\n }\n this._dialog.style.display = 'flex';\n // Release any previous trap before installing a new one.\n if (this._removeTrap) { this._removeTrap(); this._removeTrap = null; }\n this._removeTrap = trapFocus(this._dialog, () => this._close());\n }\n\n _close() {\n this._clearHighlights();\n if (this._dialog) this._dialog.style.display = 'none';\n if (this._removeTrap) { this._removeTrap(); this._removeTrap = null; }\n // Return focus to the editor\n this.context.invoke('editor.focus');\n }\n\n _updateMode() {\n if (!this._dialog) return;\n const replaceRow = this._dialog.querySelector('.an-fr-replace-row');\n const replaceActions = this._dialog.querySelector('.an-fr-replace-actions');\n const title = this._dialog.querySelector('.an-dialog-title');\n\n const isReplace = this._mode === 'replace';\n if (replaceRow) replaceRow.style.display = isReplace ? '' : 'none';\n if (replaceActions) replaceActions.style.display = isReplace ? '' : 'none';\n if (title) title.textContent = isReplace ? 'Find & Replace' : 'Find';\n }\n\n // ---------------------------------------------------------------------------\n // Build dialog\n // ---------------------------------------------------------------------------\n\n _buildDialog() {\n const overlay = createElement('div', {\n class: 'an-dialog-overlay an-fr-dialog',\n role: 'dialog',\n 'aria-modal': 'true',\n 'aria-label': 'Find and Replace',\n });\n const box = createElement('div', { class: 'an-dialog-box' });\n\n // ---- Title row ----\n const titleRow = createElement('div', { class: 'an-icon-title-row' });\n const title = createElement('h3', { class: 'an-dialog-title' });\n title.textContent = 'Find';\n const closeBtn = createElement('button', {\n type: 'button',\n class: 'an-icon-close',\n 'aria-label': 'Close',\n });\n closeBtn.textContent = '×';\n this._closeBtn = closeBtn;\n titleRow.append(title, closeBtn);\n box.appendChild(titleRow);\n\n // ---- Find row ----\n const findRow = createElement('div', { class: 'an-fr-find-row' });\n const findInput = createElement('input', {\n type: 'text',\n class: 'an-input',\n placeholder: 'Find…',\n 'aria-label': 'Search text',\n });\n this._findInput = findInput;\n findRow.appendChild(findInput);\n box.appendChild(findRow);\n\n // ---- Options row (case-sensitive toggle + match counter) ----\n const optRow = createElement('div', { class: 'an-fr-options-row' });\n const caseLabel = createElement('label', { class: 'an-label an-label-inline' });\n const caseCheckbox = createElement('input', {\n type: 'checkbox',\n 'aria-label': 'Case sensitive',\n });\n this._caseCheckbox = caseCheckbox;\n caseLabel.append(caseCheckbox, document.createTextNode('\\u00a0Case sensitive'));\n const counter = createElement('span', { class: 'an-fr-counter' });\n this._counterEl = counter;\n optRow.append(caseLabel, counter);\n box.appendChild(optRow);\n\n // ---- Find actions ----\n const findActions = createElement('div', { class: 'an-dialog-actions an-fr-find-actions' });\n const prevBtn = createElement('button', { type: 'button', class: 'an-btn' });\n prevBtn.textContent = '\\u2190 Prev';\n const nextBtn = createElement('button', { type: 'button', class: 'an-btn an-btn-primary' });\n nextBtn.textContent = 'Next \\u2192';\n findActions.append(prevBtn, nextBtn);\n box.appendChild(findActions);\n\n // ---- Replace row (hidden by default) ----\n const replaceRow = createElement('div', { class: 'an-fr-replace-row' });\n replaceRow.style.display = 'none';\n const replaceInput = createElement('input', {\n type: 'text',\n class: 'an-input',\n placeholder: 'Replace with\\u2026',\n 'aria-label': 'Replace with',\n });\n this._replaceInput = replaceInput;\n replaceRow.appendChild(replaceInput);\n box.appendChild(replaceRow);\n\n // ---- Replace actions (hidden by default) ----\n const replaceActions = createElement('div', { class: 'an-dialog-actions an-fr-replace-actions' });\n replaceActions.style.display = 'none';\n const replaceBtn = createElement('button', { type: 'button', class: 'an-btn' });\n replaceBtn.textContent = 'Replace';\n const replaceAllBtn = createElement('button', { type: 'button', class: 'an-btn an-btn-primary' });\n replaceAllBtn.textContent = 'Replace All';\n replaceActions.append(replaceBtn, replaceAllBtn);\n box.appendChild(replaceActions);\n\n overlay.appendChild(box);\n\n // ---- Event bindings ----\n const d1 = on(closeBtn, 'click', () => this._close());\n const d2 = on(overlay, 'click', (e) => { if (e.target === overlay) this._close(); });\n const d3 = on(findInput, 'input', () => this._onSearch());\n const d4 = on(caseCheckbox, 'change', () => {\n this._caseSensitive = caseCheckbox.checked;\n this._onSearch();\n });\n const d5 = on(nextBtn, 'click', () => this._next());\n const d6 = on(prevBtn, 'click', () => this._prev());\n const d7 = on(replaceBtn, 'click', () => this._replace());\n const d8 = on(replaceAllBtn, 'click', () => this._replaceAll());\n const d9 = on(findInput, 'keydown', (e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n e.shiftKey ? this._prev() : this._next();\n }\n });\n const d10 = on(replaceInput, 'keydown', (e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n this._replace();\n }\n });\n this._disposers.push(d1, d2, d3, d4, d5, d6, d7, d8, d9, d10);\n\n return overlay;\n }\n\n // ---------------------------------------------------------------------------\n // Search logic\n // ---------------------------------------------------------------------------\n\n _onSearch() {\n this._clearHighlights();\n const query = this._findInput ? this._findInput.value : '';\n if (!query) {\n this._updateCounter();\n return;\n }\n this._findAndHighlight(query);\n this._updateCounter();\n }\n\n /**\n * Finds all occurrences of `query` in the editable area text nodes,\n * then wraps each match in a <mark class=\"an-highlight\"> element.\n * Iterates text nodes in reverse so earlier offsets remain valid.\n * @param {string} query\n */\n _findAndHighlight(query) {\n const editable = this.context.layoutInfo.editable;\n if (!editable) return;\n\n // Collect raw matches: { node, start, end }\n const rawMatches = this._findRawMatches(query, editable);\n if (rawMatches.length === 0) return;\n\n this._currentIndex = 0;\n\n // Wrap in reverse order so earlier offsets in the same text node stay valid\n for (let i = rawMatches.length - 1; i >= 0; i--) {\n const { node, start, end } = rawMatches[i];\n try {\n const range = document.createRange();\n range.setStart(node, start);\n range.setEnd(node, end);\n const mark = document.createElement('mark');\n mark.className = 'an-highlight';\n range.surroundContents(mark);\n this._matches.unshift({ mark });\n } catch (_) {\n // surroundContents fails when the range crosses element boundaries.\n // This can happen with <br> inside matched text — skip safely.\n this._matches.unshift({ mark: null });\n }\n }\n\n // Drop entries where wrapping failed so the counter and navigation are accurate\n this._matches = this._matches.filter((m) => m.mark);\n if (this._matches.length === 0) return;\n\n // Highlight the first (current) match\n if (this._matches[0] && this._matches[0].mark) {\n this._matches[0].mark.className = 'an-highlight an-highlight-current';\n this._matches[0].mark.scrollIntoView({ block: 'center', behavior: 'smooth' });\n }\n }\n\n /**\n * Walks all text nodes under `root` and returns positional match descriptors.\n * @param {string} query\n * @param {HTMLElement} root\n * @returns {{ node: Text, start: number, end: number }[]}\n */\n _findRawMatches(query, root) {\n const results = [];\n const flags = this._caseSensitive ? 'g' : 'gi';\n // Escape regex special characters in the literal query string\n const escaped = query.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const re = new RegExp(escaped, flags);\n\n const walker = document.createTreeWalker(root, 0x4 /* NodeFilter.SHOW_TEXT */);\n let node;\n while ((node = walker.nextNode())) {\n re.lastIndex = 0;\n let m;\n while ((m = re.exec(node.textContent)) !== null) {\n results.push({ node, start: m.index, end: m.index + m[0].length });\n }\n }\n return results;\n }\n\n // ---------------------------------------------------------------------------\n // Navigation\n // ---------------------------------------------------------------------------\n\n _next() {\n if (this._matches.length === 0) return;\n this._currentIndex = (this._currentIndex + 1) % this._matches.length;\n this._scrollToMatch(this._currentIndex);\n this._updateCounter();\n }\n\n _prev() {\n if (this._matches.length === 0) return;\n this._currentIndex = (this._currentIndex - 1 + this._matches.length) % this._matches.length;\n this._scrollToMatch(this._currentIndex);\n this._updateCounter();\n }\n\n _scrollToMatch(index) {\n const match = this._matches[index];\n if (!match || !match.mark) return;\n // Update CSS classes\n this._matches.forEach((m, i) => {\n if (m.mark) {\n m.mark.className = i === index\n ? 'an-highlight an-highlight-current'\n : 'an-highlight';\n }\n });\n match.mark.scrollIntoView({ block: 'center', behavior: 'smooth' });\n }\n\n // ---------------------------------------------------------------------------\n // Replace\n // ---------------------------------------------------------------------------\n\n _replace() {\n if (this._matches.length === 0 || this._currentIndex < 0) return;\n const match = this._matches[this._currentIndex];\n if (!match || !match.mark || !match.mark.parentNode) return;\n\n const replacement = this._replaceInput ? this._replaceInput.value : '';\n const parent = match.mark.parentNode;\n const textNode = document.createTextNode(replacement);\n parent.insertBefore(textNode, match.mark);\n parent.removeChild(match.mark);\n parent.normalize();\n this.context.invoke('editor.afterCommand');\n const savedIndex = this._currentIndex;\n this._onSearch();\n if (this._matches.length > 0) {\n this._currentIndex = Math.min(savedIndex, this._matches.length - 1);\n this._scrollToMatch(this._currentIndex);\n this._updateCounter();\n }\n }\n\n _replaceAll() {\n if (this._matches.length === 0) return;\n const replacement = this._replaceInput ? this._replaceInput.value : '';\n\n this._matches.forEach(({ mark }) => {\n if (!mark || !mark.parentNode) return;\n const textNode = document.createTextNode(replacement);\n mark.parentNode.insertBefore(textNode, mark);\n mark.parentNode.removeChild(mark);\n });\n\n if (this.context.layoutInfo.editable) {\n this.context.layoutInfo.editable.normalize();\n }\n this._matches = [];\n this._currentIndex = -1;\n this.context.invoke('editor.afterCommand');\n this._onSearch();\n }\n\n // ---------------------------------------------------------------------------\n // Highlight management\n // ---------------------------------------------------------------------------\n\n /**\n * Removes all <mark class=\"an-highlight\"> elements from the editable area,\n * restoring the original text nodes via normalization.\n */\n _clearHighlights() {\n const editable = this.context.layoutInfo.editable;\n if (!editable) return;\n\n editable.querySelectorAll('mark.an-highlight').forEach((mark) => {\n const parent = mark.parentNode;\n if (!parent) return;\n while (mark.firstChild) parent.insertBefore(mark.firstChild, mark);\n parent.removeChild(mark);\n });\n // Merge adjacent text nodes after unwrapping\n editable.normalize();\n\n this._matches = [];\n this._currentIndex = -1;\n }\n\n // ---------------------------------------------------------------------------\n // Counter display\n // ---------------------------------------------------------------------------\n\n _updateCounter() {\n if (!this._counterEl) return;\n const total = this._matches.length;\n if (total === 0) {\n const query = this._findInput ? this._findInput.value : '';\n this._counterEl.textContent = query ? 'No results' : '';\n } else {\n this._counterEl.textContent = `${this._currentIndex + 1} / ${total}`;\n }\n }\n}\n","/**\n * Context.js - Central hub for the editor instance\n * Holds references to all sub-modules and manages inter-module communication.\n * Inspired by Summernote's Context.js\n */\n\nimport { mergeDeep } from './core/func.js';\nimport { defaultOptions } from './settings.js';\nimport { renderLayout } from './renderer.js';\nimport { on } from './core/dom.js';\n\n// Modules\nimport { Editor } from './module/Editor.js';\nimport { Toolbar } from './module/Toolbar.js';\nimport { Statusbar } from './module/Statusbar.js';\nimport { Clipboard } from './module/Clipboard.js';\nimport { Placeholder } from './module/Placeholder.js';\nimport { Codeview } from './module/Codeview.js';\nimport { Fullscreen } from './module/Fullscreen.js';\nimport { LinkDialog } from './module/LinkDialog.js';\nimport { ImageDialog } from './module/ImageDialog.js';\nimport { VideoDialog } from './module/VideoDialog.js';\nimport { ImageResizer } from './module/ImageResizer.js';\nimport { VideoResizer } from './module/VideoResizer.js';\nimport { LinkTooltip } from './module/LinkTooltip.js';\nimport { ImageTooltip } from './module/ImageTooltip.js';\nimport { VideoTooltip } from './module/VideoTooltip.js';\nimport { TableTooltip } from './module/TableTooltip.js';\nimport { CodeTooltip } from './module/CodeTooltip.js';\nimport { EmojiDialog } from './module/EmojiDialog.js';\nimport { IconDialog } from './module/IconDialog.js';\nimport { ContextMenu } from './module/ContextMenu.js';\nimport { ShortcutsDialog } from './module/ShortcutsDialog.js';\nimport { FindReplace } from './module/FindReplace.js';\n\n/** Module registry shared across all Context instances (populated via AutumnNote.registerModule). */\nexport const _customModules = new Map();\n\nexport class Context {\n /**\n * @param {HTMLElement} targetEl - The element to replace with the editor\n * @param {import('./settings.js').AsnOptions} [userOptions]\n */\n constructor(targetEl, userOptions = {}) {\n this.targetEl = targetEl;\n this.options = mergeDeep(defaultOptions, userOptions);\n\n /** @type {{ container: HTMLElement, editable: HTMLElement, toolbar?: HTMLElement, statusbar?: HTMLElement }} */\n this.layoutInfo = {};\n\n /** @type {Map<string, Function[]>} */\n this._listeners = new Map();\n\n /** @type {Map<string, object>} */\n this._modules = new Map();\n\n this._disposers = [];\n this._alive = false;\n }\n\n // ---------------------------------------------------------------------------\n // Initialisation\n // ---------------------------------------------------------------------------\n\n initialize() {\n // 1. Render the DOM skeleton\n const { container, editable } = renderLayout(this.targetEl, this.options);\n this.layoutInfo.container = container;\n this.layoutInfo.editable = editable;\n\n // 2. Register core modules\n this._registerModules();\n\n // 3. Attach toolbar/statusbar to container\n const toolbar = this._modules.get('toolbar');\n if (toolbar && toolbar.el) {\n container.insertBefore(toolbar.el, editable);\n this.layoutInfo.toolbar = toolbar.el;\n }\n\n const statusbar = this._modules.get('statusbar');\n if (statusbar && statusbar.el) {\n container.appendChild(statusbar.el);\n this.layoutInfo.statusbar = statusbar.el;\n }\n\n // 4. Bind editor-level events\n this._bindEditorEvents(editable);\n\n // 5. Auto-focus if requested\n if (this.options.focus) {\n editable.focus();\n }\n\n this._alive = true;\n\n // Initial toolbar sync so dropdowns show the correct font on load\n this.invoke('toolbar.refresh');\n\n if (typeof this.options.onInit === 'function') {\n this.options.onInit(this);\n }\n\n return this;\n }\n\n _registerModules() {\n const register = (name, ModuleClass) => {\n const instance = new ModuleClass(this);\n instance.initialize();\n this._modules.set(name, instance);\n };\n\n register('editor', Editor);\n register('toolbar', Toolbar);\n register('statusbar', Statusbar);\n register('clipboard', Clipboard);\n register('contextMenu', ContextMenu);\n register('placeholder', Placeholder);\n register('codeview', Codeview);\n register('fullscreen', Fullscreen);\n register('linkDialog', LinkDialog);\n register('imageDialog', ImageDialog);\n register('videoDialog', VideoDialog);\n register('imageResizer', ImageResizer);\n register('videoResizer', VideoResizer);\n register('linkTooltip', LinkTooltip);\n register('imageTooltip', ImageTooltip);\n register('videoTooltip', VideoTooltip);\n register('tableTooltip', TableTooltip);\n register('codeTooltip', CodeTooltip);\n register('emojiDialog', EmojiDialog);\n register('iconDialog', IconDialog);\n register('shortcutsDialog', ShortcutsDialog);\n register('findReplace', FindReplace);\n\n // Custom modules registered via AutumnNote.registerModule()\n for (const [name, ModuleClass] of _customModules) {\n register(name, ModuleClass);\n }\n }\n\n /**\n * Registers and initialises a custom module on this instance.\n * @param {string} name\n * @param {Function} ModuleClass\n * @returns {this}\n */\n registerModule(name, ModuleClass) {\n if (this._modules.has(name)) return this;\n const instance = new ModuleClass(this);\n instance.initialize();\n this._modules.set(name, instance);\n return this;\n }\n\n _bindEditorEvents(editable) {\n const d1 = on(editable, 'focus', () => {\n this.layoutInfo.container.classList.add('an-focused');\n if (typeof this.options.onFocus === 'function') {\n this.options.onFocus(this);\n }\n });\n const d2 = on(editable, 'blur', () => {\n this.layoutInfo.container.classList.remove('an-focused');\n this._syncToTarget();\n if (typeof this.options.onBlur === 'function') {\n this.options.onBlur(this);\n }\n });\n // Sync textarea/input value on every change so form.submit() always gets fresh content\n const d3 = this.on('change', () => this._syncToTarget());\n this._disposers.push(d1, d2, d3);\n\n // Auto-save to localStorage on every change\n if (this.options.autoSave && this.options.autoSaveKey) {\n const d4 = this.on('change', () => {\n try { localStorage.setItem(this.options.autoSaveKey, this.getHTML()); } catch (_) {}\n });\n this._disposers.push(d4);\n }\n }\n\n // ---------------------------------------------------------------------------\n // Module invocation\n // ---------------------------------------------------------------------------\n\n /**\n * Invokes a method on a registered module.\n * Format: 'moduleName.methodName'\n * @param {string} path - e.g. 'editor.bold'\n * @param {...*} args\n * @returns {*}\n */\n invoke(path, ...args) {\n const [moduleName, methodName] = path.split('.');\n const module = this._modules.get(moduleName);\n if (!module) {\n if (typeof process === 'undefined' || process.env?.NODE_ENV !== 'production') {\n console.warn(`[AutumnNote] invoke: module \"${moduleName}\" not found (path: \"${path}\")`);\n }\n return undefined;\n }\n if (typeof module[methodName] !== 'function') {\n if (typeof process === 'undefined' || process.env?.NODE_ENV !== 'production') {\n console.warn(`[AutumnNote] invoke: method \"${methodName}\" not found on module \"${moduleName}\" (path: \"${path}\")`);\n }\n return undefined;\n }\n return module[methodName](...args);\n }\n\n // ---------------------------------------------------------------------------\n // Event system\n // ---------------------------------------------------------------------------\n\n /**\n * Subscribes to an editor event.\n * @param {string} eventName\n * @param {Function} handler\n * @returns {() => void} unsubscribe\n */\n on(eventName, handler) {\n if (!this._listeners.has(eventName)) {\n this._listeners.set(eventName, []);\n }\n this._listeners.get(eventName).push(handler);\n return () => this.off(eventName, handler);\n }\n\n /**\n * Unsubscribes from an editor event.\n * @param {string} eventName\n * @param {Function} handler\n */\n off(eventName, handler) {\n const handlers = this._listeners.get(eventName);\n if (!handlers) return;\n const idx = handlers.indexOf(handler);\n if (idx !== -1) handlers.splice(idx, 1);\n }\n\n /**\n * Triggers an editor event.\n * @param {string} eventName\n * @param {...*} args\n */\n triggerEvent(eventName, ...args) {\n const handlers = this._listeners.get(eventName) || [];\n handlers.forEach((h) => h(...args));\n\n // Also call options callback if present (e.g. onChange)\n const cbName = 'on' + eventName.charAt(0).toUpperCase() + eventName.slice(1);\n if (typeof this.options[cbName] === 'function') {\n this.options[cbName](...args);\n }\n }\n\n // ---------------------------------------------------------------------------\n // Public editor API\n // ---------------------------------------------------------------------------\n\n /**\n * Returns the current HTML content of the editor.\n * @returns {string}\n */\n getHTML() {\n return this.invoke('editor.getHTML');\n }\n\n /**\n * Sets the HTML content of the editor.\n * @param {string} html\n */\n setHTML(html) {\n this.invoke('editor.setHTML', html);\n }\n\n /**\n * Returns the plain text content of the editor.\n * @returns {string}\n */\n getText() {\n return this.invoke('editor.getText');\n }\n\n /**\n * Sets the editor content as plain text (HTML-escaped).\n * @param {string} text\n */\n setText(text) {\n this.invoke('editor.setText', text);\n }\n\n /**\n * Clears the editor content.\n */\n clear() {\n this.invoke('editor.clear');\n }\n\n /**\n * Resets the undo/redo history stack.\n * Useful after programmatically loading a new document via setHTML() / setMarkdown()\n * so that Ctrl+Z cannot undo back to the previous document.\n */\n clearHistory() {\n this.invoke('editor.clearHistory');\n }\n\n /**\n * Returns true when the editor has no meaningful content.\n * @returns {boolean}\n */\n isEmpty() {\n return this.invoke('editor.isEmpty');\n }\n\n /**\n * Inserts HTML at the current cursor position.\n * @param {string} html\n */\n insertHTML(html) {\n this.invoke('editor.insertHTML', html);\n }\n\n /**\n * Inserts plain text at the current cursor position.\n * @param {string} text\n */\n insertText(text) {\n this.invoke('editor.insertText', text);\n }\n\n /**\n * Sets editor content from a Markdown string.\n * @param {string} md\n */\n setMarkdown(md) {\n this.invoke('editor.setMarkdown', md);\n }\n\n /**\n * Returns the editor content as Markdown.\n * @returns {string}\n */\n getMarkdown() {\n return this.invoke('editor.getMarkdown');\n }\n\n /**\n * Returns the current word count of the editor content.\n * @returns {number}\n */\n getWordCount() {\n return this.invoke('statusbar.getWordCount') ?? 0;\n }\n\n /**\n * Returns the current character count of the editor content.\n * @returns {number}\n */\n getCharCount() {\n return this.invoke('statusbar.getCharCount') ?? 0;\n }\n\n /**\n * Downloads the editor content as an HTML file.\n * @param {string} [filename='document.html']\n */\n downloadHTML(filename = 'document.html') {\n this._download(this.getHTML(), filename, 'text/html');\n }\n\n /**\n * Downloads the editor content as a plain-text file.\n * @param {string} [filename='document.txt']\n */\n downloadText(filename = 'document.txt') {\n this._download(this.getText(), filename, 'text/plain');\n }\n\n /**\n * Downloads the editor content as a Markdown file.\n * @param {string} [filename='document.md']\n */\n downloadMarkdown(filename = 'document.md') {\n this._download(this.getMarkdown(), filename, 'text/markdown');\n }\n\n /**\n * Creates a temporary Blob URL and triggers a browser file download.\n * @param {string} content\n * @param {string} filename\n * @param {string} mimeType\n */\n _download(content, filename, mimeType) {\n const blob = new Blob([content], { type: mimeType });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = filename;\n a.style.display = 'none';\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n URL.revokeObjectURL(url);\n }\n\n /**\n * Opens the editor content in a new window and triggers the browser print dialog.\n * @param {string} [title='']\n */\n print(title = '') {\n const content = this.getHTML();\n const safeTitle = (title || '').replace(/</g, '<').replace(/>/g, '>');\n const w = window.open('', '_blank');\n if (!w) return; // popup blocked by browser\n w.document.write(\n '<!DOCTYPE html><html lang=\"en\"><head><meta charset=\"utf-8\">' +\n `<title>${safeTitle}</title>` +\n '<style>' +\n 'body{font-family:system-ui,-apple-system,\"Segoe UI\",Roboto,Arial,sans-serif;font-size:14px;line-height:1.6;padding:20mm;color:#111827;}' +\n 'ul.an-checklist{list-style:none;padding-left:0;}' +\n 'ul.an-checklist li{padding-left:24px;position:relative;margin:2px 0;}' +\n 'ul.an-checklist li input[type=\"checkbox\"]{position:absolute;left:0;top:3px;}' +\n 'code{background:#f3f4f6;border-radius:3px;padding:.1em .35em;font-family:monospace;}' +\n 'pre{background:#f3f4f6;padding:.75em 1em;border-radius:4px;overflow-x:auto;}' +\n 'table{border-collapse:collapse;}td,th{border:1px solid #d1d5db;padding:4px 8px;}' +\n '</style>' +\n `</head><body>${content}</body></html>`,\n );\n w.document.close();\n w.onload = () => { w.print(); };\n }\n\n /**\n * Sets whether the editor is disabled (readonly).\n * @param {boolean} disabled\n */\n setDisabled(disabled) {\n const editable = this.layoutInfo.editable;\n if (disabled) {\n editable.setAttribute('contenteditable', 'false');\n this.layoutInfo.container.classList.add('an-disabled');\n } else {\n editable.setAttribute('contenteditable', 'true');\n this.layoutInfo.container.classList.remove('an-disabled');\n }\n }\n\n // ---------------------------------------------------------------------------\n // Destroy\n // ---------------------------------------------------------------------------\n\n /**\n * Completely removes the editor and restores the original element.\n */\n destroy() {\n if (!this._alive) return;\n\n this._modules.forEach((module) => {\n if (typeof module.destroy === 'function') module.destroy();\n });\n this._modules.clear();\n\n this._disposers.forEach((d) => d());\n this._disposers = [];\n\n const container = this.layoutInfo.container;\n if (container && container.parentNode) {\n // Restore original element\n this.targetEl.style.display = '';\n container.parentNode.removeChild(container);\n }\n\n if (typeof this.options.onDestroy === 'function') {\n this.options.onDestroy(this);\n }\n\n this._alive = false;\n this._listeners.clear();\n }\n\n // ---------------------------------------------------------------------------\n // Helpers\n // ---------------------------------------------------------------------------\n\n /**\n * Syncs editor HTML back into the original textarea/input for form submission.\n */\n _syncToTarget() {\n if (this.targetEl.tagName === 'TEXTAREA' || this.targetEl.tagName === 'INPUT') {\n this.targetEl.value = this.getHTML();\n }\n }\n}\n","/**\n * lists.js - Array/list utility helpers\n * Inspired by Summernote's lists.js\n */\n\n/**\n * Returns the last element of an array.\n * @template T\n * @param {T[]} arr\n * @returns {T|undefined}\n */\nexport function last(arr) {\n return arr[arr.length - 1];\n}\n\n/**\n * Returns the first element of an array.\n * @template T\n * @param {T[]} arr\n * @returns {T|undefined}\n */\nexport function first(arr) {\n return arr[0];\n}\n\n/**\n * Returns a new array without the last n items.\n * @template T\n * @param {T[]} arr\n * @param {number} [n=1]\n * @returns {T[]}\n */\nexport function initial(arr, n = 1) {\n return arr.slice(0, arr.length - n);\n}\n\n/**\n * Returns a new array without the first n items.\n * @template T\n * @param {T[]} arr\n * @param {number} [n=1]\n * @returns {T[]}\n */\nexport function tail(arr, n = 1) {\n return arr.slice(n);\n}\n\n/**\n * Returns a flattened (one level) array.\n * @template T\n * @param {T[][]} arr\n * @returns {T[]}\n */\nexport function flatten(arr) {\n return arr.reduce((acc, val) => acc.concat(val), []);\n}\n\n/**\n * Returns unique elements of an array (using Set).\n * @template T\n * @param {T[]} arr\n * @returns {T[]}\n */\nexport function unique(arr) {\n return [...new Set(arr)];\n}\n\n/**\n * Splits an array into chunks of size n.\n * @template T\n * @param {T[]} arr\n * @param {number} n\n * @returns {T[][]}\n */\nexport function chunk(arr, n) {\n const result = [];\n for (let i = 0; i < arr.length; i += n) {\n result.push(arr.slice(i, i + n));\n }\n return result;\n}\n\n/**\n * Groups array elements by a key function.\n * @template T\n * @param {T[]} arr\n * @param {(item: T) => string} keyFn\n * @returns {Record<string, T[]>}\n */\nexport function groupBy(arr, keyFn) {\n return arr.reduce((groups, item) => {\n const key = keyFn(item);\n if (!groups[key]) {\n groups[key] = [];\n }\n groups[key].push(item);\n return groups;\n }, {});\n}\n\n/**\n * Returns true if all elements satisfy the predicate.\n * @template T\n * @param {T[]} arr\n * @param {(item: T) => boolean} predicate\n * @returns {boolean}\n */\nexport function all(arr, predicate) {\n return arr.every(predicate);\n}\n\n/**\n * Returns true if any element satisfies the predicate.\n * @template T\n * @param {T[]} arr\n * @param {(item: T) => boolean} predicate\n * @returns {boolean}\n */\nexport function any(arr, predicate) {\n return arr.some(predicate);\n}\n","/**\n * env.js - Environment / browser detection\n * Inspired by Summernote's env.js\n */\n\nconst userAgent = navigator.userAgent;\n\nexport const env = {\n /** True if browser is Chrome */\n isChrome: /Chrome\\//.test(userAgent),\n /** True if browser is Firefox */\n isFF: /Firefox\\//.test(userAgent),\n /** True if browser is Safari (not Chrome) */\n isSafari: /^((?!chrome|android).)*safari/i.test(userAgent),\n /** True if browser is Edge (Chromium) */\n isEdge: /Edg\\//.test(userAgent),\n /** True if running on macOS */\n isMac: /Macintosh/.test(userAgent),\n /** True if running on mobile */\n isMobile: /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(userAgent),\n /** True if touch is supported */\n isTouch: 'ontouchstart' in window || navigator.maxTouchPoints > 0,\n /** Modifier key name depending on platform */\n modifierKey: /Macintosh/.test(userAgent) ? 'metaKey' : 'ctrlKey',\n};\n","/**\n * index.js - Public entry point for AutumnNote\n *\n * Usage (module):\n * import AutumnNote from 'autumnnote';\n * const editor = AutumnNote.create('#my-editor', { placeholder: 'Start typing…' });\n *\n * Usage (UMD / script tag):\n * const editor = AutumnNote.create('#my-editor');\n */\n\nimport '../styles/autumnnote.scss';\nimport { Context, _customModules } from './Context.js';\nimport { defaultOptions } from './settings.js';\n\n// Snapshot of factory defaults taken at module-load time (before any setDefaults() calls)\nconst _originalDefaults = { ...defaultOptions };\n\n// Re-export for tree-shaking / module consumers\nexport { Context } from './Context.js';\nexport { defaultOptions } from './settings.js';\nexport * from './core/dom.js';\nexport * from './core/range.js';\nexport * from './core/func.js';\nexport * from './core/key.js';\nexport * from './core/lists.js';\nexport * from './core/env.js';\nexport * from './core/sanitise.js';\nexport * from './module/Buttons.js';\n\n// ---------------------------------------------------------------------------\n// Main factory\n// ---------------------------------------------------------------------------\n\n/** @type {WeakMap<Element, Context>} */\nconst instances = new WeakMap();\n\nconst AutumnNote = {\n /**\n * Creates (or returns existing) editor instance on one or more elements.\n *\n * @param {string|Element|NodeList|Element[]} selector\n * @param {import('./settings.js').AsnOptions} [options]\n * @returns {Context|Context[]} single Context or array of Contexts\n */\n create(selector, options = {}) {\n const elements = resolveElements(selector);\n const ctxs = elements.map((el) => {\n if (instances.has(el)) return instances.get(el);\n const ctx = new Context(el, options);\n ctx.initialize();\n instances.set(el, ctx);\n return ctx;\n });\n return ctxs.length === 1 ? ctxs[0] : ctxs;\n },\n\n /**\n * Destroys the editor(s) on the given selector.\n * @param {string|Element|NodeList|Element[]} selector\n */\n destroy(selector) {\n resolveElements(selector).forEach((el) => {\n const ctx = instances.get(el);\n if (ctx) {\n ctx.destroy();\n instances.delete(el);\n }\n });\n },\n\n /**\n * Returns the Context instance for a given element (or null).\n * @param {string|Element} selector\n * @returns {Context|null}\n */\n getInstance(selector) {\n const el = typeof selector === 'string' ? document.querySelector(selector) : selector;\n return el ? instances.get(el) || null : null;\n },\n\n /** Returns a shallow copy of the default options (read-only snapshot). */\n get defaults() { return { ...defaultOptions }; },\n\n /** Merges properties into the global defaults, applied to all future instances. */\n setDefaults(overrides) { Object.assign(defaultOptions, overrides); },\n\n /** Restores global defaults to their original factory values. */\n resetDefaults() {\n Object.keys(defaultOptions).forEach((k) => delete defaultOptions[k]);\n Object.assign(defaultOptions, _originalDefaults);\n },\n\n /**\n * Registers a custom module to be included in every new editor instance.\n * @param {string} name - unique module key used for ctx.invoke() calls\n * @param {Function} ModuleClass - class with initialize() and optional destroy()\n */\n registerModule(name, ModuleClass) { _customModules.set(name, ModuleClass); },\n\n /** Library version */\n version: '1.0.1',\n};\n\n// ---------------------------------------------------------------------------\n// Helper\n// ---------------------------------------------------------------------------\n\n/**\n * @param {string|Element|NodeList|Element[]} selector\n * @returns {Element[]}\n */\nfunction resolveElements(selector) {\n if (typeof selector === 'string') {\n return Array.from(document.querySelectorAll(selector));\n }\n if (selector instanceof Element) {\n return [selector];\n }\n if (selector instanceof NodeList || Array.isArray(selector)) {\n return Array.from(selector);\n }\n return [];\n}\n\nexport default AutumnNote;\n"],"names":["clamp","val","min","max","debounce","fn","delay","timer","args","throttle","limit","lastCall","now","compose","fns","x","v","f","identity","isNil","isString","isFunction","mergeDeep","target","source","output","key","isPlainObject","rect2bnd","rect","ELEMENT_NODE","TEXT_NODE","isElement","node","isText","isVoid","isPara","isLi","isList","isTable","isInline","isEditable","isAnchor","isImage","closest","predicate","stopAt","cur","closestPara","editable","ancestors","result","children","prevElement","sibling","nextElement","createElement","tag","attrs","childNodes","el","k","child","remove","unwrap","parent","wrap","wrapper","insertAfter","newNode","refNode","nodeValue","isEmpty","outerHtml","placeCaret","range","sel","isInsideEditable","on","type","handler","options","trapFocus","container","onEscape","FOCUSABLE","getFocusable","e","els","first","last","WrappedRange","sc","so","ec","eo","ancestor","n","rects","fromNativeRange","currentRange","native","rangeFromElement","collapsedRange","offset","isSelectionInside","withSavedRange","saved","splitText","textNode","after","execCommand","cmd","value","bold","italic","underline","uEl","nativeState","strikethrough","superscript","subscript","foreColor","color","backColor","fontName","name","fontSize","size","span","formatBlock","tagName","justifyLeft","justifyCenter","justifyRight","justifyFull","indent","outdent","insertUnorderedList","insertOrderedList","lineHeight","BLOCK_TAGS","nearestBlock","block","blocks","iter","toggleInlineCode","codeEl","code","newRange","frag","isInlineCode","toggleChecklist","li","ul","text","p","nr","startNode","MARKER","newLi","cbEl","isInChecklist","btn","icon","tooltip","action","isActive","isDisabled","boldBtn","Style.bold","italicBtn","Style.italic","underlineBtn","Style.underline","strikeBtn","Style.strikethrough","superscriptBtn","Style.superscript","subscriptBtn","Style.subscript","alignLeftBtn","Style.justifyLeft","alignCenterBtn","Style.justifyCenter","alignRightBtn","Style.justifyRight","alignJustifyBtn","Style.justifyFull","ulBtn","Style.insertUnorderedList","olBtn","Style.insertOrderedList","indentBtn","Style.indent","outdentBtn","Style.outdent","undoBtn","_ctx","ctx","redoBtn","hrBtn","Style.execCommand","linkBtn","imageBtn","videoBtn","emojiBtn","iconBtn","tableBtn","rows","cols","fontSizeBtn","Style.fontSize","removeFormatBtn","directionBtn","next","fontFamilyBtn","Style.fontName","paragraphStyleBtn","Style.formatBlock","raw","lineHeightBtn","Style.lineHeight","BLOCKS","codeviewBtn","fullscreenBtn","shortcutsBtn","findBtn","findReplaceBtn","inlineCodeBtn","Style.isInlineCode","checklistBtn","Style.isInChecklist","printBtn","foreColorBtn","Style.foreColor","backColorBtn","Style.backColor","defaultToolbar","defaultOptions","PROHIBITED_TAGS","URL_ATTRS","TRUSTED_IFRAME_HOSTS","sanitiseHTML","html","allowIframes","doc","t","attr","isTrustedIframeSrc","src","trimmed","url","sanitiseUrl","allowData","renderLayout","targetEl","initialContent","defaultFont","History","count","walker","startOff","endNode","endOff","len","lastWalker","lastNode","images","point","index","match","token","current","tokenized","prev","createTable","opts","headerRow","table","thead","tr","c","th","bodyRows","tbody","r","td","insertTable","isKey","event","keyName","isModifier","handleKeydown","isFAIcon","isZwsAnchor","moveCaret","setFn","movingLeft","para","selI","videoWrapper","checkLi","nativeRange","afterRange","afterFrag","cb","cursorNode","htmlToMarkdown","_domToMd","inner","langMatch","lang","content","l","href","items","i","cellTexts","padRow","row","md","isMarkdown","markdownToHTML","lines","out","line","fenceMatch","codeLines","_esc","langAttr","_escAttr","hMatch","level","_inline","bqLines","headerCells","_parseTableRow","paraLines","_","alt","label","Editor","context","d","onKeydown","onInput","onBeforeInput","onSelChange","onCheckboxClick","fixChecklistCursor","caret","cp","anchorNode","maxChars","maxWords","chars","hasMedia","Style.toggleInlineCode","Style.toggleChecklist","openInNewTab","safeUrl","link","displayText","align","safeSrc","style","styleAttr","str","_faPageLevelReady","Toolbar","b","group","groupEl","btnDef","def","baseClass","faPrefix","S","popup","grid","cells","cell","isOpen","setHighlight","openPopup","closePopup","d1","d2","d3","d4","d5","PRESETS","currentColor","applyBtn","iconSvg","strip","arrowBtn","swatches","userSwatches","sw","customRow","colorInput","customLabel","savedRange","saveSelection","restoreSelection","popupMinW","left","applyColor","d2b","d3b","d6","onScrollResize","idx","cls","select","placeholderText","placeholder","item","isHeader","opt","disposer","selectedOpt","extra","classAttr","svgWrap","paths","svgMap","faMap","faName","links","btnMap","matched","_segmenter","_countWords","seg","_applyLimitClass","Statusbar","handle","info","startY","startH","containerEl","applyDelta","clientY","delta","MIN_EDITABLE","fixedH","sum","trueMin","onMouseMove","onMouseUp","onMouseDown","onTouchMove","touch","onTouchEnd","onTouchStart","updateDebounced","words","Clipboard","mutations","mutation","blobUrl","imgs","img","_m","cleaned","s","UNWRAP_TAGS","changed","KEEP_ATTRS","a","clipboardData","forcePlain","imageItems","files","isWordContent","isSocialContent","dt","imageFiles","maxBytes","file","message","dataUrl","blob","err","_a","header","b64","mime","binary","arr","resolve","objectUrl","width","height","canvas","reader","webp","y","pos","Placeholder","update","isFocused","Codeview","INLINE_RE","remaining","stripped","Fullscreen","LinkDialog","overlay","box","title","urlLabel","urlInput","textLabel","textInput","tabLabel","tabCheckbox","btnRow","insertBtn","cancelBtn","anchor","newTab","parsed","ImageDialog","altLabel","altInput","alignLabel","alignRow","radioId","radio","lbl","fileLabel","fileInput","maxSize","alignRadio","VideoDialog","hintEl","widthLabel","widthInput","d0","rawUrl","ytWatch","ytShort","ytShorts","vimeo","iframeTitle","escapedSrc","HANDLE_DEFS","ImageResizer","_resizeDebounce","onWindowResize","h","offsetParent","containerRect","top","startX","startW","aspectRatio","isCorner","_raf","onMove","me","clientX","dx","dy","maxW","newW","newH","onUp","VideoResizer","w","embed","ICONS","SHOW_DELAY","HIDE_DELAY","LinkTooltip","to","tipW","tipH","margin","u","display","ta","ImageTooltip","isDanger","figure","existing","cap","figcaption","VideoTooltip","shield","getVisualColIndex","visualIdx","getCellAtVisualCol","vIdx","getCellAfterVisualCol","TableTooltip","HIT","_nearCell","_nearEdge","_resizing","_edge","_startX","_startY","_startW","_startH","_colIdx","_colCells","_row","_table","_rafDocMove","_rafEditorMove","clearHover","onEditorMove","onRight","onBottom","onEditorDown","onDocMove","onDocUp","cellFromSel","position","colCount","newRow","refCells","ref","visualColIdx","refs","isHeaders","selected","rowSelected","popover","titleEl","body","inputEl","unitEl","actionsEl","isCol","tipRect","pw","ph","CodeTooltip","pre","wrapped","fromAttr","fromClass","original","isWrapped","applyPrism","br","cdn","themeHref","scriptSrc","existingScript","script","poll","EMOJI_CATS","EMOJI_LIST","EmojiDialog","titleRow","closeBtn","searchInput","catBar","allTab","id","tab","char","keywords","cat","query","q","matchCat","matchQuery","visible","empty","ICON_CATEGORIES","ICON_LIST","IconDialog","optRow","styleLabel","styleSelect","sizeLabel","sizeSelect","colorLabel","useColorLabel","useColorCb","preview","previewHint","d7","d8","d9","d10","d11","visibleCount","cellCat","matchesCat","matchesQuery","styleParts","iconEl","caretTextNode","caretOffset","caretRange","defaultItems","doInsert","clean","ContextMenu","it","backBtn","iconSpan","off","chevron","headerBtn","panel","gridEl","labelEl","expanded","offHeader","offMove","offLeave","offClick","winSel","rx","ry","cs","explicitFontFamily","explicitFontSize","boundary","prop","fmt","marker","preExisting","root","rootEl","SHORTCUTS","ShortcutsDialog","category","catEl","keys","keyEl","actEl","FindReplace","mode","replaceRow","replaceActions","isReplace","findRow","findInput","caseLabel","caseCheckbox","counter","findActions","prevBtn","nextBtn","replaceInput","replaceBtn","replaceAllBtn","rawMatches","start","end","mark","m","results","flags","escaped","re","replacement","savedIndex","total","_customModules","Context","userOptions","toolbar","statusbar","register","ModuleClass","instance","path","_b","moduleName","methodName","module","eventName","handlers","cbName","filename","mimeType","safeTitle","disabled","initial","tail","flatten","acc","unique","chunk","groupBy","keyFn","groups","all","any","userAgent","env","_originalDefaults","instances","AutumnNote","selector","ctxs","resolveElements","overrides"],"mappings":"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"}
|