@flogeez/angular-tiptap-editor 3.5.2 → 3.5.3

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.
@@ -13,6 +13,7 @@ import { Color } from '@tiptap/extension-color';
13
13
  import OfficePaste from '@intevation/tiptap-extension-office-paste';
14
14
  import { Plugin, PluginKey, TextSelection, NodeSelection } from '@tiptap/pm/state';
15
15
  import { DecorationSet, Decoration } from '@tiptap/pm/view';
16
+ import { Fragment, Slice } from '@tiptap/pm/model';
16
17
  import { Table, TableRow, TableHeader, TableCell } from '@tiptap/extension-table';
17
18
  import { Subscription, isObservable, firstValueFrom, concat, defer, of, tap } from 'rxjs';
18
19
  import tippy, { sticky } from 'tippy.js';
@@ -681,6 +682,159 @@ const AteUploadProgress = Extension.create({
681
682
  },
682
683
  });
683
684
 
685
+ const IMAGE_NODE_NAMES = new Set(["resizableImage", "image"]);
686
+ const REMOTE_SRC = /^(https?:)?\/\//i;
687
+ const INLINE_SRC = /^data:(image\/[\w.+-]+);base64,(.*)$/is;
688
+ const PASTED_IMAGE_BASENAME = "pasted-image";
689
+ /**
690
+ * Classifies the `src` of an image found in pasted HTML.
691
+ * `unreachable` sources (e.g. `attachment:`, `file:`, `cid:`, foreign `blob:`) cannot be fetched by the page.
692
+ */
693
+ function classifyPastedImageSrc(src, origin = typeof location !== "undefined" ? location.origin : "") {
694
+ if (!src) {
695
+ return "unreachable";
696
+ }
697
+ if (REMOTE_SRC.test(src) || (src.startsWith("/") && !src.startsWith("//"))) {
698
+ return "remote";
699
+ }
700
+ if (origin && src.startsWith(`blob:${origin}/`)) {
701
+ return "remote";
702
+ }
703
+ return INLINE_SRC.test(src) ? "inline" : "unreachable";
704
+ }
705
+ /** Decodes a base64 image data URI into a `File`, or returns `null` when it is malformed */
706
+ function dataUriToFile(src) {
707
+ const match = INLINE_SRC.exec(src);
708
+ if (!match) {
709
+ return null;
710
+ }
711
+ const mimeType = match[1].toLowerCase();
712
+ try {
713
+ const binary = atob(match[2].replace(/\s/g, ""));
714
+ const bytes = Uint8Array.from(binary, char => char.codePointAt(0) ?? 0);
715
+ const extension = mimeType.split("/")[1].split("+")[0];
716
+ return new File([bytes], `${PASTED_IMAGE_BASENAME}.${extension}`, { type: mimeType });
717
+ }
718
+ catch {
719
+ return null;
720
+ }
721
+ }
722
+ function isImageNode(node) {
723
+ return IMAGE_NODE_NAMES.has(node.type.name);
724
+ }
725
+ /** Removes unreachable images from a pasted slice and lists the base64 sources it keeps */
726
+ function sanitizePastedImages(slice) {
727
+ const inlineSources = new Set();
728
+ const droppedSources = [];
729
+ const sanitize = (fragment) => {
730
+ const kept = [];
731
+ fragment.forEach(child => {
732
+ if (isImageNode(child)) {
733
+ const src = child.attrs["src"];
734
+ const source = classifyPastedImageSrc(src);
735
+ if (source === "unreachable") {
736
+ droppedSources.push(src ?? "");
737
+ return;
738
+ }
739
+ if (source === "inline" && src) {
740
+ inlineSources.add(src);
741
+ }
742
+ kept.push(child);
743
+ return;
744
+ }
745
+ kept.push(child.isLeaf ? child : child.copy(sanitize(child.content)));
746
+ });
747
+ return Fragment.fromArray(kept);
748
+ };
749
+ const content = sanitize(slice.content);
750
+ if (!droppedSources.length) {
751
+ return { slice, inlineSources: [...inlineSources], droppedSources };
752
+ }
753
+ const openStart = content.firstChild === slice.content.firstChild ? slice.openStart : 0;
754
+ const openEnd = content.lastChild === slice.content.lastChild ? slice.openEnd : 0;
755
+ return {
756
+ slice: new Slice(content, openStart, openEnd),
757
+ inlineSources: [...inlineSources],
758
+ droppedSources,
759
+ };
760
+ }
761
+ function replaceImageSrc(editor, previousSrc, nextSrc) {
762
+ if (editor.isDestroyed) {
763
+ return;
764
+ }
765
+ const { state } = editor;
766
+ const matches = [];
767
+ state.doc.descendants((node, pos) => {
768
+ if (isImageNode(node) && node.attrs["src"] === previousSrc) {
769
+ matches.push({ pos, node });
770
+ }
771
+ });
772
+ if (!matches.length) {
773
+ return;
774
+ }
775
+ const tr = state.tr;
776
+ for (const { pos, node } of [...matches].reverse()) {
777
+ if (nextSrc) {
778
+ tr.setNodeMarkup(pos, undefined, { ...node.attrs, src: nextSrc });
779
+ }
780
+ else {
781
+ tr.delete(pos, pos + node.nodeSize);
782
+ }
783
+ }
784
+ editor.view.dispatch(tr);
785
+ }
786
+ /**
787
+ * Cleans images coming from pasted HTML (e.g. Notion, Google Docs, Office):
788
+ * - drops images whose source the page cannot load, instead of inserting broken images;
789
+ * - sends base64 images through the upload handler (when one is configured) and swaps in the hosted URL.
790
+ *
791
+ * File-based clipboard images keep going through the regular paste upload flow.
792
+ */
793
+ const AtePastedImage = Extension.create({
794
+ name: "atePastedImage",
795
+ addOptions() {
796
+ return {
797
+ shouldRehost: () => false,
798
+ rehost: () => Promise.reject(new Error("No upload handler configured")),
799
+ onRejected: () => undefined,
800
+ };
801
+ },
802
+ addProseMirrorPlugins() {
803
+ const editor = this.editor;
804
+ const options = this.options;
805
+ const rehost = (src) => {
806
+ const file = dataUriToFile(src);
807
+ if (!file) {
808
+ replaceImageSrc(editor, src, null);
809
+ options.onRejected({ reason: "unreachable", src });
810
+ return;
811
+ }
812
+ options
813
+ .rehost(file)
814
+ .then(url => replaceImageSrc(editor, src, url))
815
+ .catch(() => {
816
+ replaceImageSrc(editor, src, null);
817
+ options.onRejected({ reason: "upload-failed", src });
818
+ });
819
+ };
820
+ return [
821
+ new Plugin({
822
+ key: new PluginKey("atePastedImage"),
823
+ props: {
824
+ transformPasted: slice => {
825
+ const { slice: sanitized, inlineSources, droppedSources } = sanitizePastedImages(slice);
826
+ droppedSources.forEach(src => options.onRejected({ reason: "unreachable", src }));
827
+ if (inlineSources.length && options.shouldRehost()) {
828
+ queueMicrotask(() => inlineSources.forEach(rehost));
829
+ }
830
+ return sanitized;
831
+ },
832
+ },
833
+ }),
834
+ ];
835
+ },
836
+ });
837
+
684
838
  const AteTableExtension = Extension.create({
685
839
  name: "tableExtension",
686
840
  addExtensions() {
@@ -3341,43 +3495,15 @@ class AteImageService {
3341
3495
  this.uploadProgress.set(10);
3342
3496
  this.uploadMessage.set(this.t().validating);
3343
3497
  this.forceEditorUpdate();
3344
- const validation = this.validateImage(file, {
3345
- maxSize: options?.maxSize,
3346
- allowedTypes: options?.allowedTypes,
3347
- });
3348
- if (!validation.valid) {
3349
- throw new Error(validation.error);
3350
- }
3351
- this.uploadProgress.set(30);
3352
- this.uploadMessage.set(this.t().compressing);
3353
- this.forceEditorUpdate();
3354
- const result = await this.compressImage(file, options?.quality || 0.8, options?.maxWidth || 1920, options?.maxHeight || 1200);
3355
- this.uploadProgress.set(70);
3356
- // Handle custom upload if handler is provided
3357
- if (this.uploadHandler) {
3358
- this.uploadMessage.set(this.t().uploadingToServer);
3359
- this.forceEditorUpdate();
3360
- try {
3361
- const handlerResponse = this.uploadHandler({
3362
- file,
3363
- width: result.width || 0,
3364
- height: result.height || 0,
3365
- type: result.type,
3366
- base64: result.src,
3367
- });
3368
- const handlerResult = isObservable(handlerResponse)
3369
- ? await firstValueFrom(handlerResponse)
3370
- : await handlerResponse;
3371
- result.src = handlerResult.src;
3372
- if (handlerResult.alt) {
3373
- result.name = handlerResult.alt;
3374
- }
3498
+ const result = await this.processImage(file, options, (progress, message) => {
3499
+ if (progress !== undefined) {
3500
+ this.uploadProgress.set(progress);
3375
3501
  }
3376
- catch (handlerError) {
3377
- console.error(this.t().uploadError, handlerError);
3378
- throw handlerError;
3502
+ if (message !== undefined) {
3503
+ this.uploadMessage.set(message);
3504
+ this.forceEditorUpdate();
3379
3505
  }
3380
- }
3506
+ });
3381
3507
  this.uploadProgress.set(90);
3382
3508
  this.uploadMessage.set(actionMessage);
3383
3509
  this.forceEditorUpdate();
@@ -3394,6 +3520,61 @@ class AteImageService {
3394
3520
  throw error;
3395
3521
  }
3396
3522
  }
3523
+ /** Validate, compress and (when configured) send an image to the upload handler */
3524
+ async processImage(file, options, onStep) {
3525
+ const validation = this.validateImage(file, {
3526
+ maxSize: options?.maxSize,
3527
+ allowedTypes: options?.allowedTypes,
3528
+ });
3529
+ if (!validation.valid) {
3530
+ throw new Error(validation.error);
3531
+ }
3532
+ onStep?.(30, this.t().compressing);
3533
+ const result = await this.compressImage(file, options?.quality || 0.8, options?.maxWidth || 1920, options?.maxHeight || 1200);
3534
+ onStep?.(70);
3535
+ // Handle custom upload if handler is provided
3536
+ if (this.uploadHandler) {
3537
+ onStep?.(undefined, this.t().uploadingToServer);
3538
+ try {
3539
+ const handlerResponse = this.uploadHandler({
3540
+ file,
3541
+ width: result.width || 0,
3542
+ height: result.height || 0,
3543
+ type: result.type,
3544
+ base64: result.src,
3545
+ });
3546
+ const handlerResult = isObservable(handlerResponse)
3547
+ ? await firstValueFrom(handlerResponse)
3548
+ : await handlerResponse;
3549
+ result.src = handlerResult.src;
3550
+ if (handlerResult.alt) {
3551
+ result.name = handlerResult.alt;
3552
+ }
3553
+ }
3554
+ catch (handlerError) {
3555
+ console.error(this.t().uploadError, handlerError);
3556
+ throw handlerError;
3557
+ }
3558
+ }
3559
+ return result;
3560
+ }
3561
+ /**
3562
+ * Run an image that is already in the document (e.g. base64 from pasted HTML)
3563
+ * through validation, compression and the upload handler, and resolve to its new `src`.
3564
+ */
3565
+ async rehostImage(file, options) {
3566
+ try {
3567
+ const result = await this.processImage(file, options);
3568
+ if (this.onImageUploadedCallback) {
3569
+ this.onImageUploadedCallback(result);
3570
+ }
3571
+ return result.src;
3572
+ }
3573
+ catch (error) {
3574
+ console.error(this.t().uploadError, error);
3575
+ throw error;
3576
+ }
3577
+ }
3397
3578
  resetUploadState() {
3398
3579
  this.isUploading.set(false);
3399
3580
  this.uploadProgress.set(0);
@@ -4635,6 +4816,12 @@ class AteEditorCommandsService {
4635
4816
  handleImagePaste(editor, event, options) {
4636
4817
  return this.imageService.handlePaste(editor, event, options);
4637
4818
  }
4819
+ rehostImage(file, options) {
4820
+ return this.imageService.rehostImage(file, options);
4821
+ }
4822
+ get hasUploadHandler() {
4823
+ return this.imageService.uploadHandler !== null;
4824
+ }
4638
4825
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AteEditorCommandsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
4639
4826
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AteEditorCommandsService }); }
4640
4827
  }
@@ -8723,6 +8910,8 @@ class AngularTiptapEditorComponent {
8723
8910
  this.editorBlur = output();
8724
8911
  this.editableChange = output();
8725
8912
  this.imageUploaded = output();
8913
+ /** Emitted when an image from pasted HTML is dropped (unreachable source or failed upload) */
8914
+ this.pastedImageRejected = output();
8726
8915
  // ViewChild with signal
8727
8916
  this.editorElement = viewChild.required("editorElement");
8728
8917
  // Private signals for internal state
@@ -9071,6 +9260,11 @@ class AngularTiptapEditorComponent {
9071
9260
  class: "ate-image",
9072
9261
  },
9073
9262
  }),
9263
+ AtePastedImage.configure({
9264
+ shouldRehost: () => this.editorCommandsService.hasUploadHandler,
9265
+ rehost: file => this.editorCommandsService.rehostImage(file, this.getImageUploadOptions()),
9266
+ onRejected: rejection => this.pastedImageRejected.emit(rejection),
9267
+ }),
9074
9268
  AteUploadProgress.configure({
9075
9269
  isUploading: () => this.editorCommandsService.isUploading(),
9076
9270
  uploadProgress: () => this.editorCommandsService.uploadProgress(),
@@ -9353,7 +9547,7 @@ class AngularTiptapEditorComponent {
9353
9547
  }
9354
9548
  }
9355
9549
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AngularTiptapEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
9356
- 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 }, mode: { classPropertyName: "mode", publicName: "mode", 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", imageUploaded: "imageUploaded" }, 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: [
9550
+ 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 }, mode: { classPropertyName: "mode", publicName: "mode", 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", imageUploaded: "imageUploaded", pastedImageRejected: "pastedImageRejected" }, 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: [
9357
9551
  AteEditorCommandsService,
9358
9552
  AteImageService,
9359
9553
  AteColorPickerService,
@@ -9849,5 +10043,5 @@ const ATE_DEFAULT_TOC_CONFIG = {
9849
10043
  * Generated bundle index. Do not edit.
9850
10044
  */
9851
10045
 
9852
- 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_ICONS, ATE_DEFAULT_IMAGE_BUBBLE_MENU_CONFIG, ATE_DEFAULT_IMAGE_UPLOAD_CONFIG, ATE_DEFAULT_SLASH_COMMANDS_CONFIG, ATE_DEFAULT_TABLE_MENU_CONFIG, ATE_DEFAULT_TOC_CONFIG, ATE_DEFAULT_TOOLBAR_CONFIG, ATE_GLOBAL_CONFIG, ATE_ICONS, ATE_IMAGE_BUBBLE_MENU_KEYS, ATE_INITIAL_EDITOR_STATE, ATE_MATERIAL_SYMBOLS_VIEWBOX, ATE_SLASH_COMMAND_KEYS, ATE_STROKE_ICONS, ATE_TABLE_BUBBLE_MENU_KEYS, ATE_TOOLBAR_KEYS, AngularTiptapEditorComponent, AteAngularNodeView, AteColorPickerService, AteDiscoveryCalculator, AteEditorCommandsService, AteEditorRef, AteEditorRegistry, AteExportService, AteI18nService, AteIconComponent, AteIconRegistry, AteImageCalculator, AteImageService, AteLinkService, AteMarksCalculator, AteNodeViewRenderer, AteNoopValueAccessorDirective, AteSelectionCalculator, AteStructureCalculator, AteTableCalculator, AteTableOfContentsComponent, AteTocNodeComponent, AteTocNodeOptions, AteTooltipDirective, createAngularComponentExtension, createDefaultSlashCommands, filterSlashCommands, getAteTocNodeExtension, provideAteEditor, provideAteIcons, registerAngularComponent };
10046
+ 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_ICONS, ATE_DEFAULT_IMAGE_BUBBLE_MENU_CONFIG, ATE_DEFAULT_IMAGE_UPLOAD_CONFIG, ATE_DEFAULT_SLASH_COMMANDS_CONFIG, ATE_DEFAULT_TABLE_MENU_CONFIG, ATE_DEFAULT_TOC_CONFIG, ATE_DEFAULT_TOOLBAR_CONFIG, ATE_GLOBAL_CONFIG, ATE_ICONS, ATE_IMAGE_BUBBLE_MENU_KEYS, ATE_INITIAL_EDITOR_STATE, ATE_MATERIAL_SYMBOLS_VIEWBOX, ATE_SLASH_COMMAND_KEYS, ATE_STROKE_ICONS, ATE_TABLE_BUBBLE_MENU_KEYS, ATE_TOOLBAR_KEYS, AngularTiptapEditorComponent, AteAngularNodeView, AteColorPickerService, AteDiscoveryCalculator, AteEditorCommandsService, AteEditorRef, AteEditorRegistry, AteExportService, AteI18nService, AteIconComponent, AteIconRegistry, AteImageCalculator, AteImageService, AteLinkService, AteMarksCalculator, AteNodeViewRenderer, AteNoopValueAccessorDirective, AtePastedImage, AteSelectionCalculator, AteStructureCalculator, AteTableCalculator, AteTableOfContentsComponent, AteTocNodeComponent, AteTocNodeOptions, AteTooltipDirective, classifyPastedImageSrc, createAngularComponentExtension, createDefaultSlashCommands, dataUriToFile, filterSlashCommands, getAteTocNodeExtension, provideAteEditor, provideAteIcons, registerAngularComponent, sanitizePastedImages };
9853
10047
  //# sourceMappingURL=flogeez-angular-tiptap-editor.mjs.map