@flogeez/angular-tiptap-editor 3.1.4 → 3.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.
@@ -1090,6 +1090,19 @@ const ENGLISH_TRANSLATIONS = {
1090
1090
  error: "Error",
1091
1091
  success: "Success",
1092
1092
  },
1093
+ export: {
1094
+ export: "Export",
1095
+ html: "HTML",
1096
+ markdown: "Markdown",
1097
+ text: "Plain Text",
1098
+ copyHtml: "Copy as HTML",
1099
+ copyMarkdown: "Copy as Markdown",
1100
+ copyText: "Copy as plain text",
1101
+ downloadHtml: "Download .html",
1102
+ downloadMarkdown: "Download .md",
1103
+ downloadText: "Download .txt",
1104
+ copiedSuccess: "Copied to clipboard!",
1105
+ },
1093
1106
  };
1094
1107
  const FRENCH_TRANSLATIONS = {
1095
1108
  toolbar: {
@@ -1263,6 +1276,19 @@ const FRENCH_TRANSLATIONS = {
1263
1276
  error: "Erreur",
1264
1277
  success: "Succès",
1265
1278
  },
1279
+ export: {
1280
+ export: "Exporter",
1281
+ html: "HTML",
1282
+ markdown: "Markdown",
1283
+ text: "Texte brut",
1284
+ copyHtml: "Copier en HTML",
1285
+ copyMarkdown: "Copier en Markdown",
1286
+ copyText: "Copier en texte brut",
1287
+ downloadHtml: "Télécharger .html",
1288
+ downloadMarkdown: "Télécharger .md",
1289
+ downloadText: "Télécharger .txt",
1290
+ copiedSuccess: "Copié dans le presse-papiers !",
1291
+ },
1266
1292
  };
1267
1293
  class AteI18nService {
1268
1294
  constructor() {
@@ -1285,6 +1311,7 @@ class AteI18nService {
1285
1311
  this.imageUpload = computed(() => this.translations().imageUpload);
1286
1312
  this.editor = computed(() => this.translations().editor);
1287
1313
  this.common = computed(() => this.translations().common);
1314
+ this.export = computed(() => this.translations().export);
1288
1315
  // Automatically detect browser language
1289
1316
  this.detectBrowserLanguage();
1290
1317
  }
@@ -2141,11 +2168,259 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
2141
2168
  type: Injectable
2142
2169
  }] });
2143
2170
 
2171
+ /**
2172
+ * HTML to Markdown converter utility (no external dependencies).
2173
+ */
2174
+ function htmlToMarkdown(html) {
2175
+ const parser = new DOMParser();
2176
+ const doc = parser.parseFromString(html, "text/html");
2177
+ const result = convertNode(doc.body, { listDepth: 0, listType: null });
2178
+ // Normalize multiple blank lines to max two
2179
+ return result.replace(/\n{3,}/g, "\n\n").trim();
2180
+ }
2181
+ function convertNode(node, ctx) {
2182
+ if (node.nodeType === Node.TEXT_NODE) {
2183
+ return node.textContent || "";
2184
+ }
2185
+ if (node.nodeType !== Node.ELEMENT_NODE) {
2186
+ return "";
2187
+ }
2188
+ const el = node;
2189
+ const tag = el.tagName.toLowerCase();
2190
+ const children = Array.from(el.childNodes);
2191
+ const inner = (overrideCtx) => children.map(c => convertNode(c, { ...ctx, ...overrideCtx })).join("");
2192
+ // ── Block-level elements ──────────────────────────────────
2193
+ if (tag === "br") {
2194
+ return "\n";
2195
+ }
2196
+ if (tag === "hr") {
2197
+ return "\n\n---\n\n";
2198
+ }
2199
+ if (/^h[1-6]$/.test(tag)) {
2200
+ const level = parseInt(tag[1], 10);
2201
+ const prefix = "#".repeat(level);
2202
+ return `\n\n${prefix} ${inner().trim()}\n\n`;
2203
+ }
2204
+ if (tag === "p") {
2205
+ const content = inner().trim();
2206
+ if (!content) {
2207
+ return "";
2208
+ }
2209
+ return `\n\n${content}\n\n`;
2210
+ }
2211
+ if (tag === "blockquote") {
2212
+ const content = inner()
2213
+ .trim()
2214
+ .split("\n")
2215
+ .map(line => `> ${line}`)
2216
+ .join("\n");
2217
+ return `\n\n${content}\n\n`;
2218
+ }
2219
+ if (tag === "pre") {
2220
+ // Extract language from code class e.g. "language-typescript"
2221
+ const codeEl = el.querySelector("code");
2222
+ const lang = codeEl
2223
+ ? (codeEl.className.match(/language-(\S+)/) || [])[1] || ""
2224
+ : "";
2225
+ const code = codeEl ? codeEl.textContent || "" : el.textContent || "";
2226
+ return `\n\n\`\`\`${lang}\n${code}\n\`\`\`\n\n`;
2227
+ }
2228
+ if (tag === "ul" || tag === "ol") {
2229
+ const isTaskList = el.getAttribute("data-type") === "taskList";
2230
+ const items = children
2231
+ .filter(c => c.tagName?.toLowerCase() === "li")
2232
+ .map((li, idx) => convertListItem(li, {
2233
+ listDepth: ctx.listDepth + 1,
2234
+ listType: tag === "ul" ? "ul" : "ol",
2235
+ orderedIndex: idx + 1,
2236
+ isTaskList,
2237
+ }))
2238
+ .join("\n");
2239
+ const block = `\n\n${items}\n\n`;
2240
+ // Only add surrounding newlines for root-level lists
2241
+ return ctx.listDepth === 0 ? block : `\n${items}`;
2242
+ }
2243
+ if (tag === "table") {
2244
+ return convertTable(el);
2245
+ }
2246
+ // ── Inline elements ──────────────────────────────────────
2247
+ if (tag === "strong" || tag === "b") {
2248
+ const content = inner();
2249
+ return content ? `**${content}**` : "";
2250
+ }
2251
+ if (tag === "em" || tag === "i") {
2252
+ const content = inner();
2253
+ return content ? `*${content}*` : "";
2254
+ }
2255
+ if (tag === "s" || tag === "del" || tag === "strike") {
2256
+ const content = inner();
2257
+ return content ? `~~${content}~~` : "";
2258
+ }
2259
+ if (tag === "u") {
2260
+ // No standard Markdown for underline — use HTML passthrough
2261
+ const content = inner();
2262
+ return content ? `<u>${content}</u>` : "";
2263
+ }
2264
+ if (tag === "code") {
2265
+ // Inline code (not inside pre)
2266
+ const content = el.textContent || "";
2267
+ return content ? `\`${content}\`` : "";
2268
+ }
2269
+ if (tag === "a") {
2270
+ const href = el.getAttribute("href") || "";
2271
+ const content = inner().trim();
2272
+ if (!content && !href) {
2273
+ return "";
2274
+ }
2275
+ if (!content) {
2276
+ return href;
2277
+ }
2278
+ return `[${content}](${href})`;
2279
+ }
2280
+ if (tag === "img") {
2281
+ const src = el.getAttribute("src") || "";
2282
+ const alt = el.getAttribute("alt") || "";
2283
+ return `![${alt}](${src})`;
2284
+ }
2285
+ // ── Wrapper / Unknown elements → recurse ─────────────────
2286
+ return inner();
2287
+ }
2288
+ function convertListItem(li, ctx) {
2289
+ const indent = " ".repeat(ctx.listDepth - 1);
2290
+ // Task list item
2291
+ if (ctx.isTaskList) {
2292
+ const checked = li.getAttribute("data-checked") === "true";
2293
+ const checkMark = checked ? "[x]" : "[ ]";
2294
+ const content = Array.from(li.childNodes)
2295
+ .map(c => convertNode(c, { listDepth: ctx.listDepth, listType: ctx.listType }))
2296
+ .join("")
2297
+ .trim();
2298
+ return `${indent}- ${checkMark} ${content}`;
2299
+ }
2300
+ // Normal list item
2301
+ const bullet = ctx.listType === "ol" ? `${ctx.orderedIndex}.` : "-";
2302
+ // Check if li contains nested lists
2303
+ const nestedListNodes = Array.from(li.childNodes).filter(c => c.tagName?.toLowerCase() === "ul" ||
2304
+ c.tagName?.toLowerCase() === "ol");
2305
+ const textNodes = Array.from(li.childNodes).filter(c => !["ul", "ol"].includes(c.tagName?.toLowerCase()));
2306
+ const textContent = textNodes
2307
+ .map(c => convertNode(c, { listDepth: ctx.listDepth, listType: ctx.listType }))
2308
+ .join("")
2309
+ .trim();
2310
+ const nestedContent = nestedListNodes
2311
+ .map(c => convertNode(c, { listDepth: ctx.listDepth, listType: ctx.listType }))
2312
+ .join("")
2313
+ .trimEnd();
2314
+ return `${indent}${bullet} ${textContent}${nestedContent}`;
2315
+ }
2316
+ function convertTable(table) {
2317
+ const rows = Array.from(table.querySelectorAll("tr"));
2318
+ if (rows.length === 0) {
2319
+ return "";
2320
+ }
2321
+ const tableData = rows.map(row => Array.from(row.querySelectorAll("th, td")).map(cell => cell.textContent?.replace(/\n/g, " ").trim() || ""));
2322
+ if (tableData.length === 0) {
2323
+ return "";
2324
+ }
2325
+ const colCount = Math.max(...tableData.map(r => r.length));
2326
+ // Pad rows to same width
2327
+ const normalized = tableData.map(row => {
2328
+ while (row.length < colCount) {
2329
+ row.push("");
2330
+ }
2331
+ return row;
2332
+ });
2333
+ // Calculate column widths
2334
+ const colWidths = Array.from({ length: colCount }, (_, i) => Math.max(...normalized.map(r => (r[i] || "").length), 3));
2335
+ const pad = (str, len) => str.padEnd(len, " ");
2336
+ const separator = colWidths.map(w => "-".repeat(w)).join(" | ");
2337
+ // Build rows
2338
+ const lines = [];
2339
+ normalized.forEach((row, rowIdx) => {
2340
+ const line = row.map((cell, i) => pad(cell, colWidths[i])).join(" | ");
2341
+ lines.push(`| ${line} |`);
2342
+ // Add separator after header row (first row)
2343
+ if (rowIdx === 0) {
2344
+ lines.push(`| ${separator} |`);
2345
+ }
2346
+ });
2347
+ return `\n\n${lines.join("\n")}\n\n`;
2348
+ }
2349
+
2350
+ class AteExportService {
2351
+ // ============================================================
2352
+ // Public Content Getters
2353
+ // ============================================================
2354
+ /** Returns the editor content as HTML string. */
2355
+ getHtml(editor) {
2356
+ return editor.getHTML();
2357
+ }
2358
+ /** Returns the editor content as plain text. */
2359
+ getText(editor) {
2360
+ return editor.getText();
2361
+ }
2362
+ /** Returns the editor content converted to Markdown. */
2363
+ getMarkdown(editor) {
2364
+ const html = editor.getHTML();
2365
+ return htmlToMarkdown(html);
2366
+ }
2367
+ /** Returns the editor content in the specified format. */
2368
+ getContent(editor, format) {
2369
+ switch (format) {
2370
+ case "html":
2371
+ return this.getHtml(editor);
2372
+ case "markdown":
2373
+ return this.getMarkdown(editor);
2374
+ case "text":
2375
+ return this.getText(editor);
2376
+ }
2377
+ }
2378
+ // ============================================================
2379
+ // Export Methods
2380
+ // ============================================================
2381
+ /** Copies the editor content to the clipboard. */
2382
+ async exportToClipboard(editor, format) {
2383
+ const content = this.getContent(editor, format);
2384
+ await navigator.clipboard.writeText(content);
2385
+ }
2386
+ /** Downloads the editor content as a file. */
2387
+ exportToFile(editor, format, options) {
2388
+ const content = this.getContent(editor, format);
2389
+ const baseName = options?.filename || "document";
2390
+ const extensions = {
2391
+ html: "html",
2392
+ markdown: "md",
2393
+ text: "txt",
2394
+ };
2395
+ const mimeTypes = {
2396
+ html: "text/html;charset=utf-8",
2397
+ markdown: "text/markdown;charset=utf-8",
2398
+ text: "text/plain;charset=utf-8",
2399
+ };
2400
+ const filename = `${baseName}.${extensions[format]}`;
2401
+ const blob = new Blob([content], { type: mimeTypes[format] });
2402
+ const url = URL.createObjectURL(blob);
2403
+ const link = document.createElement("a");
2404
+ link.href = url;
2405
+ link.download = filename;
2406
+ document.body.appendChild(link);
2407
+ link.click();
2408
+ document.body.removeChild(link);
2409
+ URL.revokeObjectURL(url);
2410
+ }
2411
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AteExportService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2412
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AteExportService }); }
2413
+ }
2414
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AteExportService, decorators: [{
2415
+ type: Injectable
2416
+ }] });
2417
+
2144
2418
  class AteEditorCommandsService {
2145
2419
  constructor() {
2146
2420
  this.imageService = inject(AteImageService);
2147
2421
  this.colorPickerSvc = inject(AteColorPickerService);
2148
2422
  this.linkSvc = inject(AteLinkService);
2423
+ this.exportSvc = inject(AteExportService);
2149
2424
  this._editorState = signal(ATE_INITIAL_EDITOR_STATE, {
2150
2425
  equal: (a, b) => {
2151
2426
  // 1. Primitive global states
@@ -2353,6 +2628,9 @@ class AteEditorCommandsService {
2353
2628
  case "clearContent":
2354
2629
  this.clearContent(editor);
2355
2630
  break;
2631
+ case "exportAs":
2632
+ void this.exportAs(editor, args[0], args[1], args[2]);
2633
+ break;
2356
2634
  }
2357
2635
  }
2358
2636
  // --- Formatting Commands ---
@@ -2545,6 +2823,34 @@ class AteEditorCommandsService {
2545
2823
  }
2546
2824
  editor.commands.clearContent(true);
2547
2825
  }
2826
+ // --- Export Commands ---
2827
+ /**
2828
+ * Returns the editor content in the given format.
2829
+ * @param format 'html' | 'markdown' | 'text'
2830
+ */
2831
+ getContent(editor, format) {
2832
+ if (!editor) {
2833
+ return "";
2834
+ }
2835
+ return this.exportSvc.getContent(editor, format);
2836
+ }
2837
+ /**
2838
+ * Exports the editor content.
2839
+ * @param format 'html' | 'markdown' | 'text'
2840
+ * @param method 'clipboard' | 'download'
2841
+ * @param options Optional filename for download
2842
+ */
2843
+ async exportAs(editor, format, method, options) {
2844
+ if (!editor) {
2845
+ return;
2846
+ }
2847
+ if (method === "clipboard") {
2848
+ await this.exportSvc.exportToClipboard(editor, format);
2849
+ }
2850
+ else {
2851
+ this.exportSvc.exportToFile(editor, format, options);
2852
+ }
2853
+ }
2548
2854
  focus(editor) {
2549
2855
  if (!editor) {
2550
2856
  return;
@@ -6054,6 +6360,416 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
6054
6360
  `, styles: [".ate-edit-toggle-container{position:absolute;margin-top:16px;right:16px;z-index:50}\n"] }]
6055
6361
  }] });
6056
6362
 
6363
+ /**
6364
+ * A wrapper class that holds a reference to a registered editor component.
6365
+ * It provides direct, type-safe facade methods to interact with the editor
6366
+ * and execute formatting/utility commands without needing to manage the raw
6367
+ * TipTap editor instance directly.
6368
+ */
6369
+ class AteEditorRef {
6370
+ constructor(id, getEditorInstance, commandsService) {
6371
+ this.id = id;
6372
+ this.getEditorInstance = getEditorInstance;
6373
+ this.commandsService = commandsService;
6374
+ }
6375
+ /** Get the raw TipTap Editor instance. */
6376
+ get editor() {
6377
+ return this.getEditorInstance();
6378
+ }
6379
+ /** Get the current editor state snapshot. */
6380
+ get state() {
6381
+ return this.commandsService.editorState();
6382
+ }
6383
+ /** Get the reactive editor state as a Signal. */
6384
+ get stateSignal() {
6385
+ return this.commandsService.editorState;
6386
+ }
6387
+ /** Execute a generic command by name. */
6388
+ execute(command, ...args) {
6389
+ const editor = this.editor;
6390
+ if (editor) {
6391
+ this.commandsService.execute(editor, command, ...args);
6392
+ }
6393
+ }
6394
+ // ============================================
6395
+ // Facade Formatting Commands
6396
+ // ============================================
6397
+ toggleBold() {
6398
+ const editor = this.editor;
6399
+ if (editor) {
6400
+ this.commandsService.toggleBold(editor);
6401
+ }
6402
+ }
6403
+ toggleItalic() {
6404
+ const editor = this.editor;
6405
+ if (editor) {
6406
+ this.commandsService.toggleItalic(editor);
6407
+ }
6408
+ }
6409
+ toggleStrike() {
6410
+ const editor = this.editor;
6411
+ if (editor) {
6412
+ this.commandsService.toggleStrike(editor);
6413
+ }
6414
+ }
6415
+ toggleCode() {
6416
+ const editor = this.editor;
6417
+ if (editor) {
6418
+ this.commandsService.toggleCode(editor);
6419
+ }
6420
+ }
6421
+ toggleCodeBlock() {
6422
+ const editor = this.editor;
6423
+ if (editor) {
6424
+ this.commandsService.toggleCodeBlock(editor);
6425
+ }
6426
+ }
6427
+ toggleUnderline() {
6428
+ const editor = this.editor;
6429
+ if (editor) {
6430
+ this.commandsService.toggleUnderline(editor);
6431
+ }
6432
+ }
6433
+ toggleSuperscript() {
6434
+ const editor = this.editor;
6435
+ if (editor) {
6436
+ this.commandsService.toggleSuperscript(editor);
6437
+ }
6438
+ }
6439
+ toggleSubscript() {
6440
+ const editor = this.editor;
6441
+ if (editor) {
6442
+ this.commandsService.toggleSubscript(editor);
6443
+ }
6444
+ }
6445
+ toggleHeading(level) {
6446
+ const editor = this.editor;
6447
+ if (editor) {
6448
+ this.commandsService.toggleHeading(editor, level);
6449
+ }
6450
+ }
6451
+ toggleBulletList() {
6452
+ const editor = this.editor;
6453
+ if (editor) {
6454
+ this.commandsService.toggleBulletList(editor);
6455
+ }
6456
+ }
6457
+ toggleOrderedList() {
6458
+ const editor = this.editor;
6459
+ if (editor) {
6460
+ this.commandsService.toggleOrderedList(editor);
6461
+ }
6462
+ }
6463
+ toggleBlockquote() {
6464
+ const editor = this.editor;
6465
+ if (editor) {
6466
+ this.commandsService.toggleBlockquote(editor);
6467
+ }
6468
+ }
6469
+ setTextAlign(alignment) {
6470
+ const editor = this.editor;
6471
+ if (editor) {
6472
+ this.commandsService.setTextAlign(editor, alignment);
6473
+ }
6474
+ }
6475
+ insertHorizontalRule() {
6476
+ const editor = this.editor;
6477
+ if (editor) {
6478
+ this.commandsService.insertHorizontalRule(editor);
6479
+ }
6480
+ }
6481
+ insertImage(options) {
6482
+ const editor = this.editor;
6483
+ if (editor) {
6484
+ this.commandsService.insertImage(editor, options);
6485
+ }
6486
+ }
6487
+ uploadImage(file, options) {
6488
+ const editor = this.editor;
6489
+ if (editor) {
6490
+ this.commandsService.uploadImage(editor, file, options);
6491
+ }
6492
+ }
6493
+ toggleHighlight(color) {
6494
+ const editor = this.editor;
6495
+ if (editor) {
6496
+ this.commandsService.toggleHighlight(editor, color);
6497
+ }
6498
+ }
6499
+ undo() {
6500
+ const editor = this.editor;
6501
+ if (editor) {
6502
+ this.commandsService.undo(editor);
6503
+ }
6504
+ }
6505
+ redo() {
6506
+ const editor = this.editor;
6507
+ if (editor) {
6508
+ this.commandsService.redo(editor);
6509
+ }
6510
+ }
6511
+ // ============================================
6512
+ // Table Commands
6513
+ // ============================================
6514
+ insertTable(rows, cols) {
6515
+ const editor = this.editor;
6516
+ if (editor) {
6517
+ this.commandsService.insertTable(editor, rows, cols);
6518
+ }
6519
+ }
6520
+ addColumnBefore() {
6521
+ const editor = this.editor;
6522
+ if (editor) {
6523
+ this.commandsService.addColumnBefore(editor);
6524
+ }
6525
+ }
6526
+ addColumnAfter() {
6527
+ const editor = this.editor;
6528
+ if (editor) {
6529
+ this.commandsService.addColumnAfter(editor);
6530
+ }
6531
+ }
6532
+ deleteColumn() {
6533
+ const editor = this.editor;
6534
+ if (editor) {
6535
+ this.commandsService.deleteColumn(editor);
6536
+ }
6537
+ }
6538
+ addRowBefore() {
6539
+ const editor = this.editor;
6540
+ if (editor) {
6541
+ this.commandsService.addRowBefore(editor);
6542
+ }
6543
+ }
6544
+ addRowAfter() {
6545
+ const editor = this.editor;
6546
+ if (editor) {
6547
+ this.commandsService.addRowAfter(editor);
6548
+ }
6549
+ }
6550
+ deleteRow() {
6551
+ const editor = this.editor;
6552
+ if (editor) {
6553
+ this.commandsService.deleteRow(editor);
6554
+ }
6555
+ }
6556
+ deleteTable() {
6557
+ const editor = this.editor;
6558
+ if (editor) {
6559
+ this.commandsService.deleteTable(editor);
6560
+ }
6561
+ }
6562
+ mergeCells() {
6563
+ const editor = this.editor;
6564
+ if (editor) {
6565
+ this.commandsService.mergeCells(editor);
6566
+ }
6567
+ }
6568
+ splitCell() {
6569
+ const editor = this.editor;
6570
+ if (editor) {
6571
+ this.commandsService.splitCell(editor);
6572
+ }
6573
+ }
6574
+ toggleHeaderColumn() {
6575
+ const editor = this.editor;
6576
+ if (editor) {
6577
+ this.commandsService.toggleHeaderColumn(editor);
6578
+ }
6579
+ }
6580
+ toggleHeaderRow() {
6581
+ const editor = this.editor;
6582
+ if (editor) {
6583
+ this.commandsService.toggleHeaderRow(editor);
6584
+ }
6585
+ }
6586
+ // ============================================
6587
+ // Color Picker & Link Commands
6588
+ // ============================================
6589
+ applyColor(color, selectionOnly, closeMenu) {
6590
+ const editor = this.editor;
6591
+ if (editor) {
6592
+ this.commandsService.execute(editor, "applyColor", color, selectionOnly, closeMenu);
6593
+ }
6594
+ }
6595
+ applyHighlight(color, selectionOnly, closeMenu) {
6596
+ const editor = this.editor;
6597
+ if (editor) {
6598
+ this.commandsService.execute(editor, "applyHighlight", color, selectionOnly, closeMenu);
6599
+ }
6600
+ }
6601
+ unsetColor(selectionOnly) {
6602
+ const editor = this.editor;
6603
+ if (editor) {
6604
+ this.commandsService.execute(editor, "unsetColor", selectionOnly);
6605
+ }
6606
+ }
6607
+ unsetHighlight(selectionOnly) {
6608
+ const editor = this.editor;
6609
+ if (editor) {
6610
+ this.commandsService.execute(editor, "unsetHighlight", selectionOnly);
6611
+ }
6612
+ }
6613
+ toggleLink(event) {
6614
+ const editor = this.editor;
6615
+ if (editor) {
6616
+ this.commandsService.execute(editor, "toggleLink", event);
6617
+ }
6618
+ }
6619
+ unsetLink() {
6620
+ const editor = this.editor;
6621
+ if (editor) {
6622
+ this.commandsService.execute(editor, "unsetLink");
6623
+ }
6624
+ }
6625
+ toggleColorPicker(mode, event) {
6626
+ const editor = this.editor;
6627
+ if (editor) {
6628
+ this.commandsService.execute(editor, "toggleColorPicker", mode, event);
6629
+ }
6630
+ }
6631
+ // ============================================
6632
+ // General Controls & Content
6633
+ // ============================================
6634
+ clearContent() {
6635
+ const editor = this.editor;
6636
+ if (editor) {
6637
+ this.commandsService.clearContent(editor);
6638
+ }
6639
+ }
6640
+ setContent(content, emitUpdate = true) {
6641
+ const editor = this.editor;
6642
+ if (editor) {
6643
+ this.commandsService.setContent(editor, content, emitUpdate);
6644
+ }
6645
+ }
6646
+ getContent(format) {
6647
+ const editor = this.editor;
6648
+ return editor ? this.commandsService.getContent(editor, format) : "";
6649
+ }
6650
+ getHTML() {
6651
+ const editor = this.editor;
6652
+ return editor ? editor.getHTML() : "";
6653
+ }
6654
+ getJSON() {
6655
+ const editor = this.editor;
6656
+ return editor ? editor.getJSON() : undefined;
6657
+ }
6658
+ getText() {
6659
+ const editor = this.editor;
6660
+ return editor ? editor.getText() : "";
6661
+ }
6662
+ async exportAs(format, method, options) {
6663
+ const editor = this.editor;
6664
+ if (editor) {
6665
+ await this.commandsService.exportAs(editor, format, method, options);
6666
+ }
6667
+ }
6668
+ focus() {
6669
+ const editor = this.editor;
6670
+ if (editor) {
6671
+ this.commandsService.focus(editor);
6672
+ }
6673
+ }
6674
+ blur() {
6675
+ const editor = this.editor;
6676
+ if (editor) {
6677
+ this.commandsService.blur(editor);
6678
+ }
6679
+ }
6680
+ }
6681
+
6682
+ /**
6683
+ * A root-level registry service to register, unregister, and manage active editor instances.
6684
+ * This service is provided in 'root' and can be injected anywhere in the application.
6685
+ */
6686
+ class AteEditorRegistry {
6687
+ constructor() {
6688
+ // Map of registered editors
6689
+ this._editors = signal(new Map());
6690
+ this.editors = this._editors.asReadonly();
6691
+ // Active (last focused or last registered) editor ID
6692
+ this._activeEditorId = signal(null);
6693
+ this.activeEditorId = this._activeEditorId.asReadonly();
6694
+ // List of all active editor IDs reactively
6695
+ this.editorIds = computed(() => Array.from(this._editors().keys()));
6696
+ // Active AteEditorRef reactively
6697
+ this.activeEditor = computed(() => {
6698
+ const activeId = this._activeEditorId();
6699
+ if (!activeId) {
6700
+ return null;
6701
+ }
6702
+ return this._editors().get(activeId) || null;
6703
+ });
6704
+ }
6705
+ static { this.counter = 0; }
6706
+ /**
6707
+ * Register an editor instance.
6708
+ * Returns the final registered ID.
6709
+ */
6710
+ register(id, getEditor, commandsService) {
6711
+ const finalId = id || `ate-editor-${++AteEditorRegistry.counter}`;
6712
+ const editorRef = new AteEditorRef(finalId, getEditor, commandsService);
6713
+ this._editors.update(map => {
6714
+ const newMap = new Map(map);
6715
+ newMap.set(finalId, editorRef);
6716
+ return newMap;
6717
+ });
6718
+ // If there is no active editor, make this one active
6719
+ if (!this._activeEditorId()) {
6720
+ this._activeEditorId.set(finalId);
6721
+ }
6722
+ return finalId;
6723
+ }
6724
+ /**
6725
+ * Unregister an editor instance by ID.
6726
+ */
6727
+ unregister(id) {
6728
+ this._editors.update(map => {
6729
+ const newMap = new Map(map);
6730
+ newMap.delete(id);
6731
+ return newMap;
6732
+ });
6733
+ // If the active editor is the one being unregistered, find a fallback
6734
+ if (this._activeEditorId() === id) {
6735
+ const remainingIds = this.editorIds();
6736
+ if (remainingIds.length > 0) {
6737
+ // Set active to the last registered one remaining
6738
+ this._activeEditorId.set(remainingIds[remainingIds.length - 1]);
6739
+ }
6740
+ else {
6741
+ this._activeEditorId.set(null);
6742
+ }
6743
+ }
6744
+ }
6745
+ /**
6746
+ * Mark an editor as active (usually on focus).
6747
+ */
6748
+ setActive(id) {
6749
+ if (this._editors().has(id)) {
6750
+ this._activeEditorId.set(id);
6751
+ }
6752
+ }
6753
+ /**
6754
+ * Retrieve an editor reference by ID, or the active editor if ID is not specified.
6755
+ */
6756
+ get(id) {
6757
+ if (id) {
6758
+ return this._editors().get(id);
6759
+ }
6760
+ const activeId = this._activeEditorId();
6761
+ return activeId ? this._editors().get(activeId) : undefined;
6762
+ }
6763
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AteEditorRegistry, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
6764
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AteEditorRegistry, providedIn: "root" }); }
6765
+ }
6766
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AteEditorRegistry, decorators: [{
6767
+ type: Injectable,
6768
+ args: [{
6769
+ providedIn: "root",
6770
+ }]
6771
+ }] });
6772
+
6057
6773
  /**
6058
6774
  * Noop Value Accessor Directive
6059
6775
  * @link https://medium.com/netanelbasal/forwarding-form-controls-to-custom-control-components-in-angular-701e8406cc55
@@ -7045,6 +7761,11 @@ class AngularTiptapEditorComponent {
7045
7761
  * ```
7046
7762
  */
7047
7763
  this.imageUploadHandler = input(undefined);
7764
+ /**
7765
+ * Optional unique identifier for the editor instance in the registry.
7766
+ * If not specified, a unique ID is automatically generated.
7767
+ */
7768
+ this.editorId = input(undefined);
7048
7769
  // Nouveaux outputs
7049
7770
  this.contentChange = output();
7050
7771
  this.editorCreated = output();
@@ -7237,6 +7958,9 @@ class AngularTiptapEditorComponent {
7237
7958
  this.editorCommandsService = inject(AteEditorCommandsService);
7238
7959
  // Access editor state via service
7239
7960
  this.editorState = this.editorCommandsService.editorState;
7961
+ this.editorRegistry = inject(AteEditorRegistry);
7962
+ this._registeredId = signal(null);
7963
+ this.registeredId = this._registeredId.asReadonly();
7240
7964
  this.injector = inject(Injector);
7241
7965
  this.globalConfig = inject(ATE_GLOBAL_CONFIG, { optional: true });
7242
7966
  /**
@@ -7347,6 +8071,11 @@ class AngularTiptapEditorComponent {
7347
8071
  currentEditor.destroy();
7348
8072
  }
7349
8073
  this._editorFullyInitialized.set(false);
8074
+ // Unregister from the global registry
8075
+ const id = this.registeredId();
8076
+ if (id) {
8077
+ this.editorRegistry.unregister(id);
8078
+ }
7350
8079
  }
7351
8080
  initEditor() {
7352
8081
  const extensions = [
@@ -7519,6 +8248,10 @@ class AngularTiptapEditorComponent {
7519
8248
  }, 100);
7520
8249
  },
7521
8250
  onFocus: ({ editor, event }) => {
8251
+ const id = this.registeredId();
8252
+ if (id) {
8253
+ this.editorRegistry.setActive(id);
8254
+ }
7522
8255
  this.editorFocus.emit({ editor, event });
7523
8256
  },
7524
8257
  onBlur: ({ editor, event }) => {
@@ -7531,6 +8264,9 @@ class AngularTiptapEditorComponent {
7531
8264
  });
7532
8265
  // Stocker la référence de l'éditeur immédiatement
7533
8266
  this._editor.set(newEditor);
8267
+ // Register editor in the global registry
8268
+ const registeredId = this.editorRegistry.register(this.editorId(), () => this.editor(), this.editorCommandsService);
8269
+ this._registeredId.set(registeredId);
7534
8270
  }
7535
8271
  toggleEditMode(event) {
7536
8272
  event.preventDefault();
@@ -7657,7 +8393,7 @@ class AngularTiptapEditorComponent {
7657
8393
  }
7658
8394
  }
7659
8395
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AngularTiptapEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
7660
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: AngularTiptapEditorComponent, isStandalone: true, selector: "angular-tiptap-editor", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null }, content: { classPropertyName: "content", publicName: "content", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, editable: { classPropertyName: "editable", publicName: "editable", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, minHeight: { classPropertyName: "minHeight", publicName: "minHeight", isSignal: true, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null }, maxHeight: { classPropertyName: "maxHeight", publicName: "maxHeight", isSignal: true, isRequired: false, transformFunction: null }, fillContainer: { classPropertyName: "fillContainer", publicName: "fillContainer", isSignal: true, isRequired: false, transformFunction: null }, showToolbar: { classPropertyName: "showToolbar", publicName: "showToolbar", isSignal: true, isRequired: false, transformFunction: null }, showFooter: { classPropertyName: "showFooter", publicName: "showFooter", isSignal: true, isRequired: false, transformFunction: null }, showCharacterCount: { classPropertyName: "showCharacterCount", publicName: "showCharacterCount", isSignal: true, isRequired: false, transformFunction: null }, showWordCount: { classPropertyName: "showWordCount", publicName: "showWordCount", isSignal: true, isRequired: false, transformFunction: null }, maxCharacters: { classPropertyName: "maxCharacters", publicName: "maxCharacters", isSignal: true, isRequired: false, transformFunction: null }, enableOfficePaste: { classPropertyName: "enableOfficePaste", publicName: "enableOfficePaste", isSignal: true, isRequired: false, transformFunction: null }, enableSlashCommands: { classPropertyName: "enableSlashCommands", publicName: "enableSlashCommands", isSignal: true, isRequired: false, transformFunction: null }, slashCommands: { classPropertyName: "slashCommands", publicName: "slashCommands", isSignal: true, isRequired: false, transformFunction: null }, customSlashCommands: { classPropertyName: "customSlashCommands", publicName: "customSlashCommands", isSignal: true, isRequired: false, transformFunction: null }, blockControls: { classPropertyName: "blockControls", publicName: "blockControls", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, autofocus: { classPropertyName: "autofocus", publicName: "autofocus", isSignal: true, isRequired: false, transformFunction: null }, seamless: { classPropertyName: "seamless", publicName: "seamless", isSignal: true, isRequired: false, transformFunction: null }, floatingToolbar: { classPropertyName: "floatingToolbar", publicName: "floatingToolbar", isSignal: true, isRequired: false, transformFunction: null }, showEditToggle: { classPropertyName: "showEditToggle", publicName: "showEditToggle", isSignal: true, isRequired: false, transformFunction: null }, spellcheck: { classPropertyName: "spellcheck", publicName: "spellcheck", isSignal: true, isRequired: false, transformFunction: null }, tiptapExtensions: { classPropertyName: "tiptapExtensions", publicName: "tiptapExtensions", isSignal: true, isRequired: false, transformFunction: null }, tiptapOptions: { classPropertyName: "tiptapOptions", publicName: "tiptapOptions", isSignal: true, isRequired: false, transformFunction: null }, showBubbleMenu: { classPropertyName: "showBubbleMenu", publicName: "showBubbleMenu", isSignal: true, isRequired: false, transformFunction: null }, bubbleMenu: { classPropertyName: "bubbleMenu", publicName: "bubbleMenu", isSignal: true, isRequired: false, transformFunction: null }, showImageBubbleMenu: { classPropertyName: "showImageBubbleMenu", publicName: "showImageBubbleMenu", isSignal: true, isRequired: false, transformFunction: null }, imageBubbleMenu: { classPropertyName: "imageBubbleMenu", publicName: "imageBubbleMenu", isSignal: true, isRequired: false, transformFunction: null }, toolbar: { classPropertyName: "toolbar", publicName: "toolbar", isSignal: true, isRequired: false, transformFunction: null }, showTableBubbleMenu: { classPropertyName: "showTableBubbleMenu", publicName: "showTableBubbleMenu", isSignal: true, isRequired: false, transformFunction: null }, tableBubbleMenu: { classPropertyName: "tableBubbleMenu", publicName: "tableBubbleMenu", isSignal: true, isRequired: false, transformFunction: null }, showCellBubbleMenu: { classPropertyName: "showCellBubbleMenu", publicName: "showCellBubbleMenu", isSignal: true, isRequired: false, transformFunction: null }, cellBubbleMenu: { classPropertyName: "cellBubbleMenu", publicName: "cellBubbleMenu", isSignal: true, isRequired: false, transformFunction: null }, stateCalculators: { classPropertyName: "stateCalculators", publicName: "stateCalculators", isSignal: true, isRequired: false, transformFunction: null }, imageUpload: { classPropertyName: "imageUpload", publicName: "imageUpload", isSignal: true, isRequired: false, transformFunction: null }, imageUploadHandler: { classPropertyName: "imageUploadHandler", publicName: "imageUploadHandler", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { contentChange: "contentChange", editorCreated: "editorCreated", editorUpdate: "editorUpdate", editorFocus: "editorFocus", editorBlur: "editorBlur", editableChange: "editableChange" }, host: { properties: { "class.fill-container": "finalFillContainer()", "class.floating-toolbar": "finalFloatingToolbar()", "class.is-readonly": "!finalEditable() && !mergedDisabled()", "class.is-disabled": "mergedDisabled()", "style.--ate-border-width": "finalSeamless() || mergedDisabled() ? '0' : null", "style.--ate-background": "finalSeamless() ? 'transparent' : (mergedDisabled() ? 'var(--ate-surface-tertiary)' : null)", "style.--ate-toolbar-border-color": "finalSeamless() ? 'transparent' : null", "style.--ate-counter-background": "finalSeamless() ? 'transparent' : null", "style.--ate-counter-border-color": "finalSeamless() ? 'transparent' : null", "class.dark": "config().theme === 'dark'", "class.ate-blocks-inside": "finalBlockControls() === 'inside'", "class.ate-blocks-outside": "finalBlockControls() === 'outside'", "attr.data-theme": "config().theme" } }, providers: [AteEditorCommandsService, AteImageService, AteColorPickerService, AteLinkService], viewQueries: [{ propertyName: "editorElement", first: true, predicate: ["editorElement"], descendants: true, isSignal: true }], hostDirectives: [{ directive: AteNoopValueAccessorDirective }], ngImport: i0, template: `
8396
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: AngularTiptapEditorComponent, isStandalone: true, selector: "angular-tiptap-editor", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null }, content: { classPropertyName: "content", publicName: "content", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, editable: { classPropertyName: "editable", publicName: "editable", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, minHeight: { classPropertyName: "minHeight", publicName: "minHeight", isSignal: true, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null }, maxHeight: { classPropertyName: "maxHeight", publicName: "maxHeight", isSignal: true, isRequired: false, transformFunction: null }, fillContainer: { classPropertyName: "fillContainer", publicName: "fillContainer", isSignal: true, isRequired: false, transformFunction: null }, showToolbar: { classPropertyName: "showToolbar", publicName: "showToolbar", isSignal: true, isRequired: false, transformFunction: null }, showFooter: { classPropertyName: "showFooter", publicName: "showFooter", isSignal: true, isRequired: false, transformFunction: null }, showCharacterCount: { classPropertyName: "showCharacterCount", publicName: "showCharacterCount", isSignal: true, isRequired: false, transformFunction: null }, showWordCount: { classPropertyName: "showWordCount", publicName: "showWordCount", isSignal: true, isRequired: false, transformFunction: null }, maxCharacters: { classPropertyName: "maxCharacters", publicName: "maxCharacters", isSignal: true, isRequired: false, transformFunction: null }, enableOfficePaste: { classPropertyName: "enableOfficePaste", publicName: "enableOfficePaste", isSignal: true, isRequired: false, transformFunction: null }, enableSlashCommands: { classPropertyName: "enableSlashCommands", publicName: "enableSlashCommands", isSignal: true, isRequired: false, transformFunction: null }, slashCommands: { classPropertyName: "slashCommands", publicName: "slashCommands", isSignal: true, isRequired: false, transformFunction: null }, customSlashCommands: { classPropertyName: "customSlashCommands", publicName: "customSlashCommands", isSignal: true, isRequired: false, transformFunction: null }, blockControls: { classPropertyName: "blockControls", publicName: "blockControls", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, autofocus: { classPropertyName: "autofocus", publicName: "autofocus", isSignal: true, isRequired: false, transformFunction: null }, seamless: { classPropertyName: "seamless", publicName: "seamless", isSignal: true, isRequired: false, transformFunction: null }, floatingToolbar: { classPropertyName: "floatingToolbar", publicName: "floatingToolbar", isSignal: true, isRequired: false, transformFunction: null }, showEditToggle: { classPropertyName: "showEditToggle", publicName: "showEditToggle", isSignal: true, isRequired: false, transformFunction: null }, spellcheck: { classPropertyName: "spellcheck", publicName: "spellcheck", isSignal: true, isRequired: false, transformFunction: null }, tiptapExtensions: { classPropertyName: "tiptapExtensions", publicName: "tiptapExtensions", isSignal: true, isRequired: false, transformFunction: null }, tiptapOptions: { classPropertyName: "tiptapOptions", publicName: "tiptapOptions", isSignal: true, isRequired: false, transformFunction: null }, showBubbleMenu: { classPropertyName: "showBubbleMenu", publicName: "showBubbleMenu", isSignal: true, isRequired: false, transformFunction: null }, bubbleMenu: { classPropertyName: "bubbleMenu", publicName: "bubbleMenu", isSignal: true, isRequired: false, transformFunction: null }, showImageBubbleMenu: { classPropertyName: "showImageBubbleMenu", publicName: "showImageBubbleMenu", isSignal: true, isRequired: false, transformFunction: null }, imageBubbleMenu: { classPropertyName: "imageBubbleMenu", publicName: "imageBubbleMenu", isSignal: true, isRequired: false, transformFunction: null }, toolbar: { classPropertyName: "toolbar", publicName: "toolbar", isSignal: true, isRequired: false, transformFunction: null }, showTableBubbleMenu: { classPropertyName: "showTableBubbleMenu", publicName: "showTableBubbleMenu", isSignal: true, isRequired: false, transformFunction: null }, tableBubbleMenu: { classPropertyName: "tableBubbleMenu", publicName: "tableBubbleMenu", isSignal: true, isRequired: false, transformFunction: null }, showCellBubbleMenu: { classPropertyName: "showCellBubbleMenu", publicName: "showCellBubbleMenu", isSignal: true, isRequired: false, transformFunction: null }, cellBubbleMenu: { classPropertyName: "cellBubbleMenu", publicName: "cellBubbleMenu", isSignal: true, isRequired: false, transformFunction: null }, stateCalculators: { classPropertyName: "stateCalculators", publicName: "stateCalculators", isSignal: true, isRequired: false, transformFunction: null }, imageUpload: { classPropertyName: "imageUpload", publicName: "imageUpload", isSignal: true, isRequired: false, transformFunction: null }, imageUploadHandler: { classPropertyName: "imageUploadHandler", publicName: "imageUploadHandler", isSignal: true, isRequired: false, transformFunction: null }, editorId: { classPropertyName: "editorId", publicName: "editorId", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { contentChange: "contentChange", editorCreated: "editorCreated", editorUpdate: "editorUpdate", editorFocus: "editorFocus", editorBlur: "editorBlur", editableChange: "editableChange" }, host: { properties: { "class.fill-container": "finalFillContainer()", "class.floating-toolbar": "finalFloatingToolbar()", "class.is-readonly": "!finalEditable() && !mergedDisabled()", "class.is-disabled": "mergedDisabled()", "style.--ate-border-width": "finalSeamless() || mergedDisabled() ? '0' : null", "style.--ate-background": "finalSeamless() ? 'transparent' : (mergedDisabled() ? 'var(--ate-surface-tertiary)' : null)", "style.--ate-toolbar-border-color": "finalSeamless() ? 'transparent' : null", "style.--ate-counter-background": "finalSeamless() ? 'transparent' : null", "style.--ate-counter-border-color": "finalSeamless() ? 'transparent' : null", "class.dark": "config().theme === 'dark'", "class.ate-blocks-inside": "finalBlockControls() === 'inside'", "class.ate-blocks-outside": "finalBlockControls() === 'outside'", "attr.data-theme": "config().theme" } }, providers: [AteEditorCommandsService, AteImageService, AteColorPickerService, AteLinkService, AteExportService], viewQueries: [{ propertyName: "editorElement", first: true, predicate: ["editorElement"], descendants: true, isSignal: true }], hostDirectives: [{ directive: AteNoopValueAccessorDirective }], ngImport: i0, template: `
7661
8397
  <div class="ate-editor">
7662
8398
  <!-- Toolbar -->
7663
8399
  @if (finalEditable() && !mergedDisabled() && finalShowToolbar() && editor()) {
@@ -7812,7 +8548,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
7812
8548
  AteColorBubbleMenuComponent,
7813
8549
  AteEditToggleComponent,
7814
8550
  AteBlockControlsComponent,
7815
- ], providers: [AteEditorCommandsService, AteImageService, AteColorPickerService, AteLinkService], template: `
8551
+ ], providers: [AteEditorCommandsService, AteImageService, AteColorPickerService, AteLinkService, AteExportService], template: `
7816
8552
  <div class="ate-editor">
7817
8553
  <!-- Toolbar -->
7818
8554
  @if (finalEditable() && !mergedDisabled() && finalShowToolbar() && editor()) {
@@ -8020,5 +8756,5 @@ const ATE_TOOLBAR_KEYS = [
8020
8756
  * Generated bundle index. Do not edit.
8021
8757
  */
8022
8758
 
8023
- export { ATE_BUBBLE_MENU_KEYS, ATE_CELL_BUBBLE_MENU_KEYS, ATE_DEFAULT_BUBBLE_MENU_CONFIG, ATE_DEFAULT_CELL_MENU_CONFIG, ATE_DEFAULT_CONFIG, ATE_DEFAULT_IMAGE_BUBBLE_MENU_CONFIG, ATE_DEFAULT_IMAGE_UPLOAD_CONFIG, ATE_DEFAULT_SLASH_COMMANDS_CONFIG, ATE_DEFAULT_TABLE_MENU_CONFIG, ATE_DEFAULT_TOOLBAR_CONFIG, ATE_GLOBAL_CONFIG, ATE_IMAGE_BUBBLE_MENU_KEYS, ATE_INITIAL_EDITOR_STATE, ATE_SLASH_COMMAND_KEYS, ATE_TABLE_BUBBLE_MENU_KEYS, ATE_TOOLBAR_KEYS, AngularTiptapEditorComponent, AteAngularNodeView, AteColorPickerService, AteDiscoveryCalculator, AteEditorCommandsService, AteI18nService, AteImageCalculator, AteImageService, AteLinkService, AteMarksCalculator, AteNodeViewRenderer, AteNoopValueAccessorDirective, AteSelectionCalculator, AteStructureCalculator, AteTableCalculator, AteTooltipDirective, createAngularComponentExtension, createDefaultSlashCommands, filterSlashCommands, provideAteEditor, registerAngularComponent };
8759
+ export { ATE_BUBBLE_MENU_KEYS, ATE_CELL_BUBBLE_MENU_KEYS, ATE_DEFAULT_BUBBLE_MENU_CONFIG, ATE_DEFAULT_CELL_MENU_CONFIG, ATE_DEFAULT_CONFIG, ATE_DEFAULT_IMAGE_BUBBLE_MENU_CONFIG, ATE_DEFAULT_IMAGE_UPLOAD_CONFIG, ATE_DEFAULT_SLASH_COMMANDS_CONFIG, ATE_DEFAULT_TABLE_MENU_CONFIG, ATE_DEFAULT_TOOLBAR_CONFIG, ATE_GLOBAL_CONFIG, ATE_IMAGE_BUBBLE_MENU_KEYS, ATE_INITIAL_EDITOR_STATE, ATE_SLASH_COMMAND_KEYS, ATE_TABLE_BUBBLE_MENU_KEYS, ATE_TOOLBAR_KEYS, AngularTiptapEditorComponent, AteAngularNodeView, AteColorPickerService, AteDiscoveryCalculator, AteEditorCommandsService, AteEditorRef, AteEditorRegistry, AteExportService, AteI18nService, AteImageCalculator, AteImageService, AteLinkService, AteMarksCalculator, AteNodeViewRenderer, AteNoopValueAccessorDirective, AteSelectionCalculator, AteStructureCalculator, AteTableCalculator, AteTooltipDirective, createAngularComponentExtension, createDefaultSlashCommands, filterSlashCommands, provideAteEditor, registerAngularComponent };
8024
8760
  //# sourceMappingURL=flogeez-angular-tiptap-editor.mjs.map