@azlib/editor 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/core/errors.ts","../src/core/commandDiagnostics.ts","../src/core/formattingCommands.ts","../src/core/commands.ts","../src/core/history.ts","../src/transforms/html.ts","../src/transforms/diagnostics.ts","../src/transforms/importFallback.ts","../src/transforms/markdown.ts","../src/transforms/representationSwitch.ts","../src/core/createEditor.ts","../src/core/schema.ts","../src/core/toolbarModel.ts","../src/rich-text/mountEditor.ts","../src/adapters/dom/createDomAdapter.ts","../src/adapters/react/useEditorAdapter.tsx"],"sourcesContent":["import type { EditorErrorEnvelope, RepresentationDiagnostic } from \"./types\";\n\nexport const createDiagnostic = (\n code: string,\n severity: RepresentationDiagnostic[\"severity\"],\n message: string,\n location?: RepresentationDiagnostic[\"location\"],\n): RepresentationDiagnostic => ({\n code,\n severity,\n message,\n location,\n});\n\nexport const createRecoverableError = (\n code: string,\n message: string,\n details?: Record<string, unknown>,\n): EditorErrorEnvelope => ({\n code,\n message,\n severity: \"warning\",\n recoverable: true,\n details,\n});\n\nexport const createFatalError = (\n code: string,\n message: string,\n details?: Record<string, unknown>,\n): EditorErrorEnvelope => ({\n code,\n message,\n severity: \"error\",\n recoverable: false,\n details,\n});\n","import { createDiagnostic } from \"./errors\";\nimport type { RepresentationDiagnostic } from \"./types\";\n\nexport const createUnknownCommandDiagnostic = (commandName: string): RepresentationDiagnostic =>\n createDiagnostic(\"UNKNOWN_COMMAND\", \"warning\", `Command '${commandName}' is not available in current editor capabilities.`);\n\nexport const createNoHistoryDiagnostic = (type: \"undo\" | \"redo\"): RepresentationDiagnostic =>\n createDiagnostic(\"NO_HISTORY\", \"info\", `No ${type} history entry is available for this editor session.`);\n","import type { EditorCommandHandler } from \"./commands\";\n\nconst withCommandMetadata = (commandName: string): EditorCommandHandler => ({ document }) => ({\n document: {\n ...document,\n revision: document.revision + 1,\n metadata: {\n ...document.metadata,\n lastCommand: commandName,\n },\n },\n});\n\nexport const createFormattingCommandHandlers = (): Record<string, EditorCommandHandler> => ({\n bold: withCommandMetadata(\"bold\"),\n italic: withCommandMetadata(\"italic\"),\n underline: withCommandMetadata(\"underline\"),\n heading: withCommandMetadata(\"heading\"),\n list: withCommandMetadata(\"list\"),\n align: withCommandMetadata(\"align\"),\n link: withCommandMetadata(\"link\"),\n});\n","import { createUnknownCommandDiagnostic } from \"./commandDiagnostics\";\nimport { createFormattingCommandHandlers } from \"./formattingCommands\";\nimport type { EditorDocument, RepresentationDiagnostic } from \"./types\";\n\nexport interface EditorCommandContext {\n document: EditorDocument;\n}\n\nexport interface EditorCommandOutcome {\n document: EditorDocument;\n diagnostics?: RepresentationDiagnostic[];\n}\n\nexport type EditorCommandHandler = (\n context: EditorCommandContext,\n params?: Record<string, unknown>,\n) => EditorCommandOutcome;\n\nexport type EditorCommandRegistry = Map<string, EditorCommandHandler>;\n\nexport const createCommandRegistry = (capabilities?: string[]): EditorCommandRegistry => {\n const allowed = new Set(capabilities && capabilities.length > 0 ? capabilities : [\"bold\", \"italic\", \"underline\", \"heading\", \"list\", \"align\", \"link\", \"undo\", \"redo\"]);\n\n const registry: EditorCommandRegistry = new Map();\n const formattingHandlers = createFormattingCommandHandlers();\n\n const registerIfAllowed = (name: string, handler: EditorCommandHandler) => {\n if (allowed.has(name)) {\n registry.set(name, handler);\n }\n };\n\n Object.entries(formattingHandlers).forEach(([commandName, handler]) => {\n registerIfAllowed(commandName, handler);\n });\n\n return registry;\n};\n\nexport const executeCommand = (\n registry: EditorCommandRegistry,\n commandName: string,\n context: EditorCommandContext,\n params?: Record<string, unknown>,\n): EditorCommandOutcome => {\n const handler = registry.get(commandName);\n\n if (!handler) {\n return {\n document: context.document,\n diagnostics: [createUnknownCommandDiagnostic(commandName)],\n };\n }\n\n return handler(context, params);\n};\n","import type { EditorDocument } from \"./types\";\n\nexport class EditorHistory {\n private readonly undoStack: EditorDocument[] = [];\n\n private readonly redoStack: EditorDocument[] = [];\n\n public record(snapshot: EditorDocument): void {\n this.undoStack.push(snapshot);\n this.redoStack.length = 0;\n }\n\n public undo(current: EditorDocument): EditorDocument {\n const previous = this.undoStack.pop();\n\n if (!previous) {\n return current;\n }\n\n this.redoStack.push(current);\n\n return {\n ...previous,\n revision: current.revision + 1,\n metadata: {\n ...previous.metadata,\n lastCommand: \"undo\",\n },\n };\n }\n\n public redo(current: EditorDocument): EditorDocument {\n const next = this.redoStack.pop();\n\n if (!next) {\n return current;\n }\n\n this.undoStack.push(current);\n\n return {\n ...next,\n revision: current.revision + 1,\n metadata: {\n ...next.metadata,\n lastCommand: \"redo\",\n },\n };\n }\n}\n","import DOMPurify from \"isomorphic-dompurify\";\n\nimport { createDiagnostic } from \"../core/errors\";\nimport type { RepresentationDiagnostic } from \"../core/types\";\n\nconst stripHtml = (value: string): string => value.replace(/<[^>]*>/g, \" \").replace(/\\s+/g, \" \").trim();\n\nconst allowedStyleProperties = new Set([\"font-family\", \"font-size\", \"text-align\", \"margin-left\"]);\n\nconst normalizeStyleValue = (property: string, value: string): string | null => {\n const next = value.trim().toLowerCase();\n\n if (property === \"font-family\") {\n return next === \"serif\" || next === \"monospace\" ? next : null;\n }\n\n if (property === \"font-size\") {\n return [\"12px\", \"16px\", \"20px\", \"28px\"].includes(next) ? next : null;\n }\n\n if (property === \"text-align\") {\n return [\"left\", \"center\", \"right\", \"justify\"].includes(next) ? next : null;\n }\n\n if (property === \"margin-left\") {\n const match = /^([0-9]{1,3})px$/.exec(next);\n\n if (!match) {\n return null;\n }\n\n const amount = Number.parseInt(match[1], 10);\n return amount >= 0 && amount % 24 === 0 ? `${amount}px` : null;\n }\n\n return null;\n};\n\nconst normalizeStyleAttribute = (styleValue: string): string | null => {\n const entries = styleValue\n .split(\";\")\n .map((entry) => entry.trim())\n .filter((entry) => entry.length > 0)\n .map((entry) => {\n const separator = entry.indexOf(\":\");\n\n if (separator < 0) {\n return null;\n }\n\n const property = entry.slice(0, separator).trim().toLowerCase();\n const value = entry.slice(separator + 1).trim();\n\n if (!allowedStyleProperties.has(property)) {\n return null;\n }\n\n const normalized = normalizeStyleValue(property, value);\n\n if (!normalized) {\n return null;\n }\n\n return `${property}:${normalized}`;\n })\n .filter((entry): entry is string => Boolean(entry));\n\n if (entries.length === 0) {\n return null;\n }\n\n return entries.join(\";\");\n};\n\nconst normalizeHtml = (value: string): string => {\n if (typeof DOMParser === \"undefined\") {\n return value.trim().length > 0 ? value : \"<p></p>\";\n }\n\n const parser = new DOMParser();\n const doc = parser.parseFromString(`<div>${value}</div>`, \"text/html\");\n const root = doc.body.firstElementChild;\n\n if (!root) {\n return \"<p></p>\";\n }\n\n root.querySelectorAll(\"b\").forEach((element) => {\n const replacement = doc.createElement(\"strong\");\n replacement.innerHTML = element.innerHTML;\n element.replaceWith(replacement);\n });\n\n root.querySelectorAll(\"i\").forEach((element) => {\n const replacement = doc.createElement(\"em\");\n replacement.innerHTML = element.innerHTML;\n element.replaceWith(replacement);\n });\n\n root.querySelectorAll(\"strike\").forEach((element) => {\n const replacement = doc.createElement(\"s\");\n replacement.innerHTML = element.innerHTML;\n element.replaceWith(replacement);\n });\n\n root.querySelectorAll(\"*\").forEach((element) => {\n const tag = element.tagName.toLowerCase();\n\n Array.from(element.attributes).forEach((attribute) => {\n const name = attribute.name.toLowerCase();\n const valueAttr = attribute.value;\n\n if (name === \"style\") {\n const normalized = normalizeStyleAttribute(valueAttr);\n\n if (normalized) {\n element.setAttribute(\"style\", normalized);\n } else {\n element.removeAttribute(\"style\");\n }\n\n return;\n }\n\n if (name === \"href\" || name === \"src\") {\n if (!/^(https?:|mailto:|tel:)/i.test(valueAttr.trim())) {\n element.removeAttribute(attribute.name);\n }\n\n return;\n }\n\n if (name === \"target\" || name === \"rel\" || name === \"alt\" || name === \"data-formula\" || name === \"controls\" || name === \"dir\") {\n return;\n }\n\n element.removeAttribute(attribute.name);\n });\n\n if (tag === \"a\") {\n element.setAttribute(\"rel\", \"noopener noreferrer\");\n element.setAttribute(\"target\", \"_blank\");\n }\n\n if (tag === \"video\") {\n element.setAttribute(\"controls\", \"true\");\n }\n });\n\n Array.from(root.childNodes).forEach((node) => {\n if (node.nodeType === Node.TEXT_NODE && (node.textContent?.trim().length ?? 0) > 0) {\n const paragraph = doc.createElement(\"p\");\n paragraph.textContent = node.textContent ?? \"\";\n root.replaceChild(paragraph, node);\n }\n });\n\n const normalized = root.innerHTML.trim();\n return normalized.length > 0 ? normalized : \"<p></p>\";\n};\n\nexport interface HtmlImportResult {\n richText: string;\n sanitizedHtml: string;\n diagnostics: RepresentationDiagnostic[];\n}\n\nexport const sanitizeHtml = (payload: string): string =>\n DOMPurify.sanitize(payload, {\n ALLOWED_TAGS: [\n \"p\",\n \"br\",\n \"b\",\n \"i\",\n \"strike\",\n \"strong\",\n \"em\",\n \"u\",\n \"s\",\n \"code\",\n \"pre\",\n \"blockquote\",\n \"h1\",\n \"h2\",\n \"ul\",\n \"ol\",\n \"li\",\n \"a\",\n \"img\",\n \"video\",\n \"span\",\n \"sub\",\n \"sup\",\n \"div\",\n ],\n ALLOWED_ATTR: [\"href\", \"src\", \"alt\", \"target\", \"rel\", \"style\", \"data-formula\", \"controls\", \"dir\"],\n FORBID_TAGS: [\"script\", \"style\", \"iframe\", \"object\", \"embed\", \"form\", \"input\", \"button\", \"textarea\", \"select\"],\n });\n\nexport const importHtml = (payload: string): HtmlImportResult => {\n const diagnostics: RepresentationDiagnostic[] = [];\n const sanitized = sanitizeHtml(payload);\n const normalized = normalizeHtml(sanitized);\n\n if (normalized !== payload) {\n diagnostics.push(\n createDiagnostic(\n \"SANITIZED_CONTENT\",\n \"warning\",\n \"Input HTML was sanitized to remove unsupported or unsafe markup.\",\n ),\n );\n }\n\n if (normalized.trim().length === 0) {\n diagnostics.push(createDiagnostic(\"EMPTY_HTML\", \"info\", \"The provided HTML content is empty after normalization.\"));\n }\n\n return {\n richText: stripHtml(normalized),\n sanitizedHtml: normalized,\n diagnostics,\n };\n};\n\nexport const exportHtml = (richText: string): string => {\n const escaped = richText\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\\n/g, \"<br>\");\n\n return normalizeHtml(`<p>${escaped}</p>`);\n};\n\nexport { normalizeHtml };\n","import { createDiagnostic } from \"../core/errors\";\nimport type { RepresentationDiagnostic } from \"../core/types\";\n\nexport const createUnsupportedMarkupDiagnostic = (details?: string): RepresentationDiagnostic =>\n createDiagnostic(\n \"UNSUPPORTED_MARKUP\",\n \"warning\",\n details ?? \"Some markup could not be fully represented and was normalized.\",\n );\n\nexport const createRecoverableParseDiagnostic = (format: \"markdown\" | \"html\", details?: string): RepresentationDiagnostic =>\n createDiagnostic(\n \"RECOVERABLE_PARSE\",\n \"warning\",\n details ?? `Some ${format.toUpperCase()} content was partially recovered during import.`,\n );\n","import type { EditorDocument, EditorInput, RepresentationDiagnostic } from \"../core/types\";\n\nimport { createRecoverableParseDiagnostic, createUnsupportedMarkupDiagnostic } from \"./diagnostics\";\n\nexport const applyImportFallback = (\n input: EditorInput,\n base: EditorDocument,\n): { document: EditorDocument; diagnostics: RepresentationDiagnostic[] } => {\n const payload = input.payload.trim();\n const diagnostics: RepresentationDiagnostic[] = [\n createRecoverableParseDiagnostic(input.format === \"html\" ? \"html\" : \"markdown\"),\n ];\n\n const stripped = input.format === \"html\" ? payload.replace(/<[^>]*>/g, \" \").replace(/\\s+/g, \" \").trim() : payload;\n\n if (stripped.length === 0) {\n diagnostics.push(createUnsupportedMarkupDiagnostic(\"Input produced no recoverable text content after normalization.\"));\n }\n\n return {\n document: {\n ...base,\n content: {\n richText: stripped,\n html: input.format === \"html\" ? payload : base.content.html,\n },\n metadata: {\n ...base.metadata,\n importFallback: true,\n },\n },\n diagnostics,\n };\n};\n","import { createDiagnostic } from \"../core/errors\";\nimport type { RepresentationDiagnostic } from \"../core/types\";\n\nconst normalizeMarkdown = (value: string) => value.replace(/\\r\\n?/g, \"\\n\");\n\nexport interface MarkdownImportResult {\n richText: string;\n diagnostics: RepresentationDiagnostic[];\n}\n\nexport const importMarkdown = (payload: string): MarkdownImportResult => {\n const diagnostics: RepresentationDiagnostic[] = [];\n const normalized = normalizeMarkdown(payload);\n\n if (normalized.trim().length === 0) {\n diagnostics.push(createDiagnostic(\"EMPTY_MARKDOWN\", \"info\", \"The provided markdown content is empty.\"));\n }\n\n return {\n richText: normalized,\n diagnostics,\n };\n};\n\nexport const exportMarkdown = (richText: string): string => normalizeMarkdown(richText);\n","import type { ContentFormat, EditorDocument, EditorExport, EditorInput, RepresentationDiagnostic } from \"../core/types\";\n\nimport { exportHtml, importHtml, normalizeHtml } from \"./html\";\nimport { applyImportFallback } from \"./importFallback\";\nimport { exportMarkdown, importMarkdown } from \"./markdown\";\n\nexport interface ImportResult {\n document: EditorDocument;\n diagnostics: RepresentationDiagnostic[];\n}\n\nexport const importRepresentation = (input: EditorInput, base: EditorDocument): ImportResult => {\n if (input.format === \"rich\") {\n const normalizedHtml = normalizeHtml(exportHtml(input.payload));\n\n return {\n document: {\n ...base,\n content: {\n richText: input.payload,\n html: normalizedHtml,\n },\n },\n diagnostics: [],\n };\n }\n\n if (input.format === \"markdown\") {\n try {\n const result = importMarkdown(input.payload);\n\n return {\n document: {\n ...base,\n content: {\n richText: result.richText,\n },\n metadata: {\n ...base.metadata,\n importedFrom: \"markdown\",\n },\n },\n diagnostics: result.diagnostics,\n };\n } catch {\n return applyImportFallback(input, base);\n }\n }\n\n try {\n const result = importHtml(input.payload);\n\n return {\n document: {\n ...base,\n content: {\n richText: result.richText,\n html: result.sanitizedHtml,\n },\n metadata: {\n ...base.metadata,\n importedFrom: \"html\",\n },\n },\n diagnostics: result.diagnostics,\n };\n } catch {\n return applyImportFallback(input, base);\n }\n};\n\nexport const exportRepresentation = (document: EditorDocument, format: ContentFormat): EditorExport => {\n if (format === \"rich\") {\n return {\n format,\n payload: document.content.richText,\n diagnostics: [],\n };\n }\n\n if (format === \"markdown\") {\n return {\n format,\n payload: exportMarkdown(document.content.richText),\n diagnostics: [],\n };\n }\n\n const htmlPayload = document.content.html\n ? normalizeHtml(document.content.html)\n : normalizeHtml(exportHtml(document.content.richText));\n\n return {\n format,\n payload: htmlPayload,\n diagnostics: [],\n };\n};\n","import { createCommandRegistry, executeCommand } from \"./commands\";\nimport { createNoHistoryDiagnostic } from \"./commandDiagnostics\";\nimport { createRecoverableError } from \"./errors\";\nimport { EditorHistory } from \"./history\";\nimport type { CommandResult, ContentFormat, EditorConfig, EditorDocument, EditorExport, EditorInput, EditorInstance, RepresentationDiagnostic } from \"./types\";\nimport { exportRepresentation, importRepresentation } from \"../transforms/representationSwitch\";\n\nconst createDefaultDocument = (): EditorDocument => ({\n id: crypto.randomUUID(),\n content: {\n richText: \"\",\n },\n metadata: {},\n revision: 0,\n});\n\nconst fromInput = (input: EditorInput, base: EditorDocument): { document: EditorDocument; diagnostics: RepresentationDiagnostic[] } =>\n importRepresentation(input, base);\n\nconst toExport = (document: EditorDocument, format: ContentFormat): EditorExport =>\n exportRepresentation(document, format);\n\nexport const createEditor = (config: EditorConfig = {}): EditorInstance => {\n const registry = createCommandRegistry(config.commandCapabilities);\n const history = new EditorHistory();\n let mountedTarget: Element | null = null;\n let isDestroyed = false;\n let currentDocument = createDefaultDocument();\n\n if (config.initialContent) {\n const initialized = fromInput(config.initialContent, currentDocument);\n currentDocument = initialized.document;\n\n if (initialized.diagnostics.length > 0) {\n config.onError?.(\n createRecoverableError(\"INITIAL_CONTENT_DIAGNOSTIC\", \"Initial content was normalized during editor initialization.\", {\n diagnostics: initialized.diagnostics,\n }),\n );\n }\n }\n\n const ensureActive = (): boolean => {\n if (!isDestroyed) {\n return true;\n }\n\n config.onError?.(createRecoverableError(\"EDITOR_DESTROYED\", \"This editor instance has already been destroyed.\"));\n return false;\n };\n\n const emitChange = () => {\n config.onChange?.(currentDocument);\n };\n\n return {\n getDocument: () => currentDocument,\n\n execute: (commandName, params) => {\n if (!ensureActive()) {\n return {\n ok: false,\n document: currentDocument,\n diagnostics: [],\n };\n }\n\n const result = executeCommand(registry, commandName, { document: currentDocument }, params);\n\n if (commandName === \"undo\") {\n const next = history.undo(currentDocument);\n\n if (next === currentDocument) {\n return {\n ok: false,\n document: currentDocument,\n diagnostics: [createNoHistoryDiagnostic(\"undo\")],\n };\n }\n\n currentDocument = next;\n emitChange();\n\n return {\n ok: true,\n document: currentDocument,\n diagnostics: [],\n };\n }\n\n if (commandName === \"redo\") {\n const next = history.redo(currentDocument);\n\n if (next === currentDocument) {\n return {\n ok: false,\n document: currentDocument,\n diagnostics: [createNoHistoryDiagnostic(\"redo\")],\n };\n }\n\n currentDocument = next;\n emitChange();\n\n return {\n ok: true,\n document: currentDocument,\n diagnostics: [],\n };\n }\n\n history.record(currentDocument);\n currentDocument = result.document;\n emitChange();\n\n return {\n ok: (result.diagnostics?.length ?? 0) === 0,\n document: currentDocument,\n diagnostics: result.diagnostics ?? [],\n };\n },\n\n export: (format) => toExport(currentDocument, format),\n\n import: (input) => {\n if (!ensureActive()) {\n return {\n ok: false,\n document: currentDocument,\n diagnostics: [],\n };\n }\n\n const result = fromInput(input, {\n ...currentDocument,\n revision: currentDocument.revision + 1,\n });\n\n currentDocument = result.document;\n emitChange();\n\n return {\n ok: result.diagnostics.length === 0,\n document: currentDocument,\n diagnostics: result.diagnostics,\n };\n },\n\n mount: (target) => {\n if (!ensureActive()) {\n return;\n }\n\n mountedTarget = target;\n },\n\n unmount: () => {\n mountedTarget = null;\n },\n\n destroy: () => {\n mountedTarget = null;\n isDestroyed = true;\n },\n };\n};\n","import { Schema } from \"prosemirror-model\";\n\nexport const editorNodeNames = {\n doc: \"doc\",\n paragraph: \"paragraph\",\n heading: \"heading\",\n text: \"text\",\n bulletList: \"bullet_list\",\n orderedList: \"ordered_list\",\n listItem: \"list_item\",\n hardBreak: \"hard_break\",\n} as const;\n\nexport const editorMarkNames = {\n strong: \"strong\",\n em: \"em\",\n underline: \"underline\",\n link: \"link\",\n} as const;\n\nexport const createEditorSchema = () =>\n new Schema({\n nodes: {\n doc: { content: \"block+\" },\n paragraph: {\n content: \"inline*\",\n group: \"block\",\n parseDOM: [{ tag: \"p\" }],\n toDOM: () => [\"p\", 0],\n },\n heading: {\n attrs: { level: { default: 1 } },\n content: \"inline*\",\n group: \"block\",\n defining: true,\n parseDOM: [{ tag: \"h1\", attrs: { level: 1 } }, { tag: \"h2\", attrs: { level: 2 } }, { tag: \"h3\", attrs: { level: 3 } }],\n toDOM: (node) => [`h${Math.max(1, Math.min(3, Number(node.attrs.level) || 1))}`, 0],\n },\n bullet_list: {\n content: \"list_item+\",\n group: \"block\",\n parseDOM: [{ tag: \"ul\" }],\n toDOM: () => [\"ul\", 0],\n },\n ordered_list: {\n attrs: { order: { default: 1 } },\n content: \"list_item+\",\n group: \"block\",\n parseDOM: [\n {\n tag: \"ol\",\n getAttrs: (dom) => {\n if (!(dom instanceof HTMLOListElement)) {\n return { order: 1 };\n }\n\n return { order: dom.start || 1 };\n },\n },\n ],\n toDOM: (node) => [\"ol\", { start: node.attrs.order || 1 }, 0],\n },\n list_item: {\n content: \"paragraph block*\",\n parseDOM: [{ tag: \"li\" }],\n toDOM: () => [\"li\", 0],\n },\n text: { group: \"inline\" },\n hard_break: {\n inline: true,\n group: \"inline\",\n selectable: false,\n parseDOM: [{ tag: \"br\" }],\n toDOM: () => [\"br\"],\n },\n },\n marks: {\n strong: {\n parseDOM: [{ tag: \"strong\" }, { tag: \"b\", getAttrs: () => null }],\n toDOM: () => [\"strong\", 0],\n },\n em: {\n parseDOM: [{ tag: \"em\" }, { tag: \"i\", getAttrs: () => null }],\n toDOM: () => [\"em\", 0],\n },\n underline: {\n parseDOM: [{ tag: \"u\" }],\n toDOM: () => [\"u\", 0],\n },\n link: {\n attrs: { href: {}, title: { default: null } },\n inclusive: false,\n parseDOM: [\n {\n tag: \"a[href]\",\n getAttrs: (dom) => {\n if (!(dom instanceof HTMLAnchorElement)) {\n return false;\n }\n\n return {\n href: dom.getAttribute(\"href\"),\n title: dom.getAttribute(\"title\"),\n };\n },\n },\n ],\n toDOM: (node) => [\"a\", { href: node.attrs.href, title: node.attrs.title }, 0],\n },\n },\n });\n\nexport const editorSchema = createEditorSchema();\n","export interface ToolbarAction {\n command: string;\n label: string;\n group: \"inline\" | \"block\" | \"history\";\n}\n\nexport const defaultToolbarActions: ToolbarAction[] = [\n { command: \"bold\", label: \"Bold\", group: \"inline\" },\n { command: \"italic\", label: \"Italic\", group: \"inline\" },\n { command: \"underline\", label: \"Underline\", group: \"inline\" },\n { command: \"heading\", label: \"Heading\", group: \"block\" },\n { command: \"list\", label: \"List\", group: \"block\" },\n { command: \"align\", label: \"Align\", group: \"block\" },\n { command: \"link\", label: \"Link\", group: \"inline\" },\n { command: \"undo\", label: \"Undo\", group: \"history\" },\n { command: \"redo\", label: \"Redo\", group: \"history\" },\n];\n","type EmbedType = \"link\" | \"image\" | \"video\" | \"formula\";\n\ntype MountRichTextEditorOptions = {\n host: HTMLElement;\n initialHtml: string;\n disabled?: boolean;\n onChange: (html: string) => void;\n requestEmbedValue?: (type: EmbedType) => Promise<string | null> | string | null;\n};\n\ntype MountedRichTextEditor = {\n destroy: () => void;\n getHtml: () => string;\n setHtml: (html: string) => void;\n};\n\nconst commandLabels: Record<string, string> = {\n bold: \"Bold\",\n italic: \"Italic\",\n underline: \"Underline\",\n strike: \"Strike\",\n code: \"Inline code\",\n blockquote: \"Blockquote\",\n \"code-block\": \"Code block\",\n \"indent-\": \"Outdent\",\n \"indent+\": \"Indent\",\n link: \"Link\",\n image: \"Image\",\n video: \"Video\",\n formula: \"Formula\",\n clean: \"Remove formatting\",\n};\n\nconst commandIconSvg: Record<string, string> = {\n bold: '<svg viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M4 2.5h4.5a2.5 2.5 0 010 5H4z\"/><path d=\"M4 7.5h5a3 3 0 010 6H4z\"/></svg>',\n italic: '<svg viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.7\" stroke-linecap=\"round\"><path d=\"M9.8 2.5H5.5\"/><path d=\"M10.5 13.5H6.2\"/><path d=\"M9.3 2.5 6.7 13.5\"/></svg>',\n underline: '<svg viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\"><path d=\"M4 2.5v4.2a4 4 0 008 0V2.5\"/><path d=\"M3 13.5h10\"/></svg>',\n strike: '<svg viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\"><path d=\"M4 4.5c.8-1.2 2-1.9 3.7-1.9 2 0 3.3 1 3.3 2.5 0 3-6.5 1.8-6.5 4.6 0 1.5 1.3 2.3 3.4 2.3 1.6 0 2.9-.6 3.8-1.7\"/><path d=\"M2.5 8h11\"/></svg>',\n code: '<svg viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M6 4 2.5 8 6 12\"/><path d=\"M10 4 13.5 8 10 12\"/><path d=\"M8.7 2.8 7.3 13.2\"/></svg>',\n blockquote: '<svg viewBox=\"0 0 16 16\" fill=\"currentColor\"><path d=\"M3 3h4v4H4.8c.1 1.8-.7 3.2-1.8 4L2 10c1-.7 1.5-1.7 1.4-3H3zM9 3h4v4h-2.2c.1 1.8-.7 3.2-1.8 4L8 10c1-.7 1.5-1.7 1.4-3H9z\"/></svg>',\n \"code-block\": '<svg viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"2.5\" y=\"2.5\" width=\"11\" height=\"11\" rx=\"1.8\"/><path d=\"M6.2 6 4.5 8l1.7 2\"/><path d=\"M9.8 6 11.5 8l-1.7 2\"/><path d=\"M8.6 5.5 7.4 10.5\"/></svg>',\n \"indent-\": '<svg viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M9 4h4\"/><path d=\"M9 8h4\"/><path d=\"M9 12h4\"/><path d=\"M7 5.5 4 8l3 2.5\"/></svg>',\n \"indent+\": '<svg viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M3 4h4\"/><path d=\"M3 8h4\"/><path d=\"M3 12h4\"/><path d=\"M9 5.5 12 8l-3 2.5\"/></svg>',\n link: '<svg viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\"><path d=\"M6.3 9.7 4.9 11a2.4 2.4 0 103.4 3.4l1.5-1.4\"/><path d=\"M9.7 6.3 11 4.9a2.4 2.4 0 10-3.4-3.4L6.1 2.9\"/><path d=\"M5.9 10.1 10.1 5.9\"/></svg>',\n image: '<svg viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"2.3\" y=\"2.5\" width=\"11.4\" height=\"11\" rx=\"1.8\"/><circle cx=\"6\" cy=\"6\" r=\"1.2\" fill=\"currentColor\" stroke=\"none\"/><path d=\"m3.8 11 2.8-2.8 2.2 2.2 1.6-1.6 1.8 2.2\"/></svg>',\n video: '<svg viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"2.2\" y=\"3\" width=\"8.8\" height=\"10\" rx=\"1.6\"/><path d=\"M11 6.2 13.8 4.8v6.4L11 9.8z\"/><path d=\"M6.2 6.4v3.2l2.7-1.6z\" fill=\"currentColor\" stroke=\"none\"/></svg>',\n formula: '<svg viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M3 4h5\"/><path d=\"M3 12h5\"/><path d=\"M8 4 5 8l3 4\"/><path d=\"M10.3 5.8v4.4\"/><path d=\"M12.5 8h-4.4\"/></svg>',\n clean: '<svg viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M2.8 12.5h6.8\"/><path d=\"m4.2 3.3 6 6\"/><path d=\"m10.2 2.7 3 3-2 2-3-3z\"/><path d=\"M6.2 11.2 4.1 13.3\"/></svg>',\n};\n\nconst createToolbarIcon = (command: string, fallback: string): HTMLElement => {\n const icon = document.createElement(\"span\");\n icon.className = \"az-rich-editor-toolbar-icon\";\n\n const svgMarkup = commandIconSvg[command];\n if (svgMarkup) {\n icon.innerHTML = svgMarkup;\n } else {\n icon.textContent = fallback;\n }\n\n return icon;\n};\n\nconst selectOptionLabels: Record<string, Record<string, string>> = {\n font: {\n default: \"A\",\n serif: \"As\",\n monospace: \"Am\",\n },\n size: {\n small: \"S\",\n normal: \"N\",\n large: \"L\",\n huge: \"XL\",\n },\n header: {\n normal: \"P\",\n h1: \"H1\",\n h2: \"H2\",\n },\n script: {\n normal: \"x\",\n sub: \"x_\",\n super: \"x^\",\n },\n align: {\n left: \"L\",\n center: \"C\",\n right: \"R\",\n justify: \"J\",\n },\n list: {\n none: \"-\",\n ordered: \"1.\",\n bullet: \"o\",\n },\n direction: {\n ltr: \"->\",\n rtl: \"<-\",\n },\n};\n\nconst safeUrl = (value: string): string | null => {\n const trimmed = value.trim();\n\n if (!trimmed) {\n return null;\n }\n\n if (/^(https?:|mailto:|tel:)/i.test(trimmed)) {\n return trimmed;\n }\n\n return null;\n};\n\nconst escapeHtml = (value: string): string =>\n value.replace(/&/g, \"&amp;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\").replace(/\\\"/g, \"&quot;\");\n\nconst closestElement = (node: Node | null, root: HTMLElement): HTMLElement | null => {\n let current: Node | null = node;\n\n while (current && current !== root) {\n if (current instanceof HTMLElement) {\n return current;\n }\n\n current = current.parentNode;\n }\n\n return null;\n};\n\nconst closestByTag = (node: Node | null, tagName: string, root: HTMLElement): HTMLElement | null => {\n const desired = tagName.toLowerCase();\n let current: Node | null = node;\n\n while (current && current !== root) {\n if (current instanceof HTMLElement && current.tagName.toLowerCase() === desired) {\n return current;\n }\n\n current = current.parentNode;\n }\n\n return null;\n};\n\nconst unwrapElement = (element: HTMLElement) => {\n const parent = element.parentNode;\n\n if (!parent) {\n return;\n }\n\n while (element.firstChild) {\n parent.insertBefore(element.firstChild, element);\n }\n\n parent.removeChild(element);\n};\n\nconst placeCaretInside = (element: HTMLElement) => {\n const selection = window.getSelection();\n\n if (!selection) {\n return;\n }\n\n const range = document.createRange();\n range.selectNodeContents(element);\n range.collapse(false);\n selection.removeAllRanges();\n selection.addRange(range);\n};\n\nconst getSelectionRange = (root: HTMLElement): Range | null => {\n const selection = window.getSelection();\n\n if (!selection || selection.rangeCount === 0) {\n return null;\n }\n\n const range = selection.getRangeAt(0);\n\n if (!root.contains(range.commonAncestorContainer)) {\n return null;\n }\n\n return range;\n};\n\nconst wrapRange = (range: Range, tagName: string, attrs?: Record<string, string>): HTMLElement => {\n const wrapper = document.createElement(tagName);\n\n if (attrs) {\n Object.entries(attrs).forEach(([key, value]) => wrapper.setAttribute(key, value));\n }\n\n if (range.collapsed) {\n wrapper.append(document.createTextNode(\"\\u200B\"));\n range.insertNode(wrapper);\n placeCaretInside(wrapper);\n return wrapper;\n }\n\n const fragment = range.extractContents();\n wrapper.append(fragment);\n range.insertNode(wrapper);\n\n const selection = window.getSelection();\n if (selection) {\n const nextRange = document.createRange();\n nextRange.selectNodeContents(wrapper);\n selection.removeAllRanges();\n selection.addRange(nextRange);\n }\n\n return wrapper;\n};\n\nconst blockTags = new Set([\"p\", \"div\", \"h1\", \"h2\", \"blockquote\", \"pre\", \"li\"]);\n\nconst getBlockElement = (range: Range, root: HTMLElement): HTMLElement => {\n const start = closestElement(range.startContainer, root);\n\n if (!start) {\n return root;\n }\n\n let current: HTMLElement | null = start;\n while (current && current !== root) {\n if (blockTags.has(current.tagName.toLowerCase())) {\n return current;\n }\n\n current = current.parentElement;\n }\n\n return root;\n};\n\nconst replaceBlockTag = (block: HTMLElement, tagName: string): HTMLElement => {\n if (block.tagName.toLowerCase() === tagName.toLowerCase()) {\n return block;\n }\n\n const replacement = document.createElement(tagName);\n while (block.firstChild) {\n replacement.append(block.firstChild);\n }\n\n Array.from(block.attributes).forEach((attribute) => {\n if (attribute.name === \"style\" || attribute.name === \"dir\") {\n replacement.setAttribute(attribute.name, attribute.value);\n }\n });\n\n block.parentNode?.replaceChild(replacement, block);\n return replacement;\n};\n\nconst applyInlineTag = (tagName: string, root: HTMLElement, range: Range) => {\n const existing = closestByTag(range.commonAncestorContainer, tagName, root);\n\n if (existing) {\n unwrapElement(existing);\n return;\n }\n\n wrapRange(range, tagName);\n};\n\nconst applyScript = (value: \"normal\" | \"sub\" | \"super\", root: HTMLElement, range: Range) => {\n const sub = closestByTag(range.commonAncestorContainer, \"sub\", root);\n const sup = closestByTag(range.commonAncestorContainer, \"sup\", root);\n\n if (sub) {\n unwrapElement(sub);\n }\n\n if (sup) {\n unwrapElement(sup);\n }\n\n if (value === \"sub\") {\n wrapRange(range, \"sub\");\n }\n\n if (value === \"super\") {\n wrapRange(range, \"sup\");\n }\n};\n\nconst applyHeader = (value: \"normal\" | \"h1\" | \"h2\", root: HTMLElement, range: Range) => {\n const block = getBlockElement(range, root);\n\n if (value === \"h1\" || value === \"h2\") {\n replaceBlockTag(block, value);\n return;\n }\n\n replaceBlockTag(block, \"p\");\n};\n\nconst toggleBlockTag = (tagName: \"blockquote\" | \"pre\", root: HTMLElement, range: Range) => {\n const block = getBlockElement(range, root);\n\n if (block.tagName.toLowerCase() === tagName) {\n replaceBlockTag(block, \"p\");\n return;\n }\n\n replaceBlockTag(block, tagName);\n};\n\nconst ensureList = (tagName: \"ol\" | \"ul\", root: HTMLElement, range: Range, remove: boolean) => {\n const block = getBlockElement(range, root);\n const li = closestByTag(block, \"li\", root);\n\n if (li) {\n const list = li.parentElement;\n\n if (!list) {\n return;\n }\n\n if (remove || list.tagName.toLowerCase() === tagName) {\n const paragraph = document.createElement(\"p\");\n paragraph.textContent = li.textContent ?? \"\";\n list.parentNode?.insertBefore(paragraph, list);\n li.remove();\n\n if (!list.querySelector(\"li\")) {\n list.remove();\n }\n\n return;\n }\n\n const nextList = document.createElement(tagName);\n const nextLi = document.createElement(\"li\");\n nextLi.textContent = li.textContent ?? \"\";\n nextList.append(nextLi);\n list.parentNode?.insertBefore(nextList, list.nextSibling);\n li.remove();\n\n if (!list.querySelector(\"li\")) {\n list.remove();\n }\n\n return;\n }\n\n if (remove) {\n return;\n }\n\n const list = document.createElement(tagName);\n const listItem = document.createElement(\"li\");\n listItem.innerHTML = block.innerHTML;\n list.append(listItem);\n block.parentNode?.replaceChild(list, block);\n};\n\nconst applyIndent = (root: HTMLElement, range: Range, direction: \"-\" | \"+\") => {\n const block = getBlockElement(range, root);\n const current = Number.parseInt(block.style.marginLeft || \"0\", 10) || 0;\n const next = direction === \"+\" ? current + 24 : Math.max(0, current - 24);\n\n block.style.marginLeft = next === 0 ? \"\" : `${next}px`;\n};\n\nconst applyAlign = (root: HTMLElement, range: Range, align: \"left\" | \"center\" | \"right\" | \"justify\") => {\n const block = getBlockElement(range, root);\n block.style.textAlign = align;\n};\n\nconst applyDirection = (root: HTMLElement, range: Range, value: \"ltr\" | \"rtl\") => {\n const block = getBlockElement(range, root);\n block.setAttribute(\"dir\", value);\n};\n\nconst clearFormatting = (root: HTMLElement, range: Range) => {\n if (range.collapsed) {\n const block = getBlockElement(range, root);\n const text = block.textContent ?? \"\";\n block.replaceChildren(document.createTextNode(text));\n return;\n }\n\n const selectedText = range.toString();\n range.deleteContents();\n range.insertNode(document.createTextNode(selectedText));\n};\n\nconst insertNodeAtRange = (range: Range, node: Node) => {\n range.deleteContents();\n range.insertNode(node);\n\n const selection = window.getSelection();\n if (selection) {\n const after = document.createRange();\n after.setStartAfter(node);\n after.collapse(true);\n selection.removeAllRanges();\n selection.addRange(after);\n }\n};\n\nconst applyEmbed = async (\n type: EmbedType,\n range: Range,\n requestEmbedValue: MountRichTextEditorOptions[\"requestEmbedValue\"],\n) => {\n const value = await Promise.resolve(requestEmbedValue?.(type) ?? null);\n\n if (!value || value.trim().length === 0) {\n return;\n }\n\n if (type === \"formula\") {\n const formula = document.createElement(\"span\");\n formula.setAttribute(\"data-formula\", \"true\");\n formula.textContent = value.trim();\n insertNodeAtRange(range, formula);\n return;\n }\n\n const url = safeUrl(value);\n\n if (!url) {\n return;\n }\n\n if (type === \"link\") {\n const selected = range.toString().trim();\n const anchor = document.createElement(\"a\");\n anchor.href = url;\n anchor.rel = \"noopener noreferrer\";\n anchor.target = \"_blank\";\n anchor.textContent = selected.length > 0 ? selected : url;\n insertNodeAtRange(range, anchor);\n return;\n }\n\n if (type === \"image\") {\n const image = document.createElement(\"img\");\n image.src = url;\n image.alt = \"embedded image\";\n insertNodeAtRange(range, image);\n return;\n }\n\n const video = document.createElement(\"video\");\n video.setAttribute(\"controls\", \"true\");\n video.src = url;\n insertNodeAtRange(range, video);\n};\n\nconst applyButtonCommand = async (\n command: string,\n editable: HTMLDivElement,\n requestEmbedValue: MountRichTextEditorOptions[\"requestEmbedValue\"],\n) => {\n editable.focus();\n\n const range = getSelectionRange(editable);\n\n if (!range) {\n return;\n }\n\n switch (command) {\n case \"bold\":\n applyInlineTag(\"strong\", editable, range);\n break;\n case \"italic\":\n applyInlineTag(\"em\", editable, range);\n break;\n case \"underline\":\n applyInlineTag(\"u\", editable, range);\n break;\n case \"strike\":\n applyInlineTag(\"s\", editable, range);\n break;\n case \"code\":\n applyInlineTag(\"code\", editable, range);\n break;\n case \"blockquote\":\n toggleBlockTag(\"blockquote\", editable, range);\n break;\n case \"code-block\":\n toggleBlockTag(\"pre\", editable, range);\n break;\n case \"indent-\":\n applyIndent(editable, range, \"-\");\n break;\n case \"indent+\":\n applyIndent(editable, range, \"+\");\n break;\n case \"link\":\n await applyEmbed(\"link\", range, requestEmbedValue);\n break;\n case \"image\":\n await applyEmbed(\"image\", range, requestEmbedValue);\n break;\n case \"video\":\n await applyEmbed(\"video\", range, requestEmbedValue);\n break;\n case \"formula\":\n await applyEmbed(\"formula\", range, requestEmbedValue);\n break;\n case \"clean\":\n clearFormatting(editable, range);\n break;\n default:\n break;\n }\n};\n\nconst applySelectCommand = (command: string, value: string, editable: HTMLDivElement) => {\n editable.focus();\n\n const range = getSelectionRange(editable);\n\n if (!range) {\n return;\n }\n\n switch (command) {\n case \"font\":\n if (value === \"default\") {\n clearFormatting(editable, range);\n } else {\n wrapRange(range, \"span\", {\n style: `font-family:${value === \"serif\" ? \"serif\" : \"monospace\"}`,\n });\n }\n break;\n case \"size\":\n wrapRange(range, \"span\", {\n style:\n value === \"small\"\n ? \"font-size:12px\"\n : value === \"large\"\n ? \"font-size:20px\"\n : value === \"huge\"\n ? \"font-size:28px\"\n : \"font-size:16px\",\n });\n break;\n case \"header\":\n applyHeader(value as \"normal\" | \"h1\" | \"h2\", editable, range);\n break;\n case \"script\":\n applyScript(value as \"normal\" | \"sub\" | \"super\", editable, range);\n break;\n case \"align\":\n applyAlign(editable, range, value as \"left\" | \"center\" | \"right\" | \"justify\");\n break;\n case \"list\":\n ensureList(value === \"ordered\" ? \"ol\" : \"ul\", editable, range, value === \"none\");\n break;\n case \"direction\":\n applyDirection(editable, range, value === \"rtl\" ? \"rtl\" : \"ltr\");\n break;\n default:\n break;\n }\n};\n\nconst renderButton = (\n command: string,\n editable: HTMLDivElement,\n requestEmbedValue: MountRichTextEditorOptions[\"requestEmbedValue\"],\n onMutate: () => void,\n) => {\n const button = document.createElement(\"button\");\n\n button.type = \"button\";\n button.className = \"az-rich-editor-toolbar-button\";\n button.setAttribute(\"aria-label\", commandLabels[command] ?? command);\n button.title = commandLabels[command] ?? command;\n button.append(createToolbarIcon(command, command));\n button.addEventListener(\"click\", async () => {\n await applyButtonCommand(command, editable, requestEmbedValue);\n onMutate();\n });\n\n return button;\n};\n\nconst createSelect = (\n format: string,\n options: string[],\n editable: HTMLDivElement,\n onMutate: () => void,\n) => {\n const select = document.createElement(\"select\");\n\n select.className = \"az-rich-editor-toolbar-select\";\n select.setAttribute(\"aria-label\", format);\n\n options.forEach((optionValue) => {\n const option = document.createElement(\"option\");\n\n option.value = optionValue;\n option.textContent = selectOptionLabels[format]?.[optionValue] ?? optionValue;\n option.title = optionValue;\n select.append(option);\n });\n\n select.addEventListener(\"change\", () => {\n applySelectCommand(format, select.value, editable);\n onMutate();\n });\n\n return select;\n};\n\nconst buildToolbar = (\n editable: HTMLDivElement,\n requestEmbedValue: MountRichTextEditorOptions[\"requestEmbedValue\"],\n onMutate: () => void,\n) => {\n const toolbar = document.createElement(\"div\");\n\n toolbar.className = \"az-rich-editor-toolbar\";\n toolbar.setAttribute(\"role\", \"toolbar\");\n toolbar.setAttribute(\"aria-label\", \"Rich editor toolbar\");\n\n const selectConfigs: Array<{ format: string; options: string[] }> = [\n { format: \"font\", options: [\"default\", \"serif\", \"monospace\"] },\n { format: \"size\", options: [\"small\", \"normal\", \"large\", \"huge\"] },\n { format: \"header\", options: [\"normal\", \"h1\", \"h2\"] },\n { format: \"script\", options: [\"normal\", \"sub\", \"super\"] },\n { format: \"align\", options: [\"left\", \"center\", \"right\", \"justify\"] },\n { format: \"list\", options: [\"none\", \"ordered\", \"bullet\"] },\n { format: \"direction\", options: [\"ltr\", \"rtl\"] },\n ];\n\n selectConfigs.forEach((config) => toolbar.append(createSelect(config.format, config.options, editable, onMutate)));\n\n [\n \"bold\",\n \"italic\",\n \"underline\",\n \"strike\",\n \"code\",\n \"blockquote\",\n \"code-block\",\n \"indent-\",\n \"indent+\",\n \"link\",\n \"image\",\n \"video\",\n \"formula\",\n \"clean\",\n ].forEach((command) => toolbar.append(renderButton(command, editable, requestEmbedValue, onMutate)));\n\n return toolbar;\n};\n\nexport const mountRichTextEditor = ({\n host,\n initialHtml,\n disabled = false,\n onChange,\n requestEmbedValue,\n}: MountRichTextEditorOptions): MountedRichTextEditor => {\n host.innerHTML = \"\";\n\n const wrapper = document.createElement(\"div\");\n wrapper.className = \"az-rich-editor\";\n\n const editable = document.createElement(\"div\");\n editable.className = \"az-rich-editor-input\";\n editable.setAttribute(\"aria-label\", \"Rich editor input\");\n editable.setAttribute(\"role\", \"textbox\");\n editable.setAttribute(\"aria-multiline\", \"true\");\n editable.setAttribute(\"contenteditable\", disabled ? \"false\" : \"true\");\n editable.dataset.placeholder = \"Compose an epic...\";\n editable.innerHTML = initialHtml;\n\n const emitChange = () => onChange(editable.innerHTML);\n\n const toolbar = buildToolbar(editable, requestEmbedValue, emitChange);\n\n const inputHandler = () => emitChange();\n editable.addEventListener(\"input\", inputHandler);\n\n wrapper.append(toolbar, editable);\n host.append(wrapper);\n\n return {\n destroy: () => {\n editable.removeEventListener(\"input\", inputHandler);\n host.innerHTML = \"\";\n },\n getHtml: () => editable.innerHTML,\n setHtml: (html) => {\n editable.innerHTML = html;\n },\n };\n};\n","import type { EditorInstance } from \"../../core/types\";\nimport { mountRichTextEditor } from \"../../rich-text/mountEditor\";\n\nexport interface DomEditorAdapter {\n mount: (target: Element) => void;\n unmount: () => void;\n destroy: () => void;\n}\n\nexport const createDomAdapter = (editor: EditorInstance): DomEditorAdapter => {\n let target: Element | null = null;\n let mountedEditor: ReturnType<typeof mountRichTextEditor> | null = null;\n\n return {\n mount: (nextTarget) => {\n target = nextTarget;\n editor.mount(nextTarget);\n\n if (!(nextTarget instanceof HTMLElement)) {\n return;\n }\n\n mountedEditor = mountRichTextEditor({\n host: nextTarget,\n initialHtml: editor.export(\"html\").payload,\n requestEmbedValue: () => null,\n onChange: (html) => {\n editor.import({\n format: \"html\",\n payload: html,\n });\n },\n });\n },\n unmount: () => {\n if (!target) {\n return;\n }\n\n mountedEditor?.destroy();\n mountedEditor = null;\n\n editor.unmount();\n target = null;\n },\n destroy: () => {\n mountedEditor?.destroy();\n mountedEditor = null;\n\n editor.destroy();\n target = null;\n },\n };\n};\n","import { useEffect, useMemo, useRef } from \"react\";\n\nimport { createEditor } from \"../../core/createEditor\";\nimport type { EditorConfig } from \"../../core/types\";\nimport { mountRichTextEditor } from \"../../rich-text/mountEditor\";\n\nexport const useEditorAdapter = (config: EditorConfig) => {\n const editor = useMemo(() => createEditor(config), [config]);\n\n useEffect(() => () => {\n editor.destroy();\n }, [editor]);\n\n return editor;\n};\n\nexport interface RichEditorAdapterProps extends EditorConfig {\n className?: string;\n disabled?: boolean;\n onRequestEmbedValue?: (type: \"link\" | \"image\" | \"video\" | \"formula\") => Promise<string | null> | string | null;\n}\n\nexport function RichEditorAdapter({ className, disabled = false, initialContent, onChange, onError, onRequestEmbedValue }: RichEditorAdapterProps) {\n const editor = useEditorAdapter({ initialContent, onChange, onError });\n const hostRef = useRef<HTMLDivElement | null>(null);\n\n useEffect(() => {\n const host = hostRef.current;\n\n if (!host) {\n return;\n }\n\n const mounted = mountRichTextEditor({\n host,\n initialHtml: editor.export(\"html\").payload,\n disabled,\n requestEmbedValue: onRequestEmbedValue,\n onChange: (html) => {\n editor.import({\n format: \"html\",\n payload: html,\n });\n },\n });\n\n return () => {\n mounted.destroy();\n };\n }, [disabled, editor, onRequestEmbedValue]);\n\n return (\n <div\n aria-label=\"Rich editor\"\n className={className}\n ref={hostRef}\n />\n );\n}\n"],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "@azlib/editor",
3
+ "version": "0.2.0",
4
+ "type": "module",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/hanhn-dev/azlib.git"
9
+ },
10
+ "files": [
11
+ "dist",
12
+ "README.md"
13
+ ],
14
+ "exports": {
15
+ ".": {
16
+ "types": "./dist/index.d.mts",
17
+ "import": "./dist/index.mjs",
18
+ "require": "./dist/index.cjs"
19
+ }
20
+ },
21
+ "peerDependencies": {
22
+ "react": "^19.2.0",
23
+ "react-dom": "^19.2.0"
24
+ },
25
+ "peerDependenciesMeta": {
26
+ "react": {
27
+ "optional": true
28
+ },
29
+ "react-dom": {
30
+ "optional": true
31
+ }
32
+ },
33
+ "devDependencies": {
34
+ "@testing-library/jest-dom": "^6.9.1",
35
+ "@testing-library/react": "^16.3.2",
36
+ "@testing-library/user-event": "^14.6.1",
37
+ "@types/react": "19.2.14",
38
+ "@types/react-dom": "19.2.3",
39
+ "jsdom": "^29.1.0",
40
+ "react": "^19.2.5",
41
+ "react-dom": "^19.2.5",
42
+ "tsdown": "^0.22.1",
43
+ "typescript": "5.5.4",
44
+ "vitest": "^4.1.5",
45
+ "@repo/typescript-config": "0.0.0"
46
+ },
47
+ "dependencies": {
48
+ "isomorphic-dompurify": "^2.21.0",
49
+ "prosemirror-model": "^1.24.1"
50
+ },
51
+ "publishConfig": {
52
+ "access": "public",
53
+ "registry": "https://registry.npmjs.org"
54
+ },
55
+ "scripts": {
56
+ "build": "rm -rf dist && tsdown",
57
+ "dev": "tsdown --watch",
58
+ "lint": "tsc -p tsconfig.json --noEmit",
59
+ "test": "vitest run --environment jsdom",
60
+ "clean": "rm -rf .turbo node_modules dist"
61
+ }
62
+ }