@xui/rich-text-editor 2.0.0-alpha.19 → 2.0.0-alpha.21

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.
@@ -549,6 +549,7 @@ class XuiRichTextEditor {
549
549
  ...(ngDevMode ? [{ debugName: "surface" }] : /* istanbul ignore next */ []));
550
550
  linkField = viewChild('linkField', /* @ts-ignore */
551
551
  ...(ngDevMode ? [{ debugName: "linkField" }] : /* istanbul ignore next */ []));
552
+ /** Extra classes, merged into the component's own rather than replacing them. */
552
553
  class = input('', /* @ts-ignore */
553
554
  ...(ngDevMode ? [{ debugName: "class" }] : /* istanbul ignore next */ []));
554
555
  /** The source text, in the active `format`. Two-way bindable, and the form value. */
@@ -557,14 +558,17 @@ class XuiRichTextEditor {
557
558
  /** `'markdown'`, `'bbcode'`, or any format registered with `provideXuiRichTextSyntax`. */
558
559
  format = input(this.config.format, /* @ts-ignore */
559
560
  ...(ngDevMode ? [{ debugName: "format" }] : /* istanbul ignore next */ []));
561
+ /** Text shown over the empty editor. */
560
562
  placeholder = input(this.config.placeholder, /* @ts-ignore */
561
563
  ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
562
564
  /** Offer the source-text toggle. */
563
565
  sourceView = input(this.config.sourceView, { ...(ngDevMode ? { debugName: "sourceView" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
566
+ /** Block editing and dim the editor and its toolbar. */
564
567
  disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
565
568
  /** Height of the writing area before it grows with the content. */
566
569
  minHeight = input(180, /* @ts-ignore */
567
570
  ...(ngDevMode ? [{ debugName: "minHeight" }] : /* istanbul ignore next */ []));
571
+ /** Accessible name for the editing surface — what is being written. */
568
572
  ariaLabel = input(undefined, { ...(ngDevMode ? { debugName: "ariaLabel" } : /* istanbul ignore next */ {}), alias: 'aria-label' });
569
573
  /** Whether the source view is showing. Two-way bindable. */
570
574
  source = model(false, /* @ts-ignore */
@@ -1 +1 @@
1
- {"version":3,"file":"xui-rich-text-editor.mjs","sources":["../../../../../../libs/ui/rich-text-editor/xui/src/lib/rich-text-syntax.ts","../../../../../../libs/ui/rich-text-editor/xui/src/lib/bbcode-syntax.ts","../../../../../../libs/ui/rich-text-editor/xui/src/lib/markdown-syntax.ts","../../../../../../libs/ui/rich-text-editor/xui/src/lib/rich-text-editor.token.ts","../../../../../../libs/ui/rich-text-editor/xui/src/lib/rich-text-editor.ts","../../../../../../libs/ui/rich-text-editor/xui/src/index.ts","../../../../../../libs/ui/rich-text-editor/xui/src/xui-rich-text-editor.ts"],"sourcesContent":["/**\n * A formatting feature. The editor's toolbar offers exactly the features the\n * active syntax declares, so nothing can be applied that the format cannot\n * express — Markdown has no underline, BBCode has no headings.\n */\nexport type XuiRichTextMark = 'bold' | 'italic' | 'underline' | 'strike' | 'code' | 'link';\n\nexport type XuiRichTextBlock =\n 'heading1' | 'heading2' | 'heading3' | 'bulletList' | 'orderedList' | 'quote' | 'codeBlock' | 'rule';\n\nexport type XuiRichTextFeature = XuiRichTextMark | XuiRichTextBlock;\n\n/**\n * Turns the editor's HTML into source text.\n *\n * The editor edits one canonical HTML subset — `p`, `h1`–`h3`, `ul`/`ol`,\n * `blockquote`, `pre`, `hr` and the inline marks — and a syntax is only the\n * translation at each end. Implement one to teach the editor a new format;\n * nothing else changes.\n */\nexport interface XuiRichTextWriter {\n /** Escape text so the syntax's own punctuation is not read as markup. */\n escape(text: string): string;\n /** Wrap `inner` in a mark, or return it untouched when the syntax lacks one. */\n mark(kind: XuiRichTextMark, inner: string, href?: string): string;\n /** Wrap a block's already-serialised inline content. */\n block(kind: 'paragraph' | 'heading1' | 'heading2' | 'heading3' | 'quote', inner: string): string;\n /** A whole list, given its already-serialised items. */\n list(items: string[], ordered: boolean): string;\n /** Verbatim text — never escaped, never marked up. */\n codeBlock(text: string): string;\n /** A thematic break. */\n rule(): string;\n}\n\n/** Both directions of one text format. */\nexport interface XuiRichTextSyntax {\n /** How the format is named in the `format` input — `'markdown'`, `'bbcode'`, … */\n readonly name: string;\n /** What this format can express. Anything absent is left out of the toolbar. */\n readonly features: readonly XuiRichTextFeature[];\n /** Source text → the editor's HTML subset. Must return markup it produced itself. */\n toHtml(source: string): string;\n /** The editor's HTML → source text. */\n fromHtml(root: HTMLElement): string;\n}\n\nconst MARK_TAGS: Record<string, XuiRichTextMark> = {\n STRONG: 'bold',\n B: 'bold',\n EM: 'italic',\n I: 'italic',\n U: 'underline',\n S: 'strike',\n STRIKE: 'strike',\n DEL: 'strike',\n CODE: 'code',\n A: 'link'\n};\n\n/**\n * Walks the editor's HTML and hands each piece to `writer`.\n *\n * Shared by every syntax so they only describe *what* their markup looks like,\n * never how to traverse a DOM — and so a new syntax cannot get the traversal\n * subtly wrong.\n */\nexport function serializeHtml(root: HTMLElement, writer: XuiRichTextWriter): string {\n const blocks: string[] = [];\n\n for (const node of Array.from(root.childNodes)) {\n const block = serializeBlock(node, writer);\n\n if (block !== null) {\n blocks.push(block);\n }\n }\n\n return blocks.filter(block => block !== '').join('\\n\\n');\n}\n\nfunction serializeBlock(node: Node, writer: XuiRichTextWriter): string | null {\n if (node.nodeType === Node.TEXT_NODE) {\n const text = node.textContent ?? '';\n\n // Loose text between blocks — browsers leave it there after some edits.\n return text.trim() ? writer.block('paragraph', writer.escape(text)) : null;\n }\n\n if (!(node instanceof Element)) {\n return null;\n }\n\n switch (node.tagName) {\n case 'H1':\n return writer.block('heading1', serializeInline(node, writer));\n case 'H2':\n return writer.block('heading2', serializeInline(node, writer));\n case 'H3':\n return writer.block('heading3', serializeInline(node, writer));\n case 'BLOCKQUOTE':\n return writer.block('quote', quoteContent(node as HTMLElement, writer));\n case 'PRE':\n return writer.codeBlock(node.textContent ?? '');\n case 'HR':\n return writer.rule();\n case 'UL':\n case 'OL':\n return writer.list(\n Array.from(node.children)\n .filter(child => child.tagName === 'LI')\n .map(item => serializeInline(item, writer)),\n node.tagName === 'OL'\n );\n case 'BR':\n return null;\n default:\n // `p`, `div` (what some browsers still produce on Enter), and anything\n // else that reached the top level: treat as a paragraph.\n return writer.block('paragraph', serializeInline(node, writer));\n }\n}\n\n/** A quote may hold blocks of its own; flatten them to lines. */\nfunction quoteContent(node: HTMLElement, writer: XuiRichTextWriter): string {\n const hasBlocks = Array.from(node.children).some(child => /^(P|DIV|H[1-3])$/.test(child.tagName));\n\n if (!hasBlocks) {\n return serializeInline(node, writer);\n }\n\n return Array.from(node.children)\n .map(child => serializeInline(child, writer))\n .filter(Boolean)\n .join('\\n');\n}\n\nfunction serializeInline(node: Node, writer: XuiRichTextWriter): string {\n let out = '';\n\n for (const child of Array.from(node.childNodes)) {\n if (child.nodeType === Node.TEXT_NODE) {\n out += writer.escape(child.textContent ?? '');\n continue;\n }\n\n if (!(child instanceof Element)) {\n continue;\n }\n\n if (child.tagName === 'BR') {\n out += '\\n';\n continue;\n }\n\n const mark = MARK_TAGS[child.tagName];\n const inner = child.tagName === 'CODE' ? writer.escape(child.textContent ?? '') : serializeInline(child, writer);\n\n out += mark ? writer.mark(mark, inner, child.getAttribute('href') ?? undefined) : inner;\n }\n\n return out;\n}\n\n/** Escapes text for insertion into the editor's HTML. */\nexport function escapeHtml(text: string): string {\n return text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;');\n}\n\n/**\n * Keeps `javascript:` and friends out of an `href`.\n *\n * Source text is user input as far as this package is concerned — a comment, a\n * forum post — so a link is only ever emitted when its scheme is one that can\n * do nothing but navigate.\n */\nexport function sanitizeUrl(url: string): string {\n const trimmed = url.trim();\n\n return /^(https?:|mailto:|tel:|\\/|#|\\.)/i.test(trimmed) ? trimmed : '';\n}\n","import {\n escapeHtml,\n sanitizeUrl,\n serializeHtml,\n type XuiRichTextFeature,\n type XuiRichTextSyntax,\n type XuiRichTextWriter\n} from './rich-text-syntax';\n\n/**\n * The BBCode this syntax reads and writes.\n *\n * The tags every forum agrees on. BBCode has underline, which Markdown lacks;\n * it has no headings and no thematic break, so the toolbar drops those — the\n * format decides what the toolbar offers, not the other way round.\n */\nconst FEATURES: readonly XuiRichTextFeature[] = [\n 'bold',\n 'italic',\n 'underline',\n 'strike',\n 'link',\n 'bulletList',\n 'orderedList',\n 'quote',\n 'codeBlock'\n];\n\nconst writer: XuiRichTextWriter = {\n // BBCode has no escape character. A stray `[` is only ambiguous next to a tag\n // name, so that is the one case worth neutralising.\n escape: text => text.replace(/\\[(?=\\/?[a-z*]+[\\]=])/gi, '&#91;'),\n mark: (kind, inner, href) => {\n switch (kind) {\n case 'bold':\n return `[b]${inner}[/b]`;\n case 'italic':\n return `[i]${inner}[/i]`;\n case 'underline':\n return `[u]${inner}[/u]`;\n case 'strike':\n return `[s]${inner}[/s]`;\n case 'link':\n return href ? `[url=${href}]${inner}[/url]` : inner;\n // No inline-code tag in BBCode: `[code]` is a block everywhere.\n default:\n return inner;\n }\n },\n block: (kind, inner) => {\n switch (kind) {\n case 'quote':\n return `[quote]${inner}[/quote]`;\n // Headings degrade to plain paragraphs rather than to a `[size]` guess.\n default:\n return inner;\n }\n },\n list: (items, ordered) => [ordered ? '[list=1]' : '[list]', ...items.map(item => `[*]${item}`), '[/list]'].join('\\n'),\n codeBlock: text => `[code]\\n${text.replace(/\\n$/, '')}\\n[/code]`,\n rule: () => ''\n};\n\n/** BBCode ⇄ the editor's HTML. */\nexport const bbcodeSyntax: XuiRichTextSyntax = {\n name: 'bbcode',\n features: FEATURES,\n fromHtml: root => serializeHtml(root, writer),\n toHtml: source => bbcodeToHtml(source)\n};\n\n/** `[tag]…[/tag]` → HTML element, innermost pair first. */\nconst PAIRS: [RegExp, string][] = [\n [/\\[b]([\\s\\S]*?)\\[\\/b]/gi, '<strong>$1</strong>'],\n [/\\[i]([\\s\\S]*?)\\[\\/i]/gi, '<em>$1</em>'],\n [/\\[u]([\\s\\S]*?)\\[\\/u]/gi, '<u>$1</u>'],\n [/\\[s]([\\s\\S]*?)\\[\\/s]/gi, '<s>$1</s>']\n];\n\nfunction bbcodeToHtml(source: string): string {\n const blocks = splitBlocks(source.replace(/\\r\\n?/g, '\\n'));\n\n return blocks.join('');\n}\n\n/**\n * Block tags first — they own whole lines and may hold inline markup — then\n * whatever is left becomes paragraphs.\n */\nfunction splitBlocks(source: string): string[] {\n const html: string[] = [];\n const pattern = /\\[(code|quote|list)(=1)?]([\\s\\S]*?)\\[\\/\\1]/gi;\n let cursor = 0;\n let match: RegExpExecArray | null;\n\n while ((match = pattern.exec(source)) !== null) {\n html.push(...paragraphs(source.slice(cursor, match.index)));\n cursor = match.index + match[0].length;\n\n const [, tag, ordered, body] = match;\n\n if (tag.toLowerCase() === 'code') {\n html.push(`<pre>${escapeHtml(body.replace(/^\\n|\\n$/g, ''))}</pre>`);\n continue;\n }\n\n if (tag.toLowerCase() === 'quote') {\n html.push(`<blockquote>${paragraphs(body).join('') || '<p></p>'}</blockquote>`);\n continue;\n }\n\n const items = body\n .split(/\\[\\*]/)\n .map(item => item.trim())\n .filter(Boolean)\n .map(item => `<li>${inlineToHtml(item)}</li>`)\n .join('');\n\n html.push(ordered ? `<ol>${items}</ol>` : `<ul>${items}</ul>`);\n }\n\n html.push(...paragraphs(source.slice(cursor)));\n\n return html;\n}\n\nfunction paragraphs(source: string): string[] {\n return source\n .split(/\\n{2,}/)\n .map(block => block.replace(/^\\n+|\\n+$/g, ''))\n .filter(block => block.trim())\n .map(block => `<p>${block.split('\\n').map(inlineToHtml).join('<br>')}</p>`);\n}\n\nfunction inlineToHtml(text: string): string {\n let out = escapeHtml(text).replace(\n /\\[url(?:=([^\\]]+))?]([\\s\\S]*?)\\[\\/url]/gi,\n (match, href: string, label: string) => {\n const url = sanitizeUrl(href ?? label);\n\n return url ? `<a href=\"${escapeHtml(url)}\">${label || escapeHtml(url)}</a>` : match;\n }\n );\n\n for (const [pattern, replacement] of PAIRS) {\n // Non-greedy matches close the innermost pair first, so repeating until the\n // text settles unwraps nested tags from the inside out.\n let previous: string;\n\n do {\n previous = out;\n out = out.replace(pattern, replacement);\n } while (out !== previous);\n }\n\n return out;\n}\n","import {\n escapeHtml,\n sanitizeUrl,\n serializeHtml,\n type XuiRichTextFeature,\n type XuiRichTextSyntax,\n type XuiRichTextWriter\n} from './rich-text-syntax';\n\n/**\n * The Markdown this syntax reads and writes.\n *\n * A deliberately small, portable subset — what a comment box needs and what\n * every Markdown renderer agrees on. No tables, footnotes, images or HTML\n * passthrough; no underline, which Markdown has no syntax for.\n */\nconst FEATURES: readonly XuiRichTextFeature[] = [\n 'bold',\n 'italic',\n 'strike',\n 'code',\n 'link',\n 'heading1',\n 'heading2',\n 'heading3',\n 'bulletList',\n 'orderedList',\n 'quote',\n 'codeBlock',\n 'rule'\n];\n\nconst writer: XuiRichTextWriter = {\n escape: text => text.replace(/([\\\\`*_[\\]#>~])/g, '\\\\$1'),\n mark: (kind, inner, href) => {\n switch (kind) {\n case 'bold':\n return `**${inner}**`;\n case 'italic':\n return `*${inner}*`;\n case 'strike':\n return `~~${inner}~~`;\n case 'code':\n // Code spans are verbatim, so the backslashes `escape` added are noise.\n return `\\`${inner.replace(/\\\\([\\\\`*_[\\]#>~])/g, '$1')}\\``;\n case 'link':\n return href ? `[${inner}](${href})` : inner;\n // Markdown cannot underline. Rather than invent `<u>`, the text stays put.\n default:\n return inner;\n }\n },\n block: (kind, inner) => {\n switch (kind) {\n case 'heading1':\n return `# ${inner}`;\n case 'heading2':\n return `## ${inner}`;\n case 'heading3':\n return `### ${inner}`;\n case 'quote':\n return inner\n .split('\\n')\n .map(line => `> ${line}`)\n .join('\\n');\n default:\n return inner;\n }\n },\n list: (items, ordered) => items.map((item, index) => (ordered ? `${index + 1}. ${item}` : `- ${item}`)).join('\\n'),\n codeBlock: text => `\\`\\`\\`\\n${text.replace(/\\n$/, '')}\\n\\`\\`\\``,\n rule: () => '---'\n};\n\n/** Markdown ⇄ the editor's HTML. */\nexport const markdownSyntax: XuiRichTextSyntax = {\n name: 'markdown',\n features: FEATURES,\n fromHtml: root => serializeHtml(root, writer),\n toHtml: source => blocksToHtml(source)\n};\n\nfunction blocksToHtml(source: string): string {\n const lines = source.replace(/\\r\\n?/g, '\\n').split('\\n');\n const html: string[] = [];\n let index = 0;\n\n while (index < lines.length) {\n const line = lines[index];\n\n if (!line.trim()) {\n index++;\n continue;\n }\n\n // Fenced code: verbatim until the closing fence, or the end of the input.\n if (/^```/.test(line)) {\n const code: string[] = [];\n\n index++;\n\n while (index < lines.length && !/^```/.test(lines[index])) {\n code.push(lines[index++]);\n }\n\n index++;\n html.push(`<pre>${escapeHtml(code.join('\\n'))}</pre>`);\n continue;\n }\n\n const heading = /^(#{1,3})\\s+(.*)$/.exec(line);\n\n if (heading) {\n const level = heading[1].length;\n\n html.push(`<h${level}>${inlineToHtml(heading[2])}</h${level}>`);\n index++;\n continue;\n }\n\n if (/^(\\s*[-*_]){3,}\\s*$/.test(line)) {\n html.push('<hr>');\n index++;\n continue;\n }\n\n if (/^>\\s?/.test(line)) {\n const quoted: string[] = [];\n\n while (index < lines.length && /^>\\s?/.test(lines[index])) {\n quoted.push(lines[index++].replace(/^>\\s?/, ''));\n }\n\n html.push(`<blockquote>${quoted.map(text => `<p>${inlineToHtml(text)}</p>`).join('')}</blockquote>`);\n continue;\n }\n\n const bullet = /^\\s*[-*+]\\s+/;\n const ordered = /^\\s*\\d+[.)]\\s+/;\n\n if (bullet.test(line) || ordered.test(line)) {\n const isOrdered = ordered.test(line);\n const marker = isOrdered ? ordered : bullet;\n const items: string[] = [];\n\n while (index < lines.length && marker.test(lines[index])) {\n items.push(`<li>${inlineToHtml(lines[index++].replace(marker, ''))}</li>`);\n }\n\n html.push(isOrdered ? `<ol>${items.join('')}</ol>` : `<ul>${items.join('')}</ul>`);\n continue;\n }\n\n // Anything else runs on as a paragraph until a blank line or a new block.\n const paragraph: string[] = [];\n\n while (index < lines.length && lines[index].trim() && !startsBlock(lines[index])) {\n paragraph.push(lines[index++]);\n }\n\n html.push(`<p>${paragraph.map(inlineToHtml).join('<br>')}</p>`);\n }\n\n return html.join('');\n}\n\nfunction startsBlock(line: string): boolean {\n return /^(```|#{1,3}\\s|>|\\s*[-*+]\\s|\\s*\\d+[.)]\\s)/.test(line) || /^(\\s*[-*_]){3,}\\s*$/.test(line);\n}\n\n/**\n * Stand-ins for the two things that must sit out the emphasis passes: a code\n * span, and a backslash-escaped character. Private-use codepoints, so nothing a\n * user can type collides with them.\n */\nconst SPAN = String.fromCharCode(0xe000);\nconst ESCAPED = String.fromCharCode(0xe001);\n\n/**\n * Inline Markdown → HTML.\n *\n * Code spans and escapes are lifted out first and put back last. That is what\n * keeps `**` inside a code span from turning bold, and `\\*` from being read as\n * emphasis at all — both are invisible to the passes in between.\n */\nfunction inlineToHtml(text: string): string {\n const codeSpans: string[] = [];\n const escapes: string[] = [];\n\n let out = escapeHtml(text)\n .replace(/`([^`]+)`/g, (_, code: string) => {\n codeSpans.push(code);\n\n return `${SPAN}${codeSpans.length - 1}${SPAN}`;\n })\n .replace(/\\\\([\\\\`*_[\\]#>~])/g, (_, char: string) => {\n escapes.push(char);\n\n return `${ESCAPED}${escapes.length - 1}${ESCAPED}`;\n });\n\n out = out\n .replace(/\\[([^\\]]+)]\\(([^)\\s]+)\\)/g, (match, label: string, href: string) => {\n const url = sanitizeUrl(href);\n\n return url ? `<a href=\"${escapeHtml(url)}\">${label}</a>` : match;\n })\n .replace(/(\\*\\*|__)(?=\\S)([\\s\\S]*?\\S)\\1/g, '<strong>$2</strong>')\n .replace(/(?<![*\\w])\\*(?=\\S)([^*]*?\\S)\\*(?![*\\w])/g, '<em>$1</em>')\n .replace(/(?<![_\\w])_(?=\\S)([^_]*?\\S)_(?![_\\w])/g, '<em>$1</em>')\n .replace(/~~(?=\\S)([\\s\\S]*?\\S)~~/g, '<s>$1</s>');\n\n return out\n .replace(new RegExp(`${ESCAPED}(\\\\d+)${ESCAPED}`, 'g'), (_, index: string) => escapes[Number(index)])\n .replace(new RegExp(`${SPAN}(\\\\d+)${SPAN}`, 'g'), (_, index: string) => `<code>${codeSpans[Number(index)]}</code>`);\n}\n","import { InjectionToken, inject, type Provider } from '@angular/core';\nimport { createXConfigToken } from '@xui/core';\nimport { bbcodeSyntax } from './bbcode-syntax';\nimport { markdownSyntax } from './markdown-syntax';\nimport type { XuiRichTextSyntax } from './rich-text-syntax';\n\nexport interface XuiRichTextEditorConfig {\n /** Which format new editors start in. */\n format: string;\n /** Text shown while the editor is empty. */\n placeholder: string;\n /** Offer the source-text view alongside the formatted one. */\n sourceView: boolean;\n}\n\n/** Application-wide defaults for every editor. Individual inputs still win. */\nexport const [injectXuiRichTextEditorConfig, provideXuiRichTextEditorConfig] =\n createXConfigToken<XuiRichTextEditorConfig>('XuiRichTextEditorConfig', {\n format: 'markdown',\n placeholder: '',\n sourceView: true\n });\n\nconst XuiRichTextSyntaxToken = new InjectionToken<readonly XuiRichTextSyntax[]>('XuiRichTextSyntax');\n\n/**\n * Teaches the editor a format.\n *\n * Markdown and BBCode are built in; this adds to them, or replaces one by\n * registering a syntax under the same name — the last one provided wins, so an\n * app can swap in its own flavour of Markdown without forking the editor.\n *\n * ```ts\n * provideXuiRichTextSyntax({\n * name: 'plain',\n * features: ['bold'],\n * toHtml: text => `<p>${text}</p>`,\n * fromHtml: root => root.textContent ?? ''\n * });\n * ```\n */\nexport function provideXuiRichTextSyntax(...syntaxes: XuiRichTextSyntax[]): Provider {\n return { provide: XuiRichTextSyntaxToken, useValue: syntaxes, multi: true };\n}\n\n/**\n * Every known syntax, by name. Built-ins first, so anything provided by the app\n * that reuses a name replaces it.\n */\nexport function injectXuiRichTextSyntaxes(): Map<string, XuiRichTextSyntax> {\n const provided = inject(XuiRichTextSyntaxToken, { optional: true }) as XuiRichTextSyntax[][] | null;\n\n return new Map([markdownSyntax, bbcodeSyntax, ...(provided ?? []).flat()].map(syntax => [syntax.name, syntax]));\n}\n","import type { BooleanInput } from '@angular/cdk/coercion';\nimport {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n ViewEncapsulation,\n booleanAttribute,\n computed,\n effect,\n input,\n model,\n signal,\n viewChild\n} from '@angular/core';\nimport { ControlValueAccessor } from '@angular/forms';\nimport { NgIcon, provideIcons } from '@ng-icons/core';\nimport {\n matCodeRound,\n matFormatBoldRound,\n matFormatItalicRound,\n matFormatListBulletedRound,\n matFormatListNumberedRound,\n matFormatQuoteRound,\n matFormatStrikethroughRound,\n matFormatUnderlinedRound,\n matHorizontalRuleRound,\n matLinkRound,\n matTerminalRound\n} from '@ng-icons/material-icons/round';\nimport { xui } from '@xui/core';\nimport { createXValueAccessor, provideXValueAccessor } from '@xui/core/forms';\nimport { XuiIcon } from '@xui/icon';\nimport type { ClassValue } from 'clsx';\nimport { injectXuiRichTextEditorConfig, injectXuiRichTextSyntaxes } from './rich-text-editor.token';\nimport type { XuiRichTextFeature } from './rich-text-syntax';\n\ninterface Tool {\n readonly feature: XuiRichTextFeature;\n readonly label: string;\n readonly icon?: string;\n readonly text?: string;\n /** `document.execCommand` name, and its argument where one is needed. */\n readonly command: string;\n readonly argument?: string;\n /** How the button's pressed state is read back from the document. */\n readonly state: 'command' | 'block' | 'none';\n readonly key?: string;\n}\n\n/**\n * The full toolbar, in order. Each editor shows the entries its format can\n * express — the same button set can therefore never produce markup the format\n * cannot round-trip.\n */\nconst TOOLS: readonly Tool[] = [\n { feature: 'bold', label: 'Bold', icon: 'matFormatBoldRound', command: 'bold', state: 'command', key: 'b' },\n { feature: 'italic', label: 'Italic', icon: 'matFormatItalicRound', command: 'italic', state: 'command', key: 'i' },\n {\n feature: 'underline',\n label: 'Underline',\n icon: 'matFormatUnderlinedRound',\n command: 'underline',\n state: 'command',\n key: 'u'\n },\n {\n feature: 'strike',\n label: 'Strikethrough',\n icon: 'matFormatStrikethroughRound',\n command: 'strikeThrough',\n state: 'command'\n },\n { feature: 'code', label: 'Inline code', icon: 'matCodeRound', command: 'xuiCode', state: 'none' },\n { feature: 'link', label: 'Link', icon: 'matLinkRound', command: 'xuiLink', state: 'none', key: 'k' },\n { feature: 'heading1', label: 'Heading 1', text: 'H1', command: 'formatBlock', argument: 'h1', state: 'block' },\n { feature: 'heading2', label: 'Heading 2', text: 'H2', command: 'formatBlock', argument: 'h2', state: 'block' },\n { feature: 'heading3', label: 'Heading 3', text: 'H3', command: 'formatBlock', argument: 'h3', state: 'block' },\n {\n feature: 'bulletList',\n label: 'Bulleted list',\n icon: 'matFormatListBulletedRound',\n command: 'insertUnorderedList',\n state: 'command'\n },\n {\n feature: 'orderedList',\n label: 'Numbered list',\n icon: 'matFormatListNumberedRound',\n command: 'insertOrderedList',\n state: 'command'\n },\n {\n feature: 'quote',\n label: 'Quote',\n icon: 'matFormatQuoteRound',\n command: 'formatBlock',\n argument: 'blockquote',\n state: 'block'\n },\n {\n feature: 'codeBlock',\n label: 'Code block',\n icon: 'matTerminalRound',\n command: 'formatBlock',\n argument: 'pre',\n state: 'block'\n },\n {\n feature: 'rule',\n label: 'Divider',\n icon: 'matHorizontalRuleRound',\n command: 'insertHorizontalRule',\n state: 'none'\n }\n];\n\n/**\n * A WYSIWYG editor whose value is source text.\n *\n * The user works on formatted content; the binding is the Markdown or BBCode\n * you store — so nothing downstream has to know an editor was involved, and\n * nothing has to be sanitised on the way out.\n *\n * ```html\n * <xui-rich-text-editor [(value)]=\"comment\" format=\"markdown\" placeholder=\"Say something…\" />\n * ```\n *\n * ```html\n * <xui-rich-text-editor formControlName=\"post\" format=\"bbcode\" />\n * ```\n *\n * The toolbar is the format's capabilities: Markdown offers headings and a\n * divider but no underline, BBCode the reverse. Teach it a new format with\n * {@link provideXuiRichTextSyntax} and the toolbar follows.\n *\n * The source view (`</>`) shows the text itself, editable, and the two stay in\n * step. Pasting always lands as plain text — foreign HTML never enters the\n * document, so the value cannot carry markup the format does not define.\n */\n@Component({\n selector: 'xui-rich-text-editor',\n imports: [NgIcon, XuiIcon],\n template: `\n <div\n role=\"toolbar\"\n aria-label=\"Formatting\"\n class=\"border-border bg-surface-sunken flex flex-wrap items-center gap-0.5 rounded-t-lg border-b p-1\"\n >\n @for (tool of tools(); track tool.feature) {\n <button\n type=\"button\"\n [class]=\"toolClass()\"\n [attr.aria-label]=\"tool.label\"\n [attr.aria-pressed]=\"tool.state === 'none' ? null : active().includes(tool.feature)\"\n [attr.data-active]=\"active().includes(tool.feature) ? '' : null\"\n [disabled]=\"isDisabled() || source()\"\n [title]=\"tool.label\"\n (mousedown)=\"$event.preventDefault()\"\n (click)=\"run(tool)\"\n >\n @if (tool.icon) {\n <ng-icon xui size=\"sm\" [name]=\"tool.icon\" />\n } @else {\n <span class=\"px-0.5 text-xs font-semibold\">{{ tool.text }}</span>\n }\n </button>\n }\n\n @if (sourceView()) {\n <button\n type=\"button\"\n [class]=\"toolClass()\"\n class=\"ms-auto\"\n aria-label=\"Source\"\n [attr.aria-pressed]=\"source()\"\n [attr.data-active]=\"source() ? '' : null\"\n [disabled]=\"isDisabled()\"\n title=\"Source\"\n (click)=\"toggleSource()\"\n >\n <span class=\"px-0.5 text-xs font-semibold\">&lt;/&gt;</span>\n </button>\n }\n </div>\n\n @if (linkDraft() !== null) {\n <div class=\"border-border bg-surface-sunken flex items-center gap-1 border-b p-1\">\n <input\n #linkField\n type=\"url\"\n class=\"text-foreground placeholder:text-foreground-subtle min-w-0 flex-1 bg-transparent px-2 py-1 text-sm outline-none\"\n placeholder=\"https://example.com\"\n aria-label=\"Link URL\"\n [value]=\"linkDraft()\"\n (input)=\"linkDraft.set($any($event.target).value)\"\n (keydown.enter)=\"applyLink(); $event.preventDefault()\"\n (keydown.escape)=\"linkDraft.set(null)\"\n />\n <button type=\"button\" [class]=\"toolClass()\" class=\"text-xs\" (click)=\"applyLink()\">Apply</button>\n <button type=\"button\" [class]=\"toolClass()\" class=\"text-xs\" (click)=\"linkDraft.set(null)\">Cancel</button>\n </div>\n }\n\n @if (source()) {\n <textarea\n class=\"text-foreground placeholder:text-foreground-subtle block w-full resize-y bg-transparent p-3 font-mono text-sm outline-none\"\n [style.min-height.px]=\"minHeight()\"\n [attr.aria-label]=\"'Source (' + format() + ')'\"\n [disabled]=\"isDisabled()\"\n [value]=\"value()\"\n (input)=\"onSourceInput($event)\"\n (blur)=\"cva.markTouched()\"\n ></textarea>\n } @else {\n <div class=\"relative\">\n @if (!value().trim() && placeholder()) {\n <p class=\"text-foreground-subtle pointer-events-none absolute p-3 select-none\">{{ placeholder() }}</p>\n }\n\n <!-- eslint-disable-next-line @angular-eslint/template/interactive-supports-focus -->\n <div\n #surface\n role=\"textbox\"\n aria-multiline=\"true\"\n [class]=\"surfaceClass()\"\n [style.min-height.px]=\"minHeight()\"\n [attr.contenteditable]=\"isDisabled() ? null : true\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-disabled]=\"isDisabled() ? true : null\"\n (input)=\"pull()\"\n (blur)=\"cva.markTouched()\"\n (paste)=\"onPaste($event)\"\n (keydown)=\"onKeydown($event)\"\n (keyup)=\"refreshActive()\"\n (mouseup)=\"refreshActive()\"\n ></div>\n </div>\n }\n `,\n host: {\n '[class]': 'computedClass()',\n '[attr.data-disabled]': 'isDisabled() ? \"\" : null'\n },\n providers: [provideXValueAccessor(() => XuiRichTextEditor)],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n viewProviders: [\n provideIcons({\n matCodeRound,\n matFormatBoldRound,\n matFormatItalicRound,\n matFormatListBulletedRound,\n matFormatListNumberedRound,\n matFormatQuoteRound,\n matFormatStrikethroughRound,\n matFormatUnderlinedRound,\n matHorizontalRuleRound,\n matLinkRound,\n matTerminalRound\n })\n ]\n})\nexport class XuiRichTextEditor implements ControlValueAccessor {\n private readonly config = injectXuiRichTextEditorConfig();\n private readonly syntaxes = injectXuiRichTextSyntaxes();\n private readonly surface = viewChild<ElementRef<HTMLElement>>('surface');\n private readonly linkField = viewChild<ElementRef<HTMLInputElement>>('linkField');\n\n readonly class = input<ClassValue>('');\n\n /** The source text, in the active `format`. Two-way bindable, and the form value. */\n readonly value = model<string>('');\n\n /** `'markdown'`, `'bbcode'`, or any format registered with `provideXuiRichTextSyntax`. */\n readonly format = input<string>(this.config.format);\n\n readonly placeholder = input<string>(this.config.placeholder);\n\n /** Offer the source-text toggle. */\n readonly sourceView = input<boolean, BooleanInput>(this.config.sourceView, { transform: booleanAttribute });\n\n readonly disabled = input<boolean, BooleanInput>(false, { transform: booleanAttribute });\n\n /** Height of the writing area before it grows with the content. */\n readonly minHeight = input<number>(180);\n\n readonly ariaLabel = input<string | undefined>(undefined, { alias: 'aria-label' });\n\n /** Whether the source view is showing. Two-way bindable. */\n readonly source = model(false);\n\n protected readonly linkDraft = signal<string | null>(null);\n protected readonly active = signal<XuiRichTextFeature[]>([]);\n\n protected readonly cva = createXValueAccessor<string>({\n onWrite: value => {\n this.value.set(value ?? '');\n // Force the next render: the value came from outside, so whatever is in\n // the surface is stale even if the string matches what we last serialised.\n this.synced = null;\n },\n disabled: this.disabled\n });\n protected readonly isDisabled = this.cva.disabled;\n\n /**\n * The value the surface already shows, tagged with the format it was rendered\n * in. Re-rendering the user's own keystrokes would reset the caret on every\n * one, so the effect below writes only when this no longer matches.\n */\n private synced: string | null = null;\n /** The element that value went into — the source toggle builds a new one. */\n private syncedSurface: HTMLElement | null = null;\n /** What the link is to wrap, held while the URL field has the selection. */\n private savedRange: Range | null = null;\n\n private readonly syntax = computed(() => {\n const syntax = this.syntaxes.get(this.format());\n\n if (!syntax) {\n throw new Error(\n `@xui/rich-text-editor: unknown format \"${this.format()}\". ` +\n `Known formats: ${[...this.syntaxes.keys()].join(', ')}. Register others with provideXuiRichTextSyntax().`\n );\n }\n\n return syntax;\n });\n\n protected readonly tools = computed(() => {\n const features = this.syntax().features;\n\n return TOOLS.filter(tool => features.includes(tool.feature));\n });\n\n protected readonly computedClass = computed(() =>\n xui(\n 'border-border bg-surface-inset text-foreground block overflow-hidden rounded-lg border',\n 'focus-within:border-focus transition-colors',\n 'data-disabled:cursor-not-allowed data-disabled:opacity-50',\n '[&.ng-invalid.ng-touched]:border-error',\n this.class()\n )\n );\n\n // A disabled tool keeps its pointer events so the cursor can say it is unavailable — an element\n // that receives none contributes no cursor either. The native `disabled` swallows the click, and\n // `enabled:` keeps the hover lift off a tool that cannot be used.\n protected readonly toolClass = computed(() =>\n xui(\n 'text-foreground-muted enabled:hover:bg-surface-raised enabled:hover:text-foreground flex items-center rounded px-1.5 py-1',\n 'data-active:bg-surface-raised data-active:text-foreground disabled:cursor-not-allowed disabled:opacity-50'\n )\n );\n\n /** Tailwind resets block elements, so the writing area re-states how prose looks. */\n protected readonly surfaceClass = computed(() =>\n xui(\n 'block p-3 outline-none [&>*+*]:mt-2',\n '[&_h1]:text-2xl [&_h1]:font-semibold [&_h2]:text-xl [&_h2]:font-semibold [&_h3]:text-lg [&_h3]:font-semibold',\n '[&_ul]:list-disc [&_ol]:list-decimal [&_ul]:ps-6 [&_ol]:ps-6',\n '[&_blockquote]:border-border-strong [&_blockquote]:text-foreground-muted [&_blockquote]:border-s-2 [&_blockquote]:ps-3',\n '[&_pre]:bg-surface-sunken [&_pre]:rounded [&_pre]:p-2 [&_pre]:font-mono [&_pre]:text-sm',\n '[&_code]:bg-surface-sunken [&_code]:rounded [&_code]:px-1 [&_code]:font-mono [&_code]:text-sm',\n '[&_pre_code]:bg-transparent [&_pre_code]:p-0',\n '[&_a]:text-link [&_a]:underline',\n '[&_hr]:border-border [&_hr]:my-3'\n )\n );\n\n constructor() {\n // Enter should start a paragraph, and marks should be tags rather than\n // inline styles — otherwise there is nothing for a syntax to recognise.\n safely(() => document.execCommand?.('defaultParagraphSeparator', false, 'p'));\n safely(() => document.execCommand?.('styleWithCSS', false, 'false'));\n\n // Renders whenever the value arrives from outside — a binding, a form, the\n // source toggle — and skips the echo of the user's own typing, which would\n // otherwise reset the caret on every keystroke.\n effect(() => {\n const surface = this.surface()?.nativeElement;\n const value = this.value();\n const key = this.syncKey(value);\n\n if (!surface || (key === this.synced && surface === this.syncedSurface)) {\n return;\n }\n\n this.syncedSurface = surface;\n\n // A format switch keeps the content and changes only how it is written\n // down: the document is the same either way, so it is re-read in the new\n // format rather than re-rendered from text the new format cannot parse.\n if (this.synced && !this.synced.startsWith(`${this.format()}:`) && surface.innerHTML) {\n const translated = this.syntax().fromHtml(surface);\n\n this.synced = this.syncKey(translated);\n this.value.set(translated);\n this.cva.notifyChange(translated);\n\n return;\n }\n\n surface.innerHTML = this.syntax().toHtml(value);\n this.synced = key;\n });\n\n effect(() => {\n if (this.linkDraft() !== null) {\n this.linkField()?.nativeElement.focus();\n }\n });\n }\n\n /** The editing surface, for consumers who need to focus it. */\n focus(): void {\n this.surface()?.nativeElement.focus();\n }\n\n /** Show the formatted view (`false`) or the source text (`true`). */\n protected toggleSource(): void {\n this.source.update(source => !source);\n }\n\n protected onSourceInput(event: Event): void {\n this.commit((event.target as HTMLTextAreaElement).value);\n }\n\n /** Reads the surface back out as source text. */\n protected pull(): void {\n const surface = this.surface()?.nativeElement;\n\n if (!surface) {\n return;\n }\n\n this.commit(this.syntax().fromHtml(surface));\n this.refreshActive();\n }\n\n protected onKeydown(event: KeyboardEvent): void {\n if (!(event.metaKey || event.ctrlKey)) {\n return;\n }\n\n const tool = this.tools().find(candidate => candidate.key === event.key.toLowerCase());\n\n if (tool) {\n event.preventDefault();\n this.run(tool);\n }\n }\n\n /**\n * Paste as plain text.\n *\n * Whatever is on the clipboard — a Word document, half a web page — would\n * otherwise arrive as HTML the format cannot express and the editor would\n * have to guess at. The text is inserted as typed instead.\n */\n protected onPaste(event: ClipboardEvent): void {\n event.preventDefault();\n\n const text = event.clipboardData?.getData('text/plain') ?? '';\n\n this.exec('insertText', text);\n this.pull();\n }\n\n protected run(tool: Tool): void {\n if (this.isDisabled() || this.source()) {\n return;\n }\n\n if (tool.command === 'xuiLink') {\n // Captured before anything touches focus: the URL field is about to take\n // the document selection, and this is the range the link must wrap.\n this.savedRange = currentRange();\n // The field appears with the draft; an effect focuses it once it exists.\n this.linkDraft.set('');\n\n return;\n }\n\n this.focus();\n\n if (tool.command === 'xuiCode') {\n this.wrapSelection('code');\n } else if (tool.command === 'formatBlock') {\n // A second press on the same block returns it to a paragraph.\n const target = this.active().includes(tool.feature) ? 'p' : tool.argument!;\n\n this.exec('formatBlock', target);\n } else {\n this.exec(tool.command, tool.argument);\n }\n\n this.pull();\n }\n\n protected applyLink(): void {\n const href = this.linkDraft()?.trim();\n\n this.linkDraft.set(null);\n this.focus();\n this.restoreSelection();\n\n if (href) {\n this.exec('createLink', href);\n this.pull();\n }\n }\n\n /** Puts the caret back where it was before the URL field took focus. */\n private restoreSelection(): void {\n const selection = getSelection();\n\n if (!this.savedRange || !selection) {\n return;\n }\n\n selection.removeAllRanges();\n selection.addRange(this.savedRange);\n this.savedRange = null;\n }\n\n /** Reflects the caret's formatting on the toolbar. */\n protected refreshActive(): void {\n if (typeof document === 'undefined' || !document.queryCommandState) {\n return;\n }\n\n const block = document.queryCommandValue?.('formatBlock')?.toLowerCase();\n\n this.active.set(\n this.tools()\n .filter(tool => {\n if (tool.state === 'command') {\n return safely(() => document.queryCommandState(tool.command));\n }\n\n return tool.state === 'block' && block === tool.argument;\n })\n .map(tool => tool.feature)\n );\n }\n\n /** Wraps the selection in a tag, or unwraps it when it is already wrapped. */\n private wrapSelection(tag: string): void {\n const selection = getSelection();\n\n if (!selection?.rangeCount) {\n return;\n }\n\n const range = selection.getRangeAt(0);\n const existing = closest(range.commonAncestorContainer, tag);\n\n if (existing) {\n existing.replaceWith(...Array.from(existing.childNodes));\n\n return;\n }\n\n if (!range.collapsed) {\n this.exec('insertHTML', `<${tag}>${escapeText(range.toString())}</${tag}>`);\n }\n }\n\n private exec(command: string, argument?: string): void {\n // `execCommand` is the only editing API every browser implements for\n // contenteditable; absent under a test DOM, where nothing is being edited.\n safely(() => document.execCommand?.(command, false, argument));\n }\n\n private commit(next: string): void {\n if (next === this.value()) {\n return;\n }\n\n // The surface already shows this — recorded before the write so the render\n // effect sees it and leaves the caret where the user put it.\n this.synced = this.syncKey(next);\n this.value.set(next);\n this.cva.notifyChange(next);\n }\n\n private syncKey(value: string): string {\n return `${this.format()}:${value}`;\n }\n\n // --- ControlValueAccessor ---\n readonly writeValue = this.cva.writeValue;\n readonly registerOnChange = this.cva.registerOnChange;\n readonly registerOnTouched = this.cva.registerOnTouched;\n readonly setDisabledState = this.cva.setDisabledState;\n}\n\nfunction currentRange(): Range | null {\n const selection = getSelection();\n\n return selection?.rangeCount ? selection.getRangeAt(0).cloneRange() : null;\n}\n\n/** The nearest ancestor with `tag`, starting at `node` itself. */\nfunction closest(node: Node, tag: string): Element | null {\n const element = node instanceof Element ? node : node.parentElement;\n\n return element?.closest(tag) ?? null;\n}\n\nfunction escapeText(text: string): string {\n return text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');\n}\n\n/** Runs `fn`, treating a DOM that does not implement it as \"no\". */\nfunction safely(fn: () => boolean | void): boolean {\n try {\n return fn() === true;\n } catch {\n return false;\n }\n}\n","import { XuiRichTextEditor } from './lib/rich-text-editor';\n\nexport * from './lib/bbcode-syntax';\nexport * from './lib/markdown-syntax';\nexport * from './lib/rich-text-editor';\nexport * from './lib/rich-text-editor.token';\nexport * from './lib/rich-text-syntax';\n\nexport const XuiRichTextEditorImports = [XuiRichTextEditor] as const;\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["FEATURES","writer","inlineToHtml"],"mappings":"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"}
1
+ {"version":3,"file":"xui-rich-text-editor.mjs","sources":["../../../../../../libs/ui/rich-text-editor/xui/src/lib/rich-text-syntax.ts","../../../../../../libs/ui/rich-text-editor/xui/src/lib/bbcode-syntax.ts","../../../../../../libs/ui/rich-text-editor/xui/src/lib/markdown-syntax.ts","../../../../../../libs/ui/rich-text-editor/xui/src/lib/rich-text-editor.token.ts","../../../../../../libs/ui/rich-text-editor/xui/src/lib/rich-text-editor.ts","../../../../../../libs/ui/rich-text-editor/xui/src/index.ts","../../../../../../libs/ui/rich-text-editor/xui/src/xui-rich-text-editor.ts"],"sourcesContent":["/**\n * A formatting feature. The editor's toolbar offers exactly the features the\n * active syntax declares, so nothing can be applied that the format cannot\n * express — Markdown has no underline, BBCode has no headings.\n */\nexport type XuiRichTextMark = 'bold' | 'italic' | 'underline' | 'strike' | 'code' | 'link';\n\nexport type XuiRichTextBlock =\n 'heading1' | 'heading2' | 'heading3' | 'bulletList' | 'orderedList' | 'quote' | 'codeBlock' | 'rule';\n\nexport type XuiRichTextFeature = XuiRichTextMark | XuiRichTextBlock;\n\n/**\n * Turns the editor's HTML into source text.\n *\n * The editor edits one canonical HTML subset — `p`, `h1`–`h3`, `ul`/`ol`,\n * `blockquote`, `pre`, `hr` and the inline marks — and a syntax is only the\n * translation at each end. Implement one to teach the editor a new format;\n * nothing else changes.\n */\nexport interface XuiRichTextWriter {\n /** Escape text so the syntax's own punctuation is not read as markup. */\n escape(text: string): string;\n /** Wrap `inner` in a mark, or return it untouched when the syntax lacks one. */\n mark(kind: XuiRichTextMark, inner: string, href?: string): string;\n /** Wrap a block's already-serialised inline content. */\n block(kind: 'paragraph' | 'heading1' | 'heading2' | 'heading3' | 'quote', inner: string): string;\n /** A whole list, given its already-serialised items. */\n list(items: string[], ordered: boolean): string;\n /** Verbatim text — never escaped, never marked up. */\n codeBlock(text: string): string;\n /** A thematic break. */\n rule(): string;\n}\n\n/** Both directions of one text format. */\nexport interface XuiRichTextSyntax {\n /** How the format is named in the `format` input — `'markdown'`, `'bbcode'`, … */\n readonly name: string;\n /** What this format can express. Anything absent is left out of the toolbar. */\n readonly features: readonly XuiRichTextFeature[];\n /** Source text → the editor's HTML subset. Must return markup it produced itself. */\n toHtml(source: string): string;\n /** The editor's HTML → source text. */\n fromHtml(root: HTMLElement): string;\n}\n\nconst MARK_TAGS: Record<string, XuiRichTextMark> = {\n STRONG: 'bold',\n B: 'bold',\n EM: 'italic',\n I: 'italic',\n U: 'underline',\n S: 'strike',\n STRIKE: 'strike',\n DEL: 'strike',\n CODE: 'code',\n A: 'link'\n};\n\n/**\n * Walks the editor's HTML and hands each piece to `writer`.\n *\n * Shared by every syntax so they only describe *what* their markup looks like,\n * never how to traverse a DOM — and so a new syntax cannot get the traversal\n * subtly wrong.\n */\nexport function serializeHtml(root: HTMLElement, writer: XuiRichTextWriter): string {\n const blocks: string[] = [];\n\n for (const node of Array.from(root.childNodes)) {\n const block = serializeBlock(node, writer);\n\n if (block !== null) {\n blocks.push(block);\n }\n }\n\n return blocks.filter(block => block !== '').join('\\n\\n');\n}\n\nfunction serializeBlock(node: Node, writer: XuiRichTextWriter): string | null {\n if (node.nodeType === Node.TEXT_NODE) {\n const text = node.textContent ?? '';\n\n // Loose text between blocks — browsers leave it there after some edits.\n return text.trim() ? writer.block('paragraph', writer.escape(text)) : null;\n }\n\n if (!(node instanceof Element)) {\n return null;\n }\n\n switch (node.tagName) {\n case 'H1':\n return writer.block('heading1', serializeInline(node, writer));\n case 'H2':\n return writer.block('heading2', serializeInline(node, writer));\n case 'H3':\n return writer.block('heading3', serializeInline(node, writer));\n case 'BLOCKQUOTE':\n return writer.block('quote', quoteContent(node as HTMLElement, writer));\n case 'PRE':\n return writer.codeBlock(node.textContent ?? '');\n case 'HR':\n return writer.rule();\n case 'UL':\n case 'OL':\n return writer.list(\n Array.from(node.children)\n .filter(child => child.tagName === 'LI')\n .map(item => serializeInline(item, writer)),\n node.tagName === 'OL'\n );\n case 'BR':\n return null;\n default:\n // `p`, `div` (what some browsers still produce on Enter), and anything\n // else that reached the top level: treat as a paragraph.\n return writer.block('paragraph', serializeInline(node, writer));\n }\n}\n\n/** A quote may hold blocks of its own; flatten them to lines. */\nfunction quoteContent(node: HTMLElement, writer: XuiRichTextWriter): string {\n const hasBlocks = Array.from(node.children).some(child => /^(P|DIV|H[1-3])$/.test(child.tagName));\n\n if (!hasBlocks) {\n return serializeInline(node, writer);\n }\n\n return Array.from(node.children)\n .map(child => serializeInline(child, writer))\n .filter(Boolean)\n .join('\\n');\n}\n\nfunction serializeInline(node: Node, writer: XuiRichTextWriter): string {\n let out = '';\n\n for (const child of Array.from(node.childNodes)) {\n if (child.nodeType === Node.TEXT_NODE) {\n out += writer.escape(child.textContent ?? '');\n continue;\n }\n\n if (!(child instanceof Element)) {\n continue;\n }\n\n if (child.tagName === 'BR') {\n out += '\\n';\n continue;\n }\n\n const mark = MARK_TAGS[child.tagName];\n const inner = child.tagName === 'CODE' ? writer.escape(child.textContent ?? '') : serializeInline(child, writer);\n\n out += mark ? writer.mark(mark, inner, child.getAttribute('href') ?? undefined) : inner;\n }\n\n return out;\n}\n\n/** Escapes text for insertion into the editor's HTML. */\nexport function escapeHtml(text: string): string {\n return text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;');\n}\n\n/**\n * Keeps `javascript:` and friends out of an `href`.\n *\n * Source text is user input as far as this package is concerned — a comment, a\n * forum post — so a link is only ever emitted when its scheme is one that can\n * do nothing but navigate.\n */\nexport function sanitizeUrl(url: string): string {\n const trimmed = url.trim();\n\n return /^(https?:|mailto:|tel:|\\/|#|\\.)/i.test(trimmed) ? trimmed : '';\n}\n","import {\n escapeHtml,\n sanitizeUrl,\n serializeHtml,\n type XuiRichTextFeature,\n type XuiRichTextSyntax,\n type XuiRichTextWriter\n} from './rich-text-syntax';\n\n/**\n * The BBCode this syntax reads and writes.\n *\n * The tags every forum agrees on. BBCode has underline, which Markdown lacks;\n * it has no headings and no thematic break, so the toolbar drops those — the\n * format decides what the toolbar offers, not the other way round.\n */\nconst FEATURES: readonly XuiRichTextFeature[] = [\n 'bold',\n 'italic',\n 'underline',\n 'strike',\n 'link',\n 'bulletList',\n 'orderedList',\n 'quote',\n 'codeBlock'\n];\n\nconst writer: XuiRichTextWriter = {\n // BBCode has no escape character. A stray `[` is only ambiguous next to a tag\n // name, so that is the one case worth neutralising.\n escape: text => text.replace(/\\[(?=\\/?[a-z*]+[\\]=])/gi, '&#91;'),\n mark: (kind, inner, href) => {\n switch (kind) {\n case 'bold':\n return `[b]${inner}[/b]`;\n case 'italic':\n return `[i]${inner}[/i]`;\n case 'underline':\n return `[u]${inner}[/u]`;\n case 'strike':\n return `[s]${inner}[/s]`;\n case 'link':\n return href ? `[url=${href}]${inner}[/url]` : inner;\n // No inline-code tag in BBCode: `[code]` is a block everywhere.\n default:\n return inner;\n }\n },\n block: (kind, inner) => {\n switch (kind) {\n case 'quote':\n return `[quote]${inner}[/quote]`;\n // Headings degrade to plain paragraphs rather than to a `[size]` guess.\n default:\n return inner;\n }\n },\n list: (items, ordered) => [ordered ? '[list=1]' : '[list]', ...items.map(item => `[*]${item}`), '[/list]'].join('\\n'),\n codeBlock: text => `[code]\\n${text.replace(/\\n$/, '')}\\n[/code]`,\n rule: () => ''\n};\n\n/** BBCode ⇄ the editor's HTML. */\nexport const bbcodeSyntax: XuiRichTextSyntax = {\n name: 'bbcode',\n features: FEATURES,\n fromHtml: root => serializeHtml(root, writer),\n toHtml: source => bbcodeToHtml(source)\n};\n\n/** `[tag]…[/tag]` → HTML element, innermost pair first. */\nconst PAIRS: [RegExp, string][] = [\n [/\\[b]([\\s\\S]*?)\\[\\/b]/gi, '<strong>$1</strong>'],\n [/\\[i]([\\s\\S]*?)\\[\\/i]/gi, '<em>$1</em>'],\n [/\\[u]([\\s\\S]*?)\\[\\/u]/gi, '<u>$1</u>'],\n [/\\[s]([\\s\\S]*?)\\[\\/s]/gi, '<s>$1</s>']\n];\n\nfunction bbcodeToHtml(source: string): string {\n const blocks = splitBlocks(source.replace(/\\r\\n?/g, '\\n'));\n\n return blocks.join('');\n}\n\n/**\n * Block tags first — they own whole lines and may hold inline markup — then\n * whatever is left becomes paragraphs.\n */\nfunction splitBlocks(source: string): string[] {\n const html: string[] = [];\n const pattern = /\\[(code|quote|list)(=1)?]([\\s\\S]*?)\\[\\/\\1]/gi;\n let cursor = 0;\n let match: RegExpExecArray | null;\n\n while ((match = pattern.exec(source)) !== null) {\n html.push(...paragraphs(source.slice(cursor, match.index)));\n cursor = match.index + match[0].length;\n\n const [, tag, ordered, body] = match;\n\n if (tag.toLowerCase() === 'code') {\n html.push(`<pre>${escapeHtml(body.replace(/^\\n|\\n$/g, ''))}</pre>`);\n continue;\n }\n\n if (tag.toLowerCase() === 'quote') {\n html.push(`<blockquote>${paragraphs(body).join('') || '<p></p>'}</blockquote>`);\n continue;\n }\n\n const items = body\n .split(/\\[\\*]/)\n .map(item => item.trim())\n .filter(Boolean)\n .map(item => `<li>${inlineToHtml(item)}</li>`)\n .join('');\n\n html.push(ordered ? `<ol>${items}</ol>` : `<ul>${items}</ul>`);\n }\n\n html.push(...paragraphs(source.slice(cursor)));\n\n return html;\n}\n\nfunction paragraphs(source: string): string[] {\n return source\n .split(/\\n{2,}/)\n .map(block => block.replace(/^\\n+|\\n+$/g, ''))\n .filter(block => block.trim())\n .map(block => `<p>${block.split('\\n').map(inlineToHtml).join('<br>')}</p>`);\n}\n\nfunction inlineToHtml(text: string): string {\n let out = escapeHtml(text).replace(\n /\\[url(?:=([^\\]]+))?]([\\s\\S]*?)\\[\\/url]/gi,\n (match, href: string, label: string) => {\n const url = sanitizeUrl(href ?? label);\n\n return url ? `<a href=\"${escapeHtml(url)}\">${label || escapeHtml(url)}</a>` : match;\n }\n );\n\n for (const [pattern, replacement] of PAIRS) {\n // Non-greedy matches close the innermost pair first, so repeating until the\n // text settles unwraps nested tags from the inside out.\n let previous: string;\n\n do {\n previous = out;\n out = out.replace(pattern, replacement);\n } while (out !== previous);\n }\n\n return out;\n}\n","import {\n escapeHtml,\n sanitizeUrl,\n serializeHtml,\n type XuiRichTextFeature,\n type XuiRichTextSyntax,\n type XuiRichTextWriter\n} from './rich-text-syntax';\n\n/**\n * The Markdown this syntax reads and writes.\n *\n * A deliberately small, portable subset — what a comment box needs and what\n * every Markdown renderer agrees on. No tables, footnotes, images or HTML\n * passthrough; no underline, which Markdown has no syntax for.\n */\nconst FEATURES: readonly XuiRichTextFeature[] = [\n 'bold',\n 'italic',\n 'strike',\n 'code',\n 'link',\n 'heading1',\n 'heading2',\n 'heading3',\n 'bulletList',\n 'orderedList',\n 'quote',\n 'codeBlock',\n 'rule'\n];\n\nconst writer: XuiRichTextWriter = {\n escape: text => text.replace(/([\\\\`*_[\\]#>~])/g, '\\\\$1'),\n mark: (kind, inner, href) => {\n switch (kind) {\n case 'bold':\n return `**${inner}**`;\n case 'italic':\n return `*${inner}*`;\n case 'strike':\n return `~~${inner}~~`;\n case 'code':\n // Code spans are verbatim, so the backslashes `escape` added are noise.\n return `\\`${inner.replace(/\\\\([\\\\`*_[\\]#>~])/g, '$1')}\\``;\n case 'link':\n return href ? `[${inner}](${href})` : inner;\n // Markdown cannot underline. Rather than invent `<u>`, the text stays put.\n default:\n return inner;\n }\n },\n block: (kind, inner) => {\n switch (kind) {\n case 'heading1':\n return `# ${inner}`;\n case 'heading2':\n return `## ${inner}`;\n case 'heading3':\n return `### ${inner}`;\n case 'quote':\n return inner\n .split('\\n')\n .map(line => `> ${line}`)\n .join('\\n');\n default:\n return inner;\n }\n },\n list: (items, ordered) => items.map((item, index) => (ordered ? `${index + 1}. ${item}` : `- ${item}`)).join('\\n'),\n codeBlock: text => `\\`\\`\\`\\n${text.replace(/\\n$/, '')}\\n\\`\\`\\``,\n rule: () => '---'\n};\n\n/** Markdown ⇄ the editor's HTML. */\nexport const markdownSyntax: XuiRichTextSyntax = {\n name: 'markdown',\n features: FEATURES,\n fromHtml: root => serializeHtml(root, writer),\n toHtml: source => blocksToHtml(source)\n};\n\nfunction blocksToHtml(source: string): string {\n const lines = source.replace(/\\r\\n?/g, '\\n').split('\\n');\n const html: string[] = [];\n let index = 0;\n\n while (index < lines.length) {\n const line = lines[index];\n\n if (!line.trim()) {\n index++;\n continue;\n }\n\n // Fenced code: verbatim until the closing fence, or the end of the input.\n if (/^```/.test(line)) {\n const code: string[] = [];\n\n index++;\n\n while (index < lines.length && !/^```/.test(lines[index])) {\n code.push(lines[index++]);\n }\n\n index++;\n html.push(`<pre>${escapeHtml(code.join('\\n'))}</pre>`);\n continue;\n }\n\n const heading = /^(#{1,3})\\s+(.*)$/.exec(line);\n\n if (heading) {\n const level = heading[1].length;\n\n html.push(`<h${level}>${inlineToHtml(heading[2])}</h${level}>`);\n index++;\n continue;\n }\n\n if (/^(\\s*[-*_]){3,}\\s*$/.test(line)) {\n html.push('<hr>');\n index++;\n continue;\n }\n\n if (/^>\\s?/.test(line)) {\n const quoted: string[] = [];\n\n while (index < lines.length && /^>\\s?/.test(lines[index])) {\n quoted.push(lines[index++].replace(/^>\\s?/, ''));\n }\n\n html.push(`<blockquote>${quoted.map(text => `<p>${inlineToHtml(text)}</p>`).join('')}</blockquote>`);\n continue;\n }\n\n const bullet = /^\\s*[-*+]\\s+/;\n const ordered = /^\\s*\\d+[.)]\\s+/;\n\n if (bullet.test(line) || ordered.test(line)) {\n const isOrdered = ordered.test(line);\n const marker = isOrdered ? ordered : bullet;\n const items: string[] = [];\n\n while (index < lines.length && marker.test(lines[index])) {\n items.push(`<li>${inlineToHtml(lines[index++].replace(marker, ''))}</li>`);\n }\n\n html.push(isOrdered ? `<ol>${items.join('')}</ol>` : `<ul>${items.join('')}</ul>`);\n continue;\n }\n\n // Anything else runs on as a paragraph until a blank line or a new block.\n const paragraph: string[] = [];\n\n while (index < lines.length && lines[index].trim() && !startsBlock(lines[index])) {\n paragraph.push(lines[index++]);\n }\n\n html.push(`<p>${paragraph.map(inlineToHtml).join('<br>')}</p>`);\n }\n\n return html.join('');\n}\n\nfunction startsBlock(line: string): boolean {\n return /^(```|#{1,3}\\s|>|\\s*[-*+]\\s|\\s*\\d+[.)]\\s)/.test(line) || /^(\\s*[-*_]){3,}\\s*$/.test(line);\n}\n\n/**\n * Stand-ins for the two things that must sit out the emphasis passes: a code\n * span, and a backslash-escaped character. Private-use codepoints, so nothing a\n * user can type collides with them.\n */\nconst SPAN = String.fromCharCode(0xe000);\nconst ESCAPED = String.fromCharCode(0xe001);\n\n/**\n * Inline Markdown → HTML.\n *\n * Code spans and escapes are lifted out first and put back last. That is what\n * keeps `**` inside a code span from turning bold, and `\\*` from being read as\n * emphasis at all — both are invisible to the passes in between.\n */\nfunction inlineToHtml(text: string): string {\n const codeSpans: string[] = [];\n const escapes: string[] = [];\n\n let out = escapeHtml(text)\n .replace(/`([^`]+)`/g, (_, code: string) => {\n codeSpans.push(code);\n\n return `${SPAN}${codeSpans.length - 1}${SPAN}`;\n })\n .replace(/\\\\([\\\\`*_[\\]#>~])/g, (_, char: string) => {\n escapes.push(char);\n\n return `${ESCAPED}${escapes.length - 1}${ESCAPED}`;\n });\n\n out = out\n .replace(/\\[([^\\]]+)]\\(([^)\\s]+)\\)/g, (match, label: string, href: string) => {\n const url = sanitizeUrl(href);\n\n return url ? `<a href=\"${escapeHtml(url)}\">${label}</a>` : match;\n })\n .replace(/(\\*\\*|__)(?=\\S)([\\s\\S]*?\\S)\\1/g, '<strong>$2</strong>')\n .replace(/(?<![*\\w])\\*(?=\\S)([^*]*?\\S)\\*(?![*\\w])/g, '<em>$1</em>')\n .replace(/(?<![_\\w])_(?=\\S)([^_]*?\\S)_(?![_\\w])/g, '<em>$1</em>')\n .replace(/~~(?=\\S)([\\s\\S]*?\\S)~~/g, '<s>$1</s>');\n\n return out\n .replace(new RegExp(`${ESCAPED}(\\\\d+)${ESCAPED}`, 'g'), (_, index: string) => escapes[Number(index)])\n .replace(new RegExp(`${SPAN}(\\\\d+)${SPAN}`, 'g'), (_, index: string) => `<code>${codeSpans[Number(index)]}</code>`);\n}\n","import { InjectionToken, inject, type Provider } from '@angular/core';\nimport { createXConfigToken } from '@xui/core';\nimport { bbcodeSyntax } from './bbcode-syntax';\nimport { markdownSyntax } from './markdown-syntax';\nimport type { XuiRichTextSyntax } from './rich-text-syntax';\n\nexport interface XuiRichTextEditorConfig {\n /** Which format new editors start in. */\n format: string;\n /** Text shown while the editor is empty. */\n placeholder: string;\n /** Offer the source-text view alongside the formatted one. */\n sourceView: boolean;\n}\n\n/** Application-wide defaults for every editor. Individual inputs still win. */\nexport const [injectXuiRichTextEditorConfig, provideXuiRichTextEditorConfig] =\n createXConfigToken<XuiRichTextEditorConfig>('XuiRichTextEditorConfig', {\n format: 'markdown',\n placeholder: '',\n sourceView: true\n });\n\nconst XuiRichTextSyntaxToken = new InjectionToken<readonly XuiRichTextSyntax[]>('XuiRichTextSyntax');\n\n/**\n * Teaches the editor a format.\n *\n * Markdown and BBCode are built in; this adds to them, or replaces one by\n * registering a syntax under the same name — the last one provided wins, so an\n * app can swap in its own flavour of Markdown without forking the editor.\n *\n * ```ts\n * provideXuiRichTextSyntax({\n * name: 'plain',\n * features: ['bold'],\n * toHtml: text => `<p>${text}</p>`,\n * fromHtml: root => root.textContent ?? ''\n * });\n * ```\n */\nexport function provideXuiRichTextSyntax(...syntaxes: XuiRichTextSyntax[]): Provider {\n return { provide: XuiRichTextSyntaxToken, useValue: syntaxes, multi: true };\n}\n\n/**\n * Every known syntax, by name. Built-ins first, so anything provided by the app\n * that reuses a name replaces it.\n */\nexport function injectXuiRichTextSyntaxes(): Map<string, XuiRichTextSyntax> {\n const provided = inject(XuiRichTextSyntaxToken, { optional: true }) as XuiRichTextSyntax[][] | null;\n\n return new Map([markdownSyntax, bbcodeSyntax, ...(provided ?? []).flat()].map(syntax => [syntax.name, syntax]));\n}\n","import type { BooleanInput } from '@angular/cdk/coercion';\nimport {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n ViewEncapsulation,\n booleanAttribute,\n computed,\n effect,\n input,\n model,\n signal,\n viewChild\n} from '@angular/core';\nimport { ControlValueAccessor } from '@angular/forms';\nimport { NgIcon, provideIcons } from '@ng-icons/core';\nimport {\n matCodeRound,\n matFormatBoldRound,\n matFormatItalicRound,\n matFormatListBulletedRound,\n matFormatListNumberedRound,\n matFormatQuoteRound,\n matFormatStrikethroughRound,\n matFormatUnderlinedRound,\n matHorizontalRuleRound,\n matLinkRound,\n matTerminalRound\n} from '@ng-icons/material-icons/round';\nimport { xui } from '@xui/core';\nimport { createXValueAccessor, provideXValueAccessor } from '@xui/core/forms';\nimport { XuiIcon } from '@xui/icon';\nimport type { ClassValue } from 'clsx';\nimport { injectXuiRichTextEditorConfig, injectXuiRichTextSyntaxes } from './rich-text-editor.token';\nimport type { XuiRichTextFeature } from './rich-text-syntax';\n\ninterface Tool {\n readonly feature: XuiRichTextFeature;\n readonly label: string;\n readonly icon?: string;\n readonly text?: string;\n /** `document.execCommand` name, and its argument where one is needed. */\n readonly command: string;\n readonly argument?: string;\n /** How the button's pressed state is read back from the document. */\n readonly state: 'command' | 'block' | 'none';\n readonly key?: string;\n}\n\n/**\n * The full toolbar, in order. Each editor shows the entries its format can\n * express — the same button set can therefore never produce markup the format\n * cannot round-trip.\n */\nconst TOOLS: readonly Tool[] = [\n { feature: 'bold', label: 'Bold', icon: 'matFormatBoldRound', command: 'bold', state: 'command', key: 'b' },\n { feature: 'italic', label: 'Italic', icon: 'matFormatItalicRound', command: 'italic', state: 'command', key: 'i' },\n {\n feature: 'underline',\n label: 'Underline',\n icon: 'matFormatUnderlinedRound',\n command: 'underline',\n state: 'command',\n key: 'u'\n },\n {\n feature: 'strike',\n label: 'Strikethrough',\n icon: 'matFormatStrikethroughRound',\n command: 'strikeThrough',\n state: 'command'\n },\n { feature: 'code', label: 'Inline code', icon: 'matCodeRound', command: 'xuiCode', state: 'none' },\n { feature: 'link', label: 'Link', icon: 'matLinkRound', command: 'xuiLink', state: 'none', key: 'k' },\n { feature: 'heading1', label: 'Heading 1', text: 'H1', command: 'formatBlock', argument: 'h1', state: 'block' },\n { feature: 'heading2', label: 'Heading 2', text: 'H2', command: 'formatBlock', argument: 'h2', state: 'block' },\n { feature: 'heading3', label: 'Heading 3', text: 'H3', command: 'formatBlock', argument: 'h3', state: 'block' },\n {\n feature: 'bulletList',\n label: 'Bulleted list',\n icon: 'matFormatListBulletedRound',\n command: 'insertUnorderedList',\n state: 'command'\n },\n {\n feature: 'orderedList',\n label: 'Numbered list',\n icon: 'matFormatListNumberedRound',\n command: 'insertOrderedList',\n state: 'command'\n },\n {\n feature: 'quote',\n label: 'Quote',\n icon: 'matFormatQuoteRound',\n command: 'formatBlock',\n argument: 'blockquote',\n state: 'block'\n },\n {\n feature: 'codeBlock',\n label: 'Code block',\n icon: 'matTerminalRound',\n command: 'formatBlock',\n argument: 'pre',\n state: 'block'\n },\n {\n feature: 'rule',\n label: 'Divider',\n icon: 'matHorizontalRuleRound',\n command: 'insertHorizontalRule',\n state: 'none'\n }\n];\n\n/**\n * A WYSIWYG editor whose value is source text.\n *\n * The user works on formatted content; the binding is the Markdown or BBCode\n * you store — so nothing downstream has to know an editor was involved, and\n * nothing has to be sanitised on the way out.\n *\n * ```html\n * <xui-rich-text-editor [(value)]=\"comment\" format=\"markdown\" placeholder=\"Say something…\" />\n * ```\n *\n * ```html\n * <xui-rich-text-editor formControlName=\"post\" format=\"bbcode\" />\n * ```\n *\n * The toolbar is the format's capabilities: Markdown offers headings and a\n * divider but no underline, BBCode the reverse. Teach it a new format with\n * {@link provideXuiRichTextSyntax} and the toolbar follows.\n *\n * The source view (`</>`) shows the text itself, editable, and the two stay in\n * step. Pasting always lands as plain text — foreign HTML never enters the\n * document, so the value cannot carry markup the format does not define.\n */\n@Component({\n selector: 'xui-rich-text-editor',\n imports: [NgIcon, XuiIcon],\n template: `\n <div\n role=\"toolbar\"\n aria-label=\"Formatting\"\n class=\"border-border bg-surface-sunken flex flex-wrap items-center gap-0.5 rounded-t-lg border-b p-1\"\n >\n @for (tool of tools(); track tool.feature) {\n <button\n type=\"button\"\n [class]=\"toolClass()\"\n [attr.aria-label]=\"tool.label\"\n [attr.aria-pressed]=\"tool.state === 'none' ? null : active().includes(tool.feature)\"\n [attr.data-active]=\"active().includes(tool.feature) ? '' : null\"\n [disabled]=\"isDisabled() || source()\"\n [title]=\"tool.label\"\n (mousedown)=\"$event.preventDefault()\"\n (click)=\"run(tool)\"\n >\n @if (tool.icon) {\n <ng-icon xui size=\"sm\" [name]=\"tool.icon\" />\n } @else {\n <span class=\"px-0.5 text-xs font-semibold\">{{ tool.text }}</span>\n }\n </button>\n }\n\n @if (sourceView()) {\n <button\n type=\"button\"\n [class]=\"toolClass()\"\n class=\"ms-auto\"\n aria-label=\"Source\"\n [attr.aria-pressed]=\"source()\"\n [attr.data-active]=\"source() ? '' : null\"\n [disabled]=\"isDisabled()\"\n title=\"Source\"\n (click)=\"toggleSource()\"\n >\n <span class=\"px-0.5 text-xs font-semibold\">&lt;/&gt;</span>\n </button>\n }\n </div>\n\n @if (linkDraft() !== null) {\n <div class=\"border-border bg-surface-sunken flex items-center gap-1 border-b p-1\">\n <input\n #linkField\n type=\"url\"\n class=\"text-foreground placeholder:text-foreground-subtle min-w-0 flex-1 bg-transparent px-2 py-1 text-sm outline-none\"\n placeholder=\"https://example.com\"\n aria-label=\"Link URL\"\n [value]=\"linkDraft()\"\n (input)=\"linkDraft.set($any($event.target).value)\"\n (keydown.enter)=\"applyLink(); $event.preventDefault()\"\n (keydown.escape)=\"linkDraft.set(null)\"\n />\n <button type=\"button\" [class]=\"toolClass()\" class=\"text-xs\" (click)=\"applyLink()\">Apply</button>\n <button type=\"button\" [class]=\"toolClass()\" class=\"text-xs\" (click)=\"linkDraft.set(null)\">Cancel</button>\n </div>\n }\n\n @if (source()) {\n <textarea\n class=\"text-foreground placeholder:text-foreground-subtle block w-full resize-y bg-transparent p-3 font-mono text-sm outline-none\"\n [style.min-height.px]=\"minHeight()\"\n [attr.aria-label]=\"'Source (' + format() + ')'\"\n [disabled]=\"isDisabled()\"\n [value]=\"value()\"\n (input)=\"onSourceInput($event)\"\n (blur)=\"cva.markTouched()\"\n ></textarea>\n } @else {\n <div class=\"relative\">\n @if (!value().trim() && placeholder()) {\n <p class=\"text-foreground-subtle pointer-events-none absolute p-3 select-none\">{{ placeholder() }}</p>\n }\n\n <!-- eslint-disable-next-line @angular-eslint/template/interactive-supports-focus -->\n <div\n #surface\n role=\"textbox\"\n aria-multiline=\"true\"\n [class]=\"surfaceClass()\"\n [style.min-height.px]=\"minHeight()\"\n [attr.contenteditable]=\"isDisabled() ? null : true\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-disabled]=\"isDisabled() ? true : null\"\n (input)=\"pull()\"\n (blur)=\"cva.markTouched()\"\n (paste)=\"onPaste($event)\"\n (keydown)=\"onKeydown($event)\"\n (keyup)=\"refreshActive()\"\n (mouseup)=\"refreshActive()\"\n ></div>\n </div>\n }\n `,\n host: {\n '[class]': 'computedClass()',\n '[attr.data-disabled]': 'isDisabled() ? \"\" : null'\n },\n providers: [provideXValueAccessor(() => XuiRichTextEditor)],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n viewProviders: [\n provideIcons({\n matCodeRound,\n matFormatBoldRound,\n matFormatItalicRound,\n matFormatListBulletedRound,\n matFormatListNumberedRound,\n matFormatQuoteRound,\n matFormatStrikethroughRound,\n matFormatUnderlinedRound,\n matHorizontalRuleRound,\n matLinkRound,\n matTerminalRound\n })\n ]\n})\nexport class XuiRichTextEditor implements ControlValueAccessor {\n private readonly config = injectXuiRichTextEditorConfig();\n private readonly syntaxes = injectXuiRichTextSyntaxes();\n private readonly surface = viewChild<ElementRef<HTMLElement>>('surface');\n private readonly linkField = viewChild<ElementRef<HTMLInputElement>>('linkField');\n\n /** Extra classes, merged into the component's own rather than replacing them. */\n readonly class = input<ClassValue>('');\n\n /** The source text, in the active `format`. Two-way bindable, and the form value. */\n readonly value = model<string>('');\n\n /** `'markdown'`, `'bbcode'`, or any format registered with `provideXuiRichTextSyntax`. */\n readonly format = input<string>(this.config.format);\n\n /** Text shown over the empty editor. */\n readonly placeholder = input<string>(this.config.placeholder);\n\n /** Offer the source-text toggle. */\n readonly sourceView = input<boolean, BooleanInput>(this.config.sourceView, { transform: booleanAttribute });\n\n /** Block editing and dim the editor and its toolbar. */\n readonly disabled = input<boolean, BooleanInput>(false, { transform: booleanAttribute });\n\n /** Height of the writing area before it grows with the content. */\n readonly minHeight = input<number>(180);\n\n /** Accessible name for the editing surface — what is being written. */\n readonly ariaLabel = input<string | undefined>(undefined, { alias: 'aria-label' });\n\n /** Whether the source view is showing. Two-way bindable. */\n readonly source = model(false);\n\n protected readonly linkDraft = signal<string | null>(null);\n protected readonly active = signal<XuiRichTextFeature[]>([]);\n\n protected readonly cva = createXValueAccessor<string>({\n onWrite: value => {\n this.value.set(value ?? '');\n // Force the next render: the value came from outside, so whatever is in\n // the surface is stale even if the string matches what we last serialised.\n this.synced = null;\n },\n disabled: this.disabled\n });\n protected readonly isDisabled = this.cva.disabled;\n\n /**\n * The value the surface already shows, tagged with the format it was rendered\n * in. Re-rendering the user's own keystrokes would reset the caret on every\n * one, so the effect below writes only when this no longer matches.\n */\n private synced: string | null = null;\n /** The element that value went into — the source toggle builds a new one. */\n private syncedSurface: HTMLElement | null = null;\n /** What the link is to wrap, held while the URL field has the selection. */\n private savedRange: Range | null = null;\n\n private readonly syntax = computed(() => {\n const syntax = this.syntaxes.get(this.format());\n\n if (!syntax) {\n throw new Error(\n `@xui/rich-text-editor: unknown format \"${this.format()}\". ` +\n `Known formats: ${[...this.syntaxes.keys()].join(', ')}. Register others with provideXuiRichTextSyntax().`\n );\n }\n\n return syntax;\n });\n\n protected readonly tools = computed(() => {\n const features = this.syntax().features;\n\n return TOOLS.filter(tool => features.includes(tool.feature));\n });\n\n protected readonly computedClass = computed(() =>\n xui(\n 'border-border bg-surface-inset text-foreground block overflow-hidden rounded-lg border',\n 'focus-within:border-focus transition-colors',\n 'data-disabled:cursor-not-allowed data-disabled:opacity-50',\n '[&.ng-invalid.ng-touched]:border-error',\n this.class()\n )\n );\n\n // A disabled tool keeps its pointer events so the cursor can say it is unavailable — an element\n // that receives none contributes no cursor either. The native `disabled` swallows the click, and\n // `enabled:` keeps the hover lift off a tool that cannot be used.\n protected readonly toolClass = computed(() =>\n xui(\n 'text-foreground-muted enabled:hover:bg-surface-raised enabled:hover:text-foreground flex items-center rounded px-1.5 py-1',\n 'data-active:bg-surface-raised data-active:text-foreground disabled:cursor-not-allowed disabled:opacity-50'\n )\n );\n\n /** Tailwind resets block elements, so the writing area re-states how prose looks. */\n protected readonly surfaceClass = computed(() =>\n xui(\n 'block p-3 outline-none [&>*+*]:mt-2',\n '[&_h1]:text-2xl [&_h1]:font-semibold [&_h2]:text-xl [&_h2]:font-semibold [&_h3]:text-lg [&_h3]:font-semibold',\n '[&_ul]:list-disc [&_ol]:list-decimal [&_ul]:ps-6 [&_ol]:ps-6',\n '[&_blockquote]:border-border-strong [&_blockquote]:text-foreground-muted [&_blockquote]:border-s-2 [&_blockquote]:ps-3',\n '[&_pre]:bg-surface-sunken [&_pre]:rounded [&_pre]:p-2 [&_pre]:font-mono [&_pre]:text-sm',\n '[&_code]:bg-surface-sunken [&_code]:rounded [&_code]:px-1 [&_code]:font-mono [&_code]:text-sm',\n '[&_pre_code]:bg-transparent [&_pre_code]:p-0',\n '[&_a]:text-link [&_a]:underline',\n '[&_hr]:border-border [&_hr]:my-3'\n )\n );\n\n constructor() {\n // Enter should start a paragraph, and marks should be tags rather than\n // inline styles — otherwise there is nothing for a syntax to recognise.\n safely(() => document.execCommand?.('defaultParagraphSeparator', false, 'p'));\n safely(() => document.execCommand?.('styleWithCSS', false, 'false'));\n\n // Renders whenever the value arrives from outside — a binding, a form, the\n // source toggle — and skips the echo of the user's own typing, which would\n // otherwise reset the caret on every keystroke.\n effect(() => {\n const surface = this.surface()?.nativeElement;\n const value = this.value();\n const key = this.syncKey(value);\n\n if (!surface || (key === this.synced && surface === this.syncedSurface)) {\n return;\n }\n\n this.syncedSurface = surface;\n\n // A format switch keeps the content and changes only how it is written\n // down: the document is the same either way, so it is re-read in the new\n // format rather than re-rendered from text the new format cannot parse.\n if (this.synced && !this.synced.startsWith(`${this.format()}:`) && surface.innerHTML) {\n const translated = this.syntax().fromHtml(surface);\n\n this.synced = this.syncKey(translated);\n this.value.set(translated);\n this.cva.notifyChange(translated);\n\n return;\n }\n\n surface.innerHTML = this.syntax().toHtml(value);\n this.synced = key;\n });\n\n effect(() => {\n if (this.linkDraft() !== null) {\n this.linkField()?.nativeElement.focus();\n }\n });\n }\n\n /** The editing surface, for consumers who need to focus it. */\n focus(): void {\n this.surface()?.nativeElement.focus();\n }\n\n /** Show the formatted view (`false`) or the source text (`true`). */\n protected toggleSource(): void {\n this.source.update(source => !source);\n }\n\n protected onSourceInput(event: Event): void {\n this.commit((event.target as HTMLTextAreaElement).value);\n }\n\n /** Reads the surface back out as source text. */\n protected pull(): void {\n const surface = this.surface()?.nativeElement;\n\n if (!surface) {\n return;\n }\n\n this.commit(this.syntax().fromHtml(surface));\n this.refreshActive();\n }\n\n protected onKeydown(event: KeyboardEvent): void {\n if (!(event.metaKey || event.ctrlKey)) {\n return;\n }\n\n const tool = this.tools().find(candidate => candidate.key === event.key.toLowerCase());\n\n if (tool) {\n event.preventDefault();\n this.run(tool);\n }\n }\n\n /**\n * Paste as plain text.\n *\n * Whatever is on the clipboard — a Word document, half a web page — would\n * otherwise arrive as HTML the format cannot express and the editor would\n * have to guess at. The text is inserted as typed instead.\n */\n protected onPaste(event: ClipboardEvent): void {\n event.preventDefault();\n\n const text = event.clipboardData?.getData('text/plain') ?? '';\n\n this.exec('insertText', text);\n this.pull();\n }\n\n protected run(tool: Tool): void {\n if (this.isDisabled() || this.source()) {\n return;\n }\n\n if (tool.command === 'xuiLink') {\n // Captured before anything touches focus: the URL field is about to take\n // the document selection, and this is the range the link must wrap.\n this.savedRange = currentRange();\n // The field appears with the draft; an effect focuses it once it exists.\n this.linkDraft.set('');\n\n return;\n }\n\n this.focus();\n\n if (tool.command === 'xuiCode') {\n this.wrapSelection('code');\n } else if (tool.command === 'formatBlock') {\n // A second press on the same block returns it to a paragraph.\n const target = this.active().includes(tool.feature) ? 'p' : tool.argument!;\n\n this.exec('formatBlock', target);\n } else {\n this.exec(tool.command, tool.argument);\n }\n\n this.pull();\n }\n\n protected applyLink(): void {\n const href = this.linkDraft()?.trim();\n\n this.linkDraft.set(null);\n this.focus();\n this.restoreSelection();\n\n if (href) {\n this.exec('createLink', href);\n this.pull();\n }\n }\n\n /** Puts the caret back where it was before the URL field took focus. */\n private restoreSelection(): void {\n const selection = getSelection();\n\n if (!this.savedRange || !selection) {\n return;\n }\n\n selection.removeAllRanges();\n selection.addRange(this.savedRange);\n this.savedRange = null;\n }\n\n /** Reflects the caret's formatting on the toolbar. */\n protected refreshActive(): void {\n if (typeof document === 'undefined' || !document.queryCommandState) {\n return;\n }\n\n const block = document.queryCommandValue?.('formatBlock')?.toLowerCase();\n\n this.active.set(\n this.tools()\n .filter(tool => {\n if (tool.state === 'command') {\n return safely(() => document.queryCommandState(tool.command));\n }\n\n return tool.state === 'block' && block === tool.argument;\n })\n .map(tool => tool.feature)\n );\n }\n\n /** Wraps the selection in a tag, or unwraps it when it is already wrapped. */\n private wrapSelection(tag: string): void {\n const selection = getSelection();\n\n if (!selection?.rangeCount) {\n return;\n }\n\n const range = selection.getRangeAt(0);\n const existing = closest(range.commonAncestorContainer, tag);\n\n if (existing) {\n existing.replaceWith(...Array.from(existing.childNodes));\n\n return;\n }\n\n if (!range.collapsed) {\n this.exec('insertHTML', `<${tag}>${escapeText(range.toString())}</${tag}>`);\n }\n }\n\n private exec(command: string, argument?: string): void {\n // `execCommand` is the only editing API every browser implements for\n // contenteditable; absent under a test DOM, where nothing is being edited.\n safely(() => document.execCommand?.(command, false, argument));\n }\n\n private commit(next: string): void {\n if (next === this.value()) {\n return;\n }\n\n // The surface already shows this — recorded before the write so the render\n // effect sees it and leaves the caret where the user put it.\n this.synced = this.syncKey(next);\n this.value.set(next);\n this.cva.notifyChange(next);\n }\n\n private syncKey(value: string): string {\n return `${this.format()}:${value}`;\n }\n\n // --- ControlValueAccessor ---\n readonly writeValue = this.cva.writeValue;\n readonly registerOnChange = this.cva.registerOnChange;\n readonly registerOnTouched = this.cva.registerOnTouched;\n readonly setDisabledState = this.cva.setDisabledState;\n}\n\nfunction currentRange(): Range | null {\n const selection = getSelection();\n\n return selection?.rangeCount ? selection.getRangeAt(0).cloneRange() : null;\n}\n\n/** The nearest ancestor with `tag`, starting at `node` itself. */\nfunction closest(node: Node, tag: string): Element | null {\n const element = node instanceof Element ? node : node.parentElement;\n\n return element?.closest(tag) ?? null;\n}\n\nfunction escapeText(text: string): string {\n return text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');\n}\n\n/** Runs `fn`, treating a DOM that does not implement it as \"no\". */\nfunction safely(fn: () => boolean | void): boolean {\n try {\n return fn() === true;\n } catch {\n return false;\n }\n}\n","import { XuiRichTextEditor } from './lib/rich-text-editor';\n\nexport * from './lib/bbcode-syntax';\nexport * from './lib/markdown-syntax';\nexport * from './lib/rich-text-editor';\nexport * from './lib/rich-text-editor.token';\nexport * from './lib/rich-text-syntax';\n\nexport const XuiRichTextEditorImports = [XuiRichTextEditor] as const;\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["FEATURES","writer","inlineToHtml"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xui/rich-text-editor",
3
- "version": "2.0.0-alpha.19",
3
+ "version": "2.0.0-alpha.21",
4
4
  "description": "Modern Angular 22 UI Library based on TailwindCSS",
5
5
  "keywords": [
6
6
  "angular",
@@ -41,8 +41,8 @@
41
41
  "@angular/forms": "22",
42
42
  "@ng-icons/core": "^34.0.0",
43
43
  "@ng-icons/material-icons": "^34.0.0",
44
- "@xui/core": "2.0.0-alpha.19",
45
- "@xui/icon": "2.0.0-alpha.19",
44
+ "@xui/core": "2.0.0-alpha.21",
45
+ "@xui/icon": "2.0.0-alpha.21",
46
46
  "clsx": "^2.1.1"
47
47
  },
48
48
  "publishConfig": {
@@ -105,17 +105,21 @@ declare class XuiRichTextEditor implements ControlValueAccessor {
105
105
  private readonly syntaxes;
106
106
  private readonly surface;
107
107
  private readonly linkField;
108
+ /** Extra classes, merged into the component's own rather than replacing them. */
108
109
  readonly class: _angular_core.InputSignal<ClassValue>;
109
110
  /** The source text, in the active `format`. Two-way bindable, and the form value. */
110
111
  readonly value: _angular_core.ModelSignal<string>;
111
112
  /** `'markdown'`, `'bbcode'`, or any format registered with `provideXuiRichTextSyntax`. */
112
113
  readonly format: _angular_core.InputSignal<string>;
114
+ /** Text shown over the empty editor. */
113
115
  readonly placeholder: _angular_core.InputSignal<string>;
114
116
  /** Offer the source-text toggle. */
115
117
  readonly sourceView: _angular_core.InputSignalWithTransform<boolean, BooleanInput>;
118
+ /** Block editing and dim the editor and its toolbar. */
116
119
  readonly disabled: _angular_core.InputSignalWithTransform<boolean, BooleanInput>;
117
120
  /** Height of the writing area before it grows with the content. */
118
121
  readonly minHeight: _angular_core.InputSignal<number>;
122
+ /** Accessible name for the editing surface — what is being written. */
119
123
  readonly ariaLabel: _angular_core.InputSignal<string | undefined>;
120
124
  /** Whether the source view is showing. Two-way bindable. */
121
125
  readonly source: _angular_core.ModelSignal<boolean>;