@flogeez/angular-tiptap-editor 3.5.2 → 3.5.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/esm2022/lib/components/bubble-menus/link/ate-link-bubble-menu.component.mjs +22 -2
- package/esm2022/lib/components/editor/angular-tiptap-editor.component.mjs +15 -2
- package/esm2022/lib/extensions/ate-link-shortcut.extension.mjs +50 -0
- package/esm2022/lib/extensions/ate-pasted-image.extension.mjs +156 -0
- package/esm2022/lib/models/ate-image.model.mjs +1 -1
- package/esm2022/lib/services/ate-editor-commands.service.mjs +7 -1
- package/esm2022/lib/services/ate-image.service.mjs +63 -36
- package/esm2022/public-api.mjs +4 -1
- package/fesm2022/flogeez-angular-tiptap-editor.mjs +303 -37
- package/fesm2022/flogeez-angular-tiptap-editor.mjs.map +1 -1
- package/lib/components/bubble-menus/link/ate-link-bubble-menu.component.d.ts +1 -0
- package/lib/components/editor/angular-tiptap-editor.component.d.ts +4 -2
- package/lib/extensions/ate-link-shortcut.extension.d.ts +15 -0
- package/lib/extensions/ate-pasted-image.extension.d.ts +33 -0
- package/lib/models/ate-image.model.d.ts +9 -0
- package/lib/services/ate-editor-commands.service.d.ts +2 -0
- package/lib/services/ate-image.service.d.ts +7 -0
- package/package.json +1 -1
- package/public-api.d.ts +2 -0
|
@@ -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,207 @@ 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
|
+
|
|
838
|
+
/** Matches the bare `Mod+K` chord (`Cmd+K` on macOS, `Ctrl+K` elsewhere) */
|
|
839
|
+
function isLinkShortcut(event) {
|
|
840
|
+
return ((event.metaKey || event.ctrlKey) &&
|
|
841
|
+
!event.shiftKey &&
|
|
842
|
+
!event.altKey &&
|
|
843
|
+
event.key.toLowerCase() === "k");
|
|
844
|
+
}
|
|
845
|
+
/**
|
|
846
|
+
* `Mod+K` opens the link editor when text is selected or the cursor is on a link.
|
|
847
|
+
* With an empty selection outside a link the event is left alone, so host-level `Mod+K`
|
|
848
|
+
* shortcuts (search, command palettes) keep working.
|
|
849
|
+
*/
|
|
850
|
+
const AteLinkShortcut = Extension.create({
|
|
851
|
+
name: "ateLinkShortcut",
|
|
852
|
+
addOptions() {
|
|
853
|
+
return {
|
|
854
|
+
canOpen: () => true,
|
|
855
|
+
open: () => undefined,
|
|
856
|
+
};
|
|
857
|
+
},
|
|
858
|
+
addProseMirrorPlugins() {
|
|
859
|
+
const editor = this.editor;
|
|
860
|
+
const options = this.options;
|
|
861
|
+
return [
|
|
862
|
+
new Plugin({
|
|
863
|
+
key: new PluginKey("ateLinkShortcut"),
|
|
864
|
+
props: {
|
|
865
|
+
handleKeyDown: (view, event) => {
|
|
866
|
+
if (!isLinkShortcut(event) || !view.editable) {
|
|
867
|
+
return false;
|
|
868
|
+
}
|
|
869
|
+
if (view.state.selection.empty && !editor.isActive("link")) {
|
|
870
|
+
return false;
|
|
871
|
+
}
|
|
872
|
+
if (!options.canOpen()) {
|
|
873
|
+
return false;
|
|
874
|
+
}
|
|
875
|
+
event.preventDefault();
|
|
876
|
+
event.stopPropagation();
|
|
877
|
+
options.open(editor);
|
|
878
|
+
return true;
|
|
879
|
+
},
|
|
880
|
+
},
|
|
881
|
+
}),
|
|
882
|
+
];
|
|
883
|
+
},
|
|
884
|
+
});
|
|
885
|
+
|
|
684
886
|
const AteTableExtension = Extension.create({
|
|
685
887
|
name: "tableExtension",
|
|
686
888
|
addExtensions() {
|
|
@@ -3341,43 +3543,15 @@ class AteImageService {
|
|
|
3341
3543
|
this.uploadProgress.set(10);
|
|
3342
3544
|
this.uploadMessage.set(this.t().validating);
|
|
3343
3545
|
this.forceEditorUpdate();
|
|
3344
|
-
const
|
|
3345
|
-
|
|
3346
|
-
|
|
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
|
-
}
|
|
3546
|
+
const result = await this.processImage(file, options, (progress, message) => {
|
|
3547
|
+
if (progress !== undefined) {
|
|
3548
|
+
this.uploadProgress.set(progress);
|
|
3375
3549
|
}
|
|
3376
|
-
|
|
3377
|
-
|
|
3378
|
-
|
|
3550
|
+
if (message !== undefined) {
|
|
3551
|
+
this.uploadMessage.set(message);
|
|
3552
|
+
this.forceEditorUpdate();
|
|
3379
3553
|
}
|
|
3380
|
-
}
|
|
3554
|
+
});
|
|
3381
3555
|
this.uploadProgress.set(90);
|
|
3382
3556
|
this.uploadMessage.set(actionMessage);
|
|
3383
3557
|
this.forceEditorUpdate();
|
|
@@ -3394,6 +3568,61 @@ class AteImageService {
|
|
|
3394
3568
|
throw error;
|
|
3395
3569
|
}
|
|
3396
3570
|
}
|
|
3571
|
+
/** Validate, compress and (when configured) send an image to the upload handler */
|
|
3572
|
+
async processImage(file, options, onStep) {
|
|
3573
|
+
const validation = this.validateImage(file, {
|
|
3574
|
+
maxSize: options?.maxSize,
|
|
3575
|
+
allowedTypes: options?.allowedTypes,
|
|
3576
|
+
});
|
|
3577
|
+
if (!validation.valid) {
|
|
3578
|
+
throw new Error(validation.error);
|
|
3579
|
+
}
|
|
3580
|
+
onStep?.(30, this.t().compressing);
|
|
3581
|
+
const result = await this.compressImage(file, options?.quality || 0.8, options?.maxWidth || 1920, options?.maxHeight || 1200);
|
|
3582
|
+
onStep?.(70);
|
|
3583
|
+
// Handle custom upload if handler is provided
|
|
3584
|
+
if (this.uploadHandler) {
|
|
3585
|
+
onStep?.(undefined, this.t().uploadingToServer);
|
|
3586
|
+
try {
|
|
3587
|
+
const handlerResponse = this.uploadHandler({
|
|
3588
|
+
file,
|
|
3589
|
+
width: result.width || 0,
|
|
3590
|
+
height: result.height || 0,
|
|
3591
|
+
type: result.type,
|
|
3592
|
+
base64: result.src,
|
|
3593
|
+
});
|
|
3594
|
+
const handlerResult = isObservable(handlerResponse)
|
|
3595
|
+
? await firstValueFrom(handlerResponse)
|
|
3596
|
+
: await handlerResponse;
|
|
3597
|
+
result.src = handlerResult.src;
|
|
3598
|
+
if (handlerResult.alt) {
|
|
3599
|
+
result.name = handlerResult.alt;
|
|
3600
|
+
}
|
|
3601
|
+
}
|
|
3602
|
+
catch (handlerError) {
|
|
3603
|
+
console.error(this.t().uploadError, handlerError);
|
|
3604
|
+
throw handlerError;
|
|
3605
|
+
}
|
|
3606
|
+
}
|
|
3607
|
+
return result;
|
|
3608
|
+
}
|
|
3609
|
+
/**
|
|
3610
|
+
* Run an image that is already in the document (e.g. base64 from pasted HTML)
|
|
3611
|
+
* through validation, compression and the upload handler, and resolve to its new `src`.
|
|
3612
|
+
*/
|
|
3613
|
+
async rehostImage(file, options) {
|
|
3614
|
+
try {
|
|
3615
|
+
const result = await this.processImage(file, options);
|
|
3616
|
+
if (this.onImageUploadedCallback) {
|
|
3617
|
+
this.onImageUploadedCallback(result);
|
|
3618
|
+
}
|
|
3619
|
+
return result.src;
|
|
3620
|
+
}
|
|
3621
|
+
catch (error) {
|
|
3622
|
+
console.error(this.t().uploadError, error);
|
|
3623
|
+
throw error;
|
|
3624
|
+
}
|
|
3625
|
+
}
|
|
3397
3626
|
resetUploadState() {
|
|
3398
3627
|
this.isUploading.set(false);
|
|
3399
3628
|
this.uploadProgress.set(0);
|
|
@@ -4635,6 +4864,12 @@ class AteEditorCommandsService {
|
|
|
4635
4864
|
handleImagePaste(editor, event, options) {
|
|
4636
4865
|
return this.imageService.handlePaste(editor, event, options);
|
|
4637
4866
|
}
|
|
4867
|
+
rehostImage(file, options) {
|
|
4868
|
+
return this.imageService.rehostImage(file, options);
|
|
4869
|
+
}
|
|
4870
|
+
get hasUploadHandler() {
|
|
4871
|
+
return this.imageService.uploadHandler !== null;
|
|
4872
|
+
}
|
|
4638
4873
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AteEditorCommandsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
4639
4874
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AteEditorCommandsService }); }
|
|
4640
4875
|
}
|
|
@@ -6751,6 +6986,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
6751
6986
|
type: Directive
|
|
6752
6987
|
}], ctorParameters: () => [] });
|
|
6753
6988
|
|
|
6989
|
+
/** Frames to wait for the menu to become visible before giving up on focusing the URL field */
|
|
6990
|
+
const FOCUS_MAX_ATTEMPTS = 20;
|
|
6754
6991
|
class AteLinkBubbleMenuComponent extends AteBaseSubBubbleMenu {
|
|
6755
6992
|
constructor() {
|
|
6756
6993
|
super();
|
|
@@ -6771,6 +7008,24 @@ class AteLinkBubbleMenuComponent extends AteBaseSubBubbleMenu {
|
|
|
6771
7008
|
this.editUrl.set(currentLinkHref);
|
|
6772
7009
|
}
|
|
6773
7010
|
}, { allowSignalWrites: true });
|
|
7011
|
+
// Move focus to the URL field whenever link editing starts (toolbar, bubble menu or Mod+K)
|
|
7012
|
+
effect(() => {
|
|
7013
|
+
if (this.linkSvc.editMode()) {
|
|
7014
|
+
untracked(() => this.focusInputWhenVisible());
|
|
7015
|
+
}
|
|
7016
|
+
});
|
|
7017
|
+
}
|
|
7018
|
+
focusInputWhenVisible(attempt = 0) {
|
|
7019
|
+
requestAnimationFrame(() => {
|
|
7020
|
+
const input = this.linkInput()?.nativeElement;
|
|
7021
|
+
if (!input || !this.linkSvc.editMode()) {
|
|
7022
|
+
return;
|
|
7023
|
+
}
|
|
7024
|
+
input.focus();
|
|
7025
|
+
if (document.activeElement !== input && attempt < FOCUS_MAX_ATTEMPTS) {
|
|
7026
|
+
this.focusInputWhenVisible(attempt + 1);
|
|
7027
|
+
}
|
|
7028
|
+
});
|
|
6774
7029
|
}
|
|
6775
7030
|
onStateChange() {
|
|
6776
7031
|
this.linkSvc.editMode();
|
|
@@ -8723,6 +8978,8 @@ class AngularTiptapEditorComponent {
|
|
|
8723
8978
|
this.editorBlur = output();
|
|
8724
8979
|
this.editableChange = output();
|
|
8725
8980
|
this.imageUploaded = output();
|
|
8981
|
+
/** Emitted when an image from pasted HTML is dropped (unreachable source or failed upload) */
|
|
8982
|
+
this.pastedImageRejected = output();
|
|
8726
8983
|
// ViewChild with signal
|
|
8727
8984
|
this.editorElement = viewChild.required("editorElement");
|
|
8728
8985
|
// Private signals for internal state
|
|
@@ -9058,6 +9315,10 @@ class AngularTiptapEditorComponent {
|
|
|
9058
9315
|
types: ["heading", "paragraph", "resizableImage"],
|
|
9059
9316
|
}),
|
|
9060
9317
|
AteLinkClickBehavior,
|
|
9318
|
+
AteLinkShortcut.configure({
|
|
9319
|
+
canOpen: () => this.editorCommandsService.editorState().can.toggleLink,
|
|
9320
|
+
open: editor => this.editorCommandsService.execute(editor, "toggleLink"),
|
|
9321
|
+
}),
|
|
9061
9322
|
Highlight.configure({
|
|
9062
9323
|
multicolor: true,
|
|
9063
9324
|
HTMLAttributes: {
|
|
@@ -9071,6 +9332,11 @@ class AngularTiptapEditorComponent {
|
|
|
9071
9332
|
class: "ate-image",
|
|
9072
9333
|
},
|
|
9073
9334
|
}),
|
|
9335
|
+
AtePastedImage.configure({
|
|
9336
|
+
shouldRehost: () => this.editorCommandsService.hasUploadHandler,
|
|
9337
|
+
rehost: file => this.editorCommandsService.rehostImage(file, this.getImageUploadOptions()),
|
|
9338
|
+
onRejected: rejection => this.pastedImageRejected.emit(rejection),
|
|
9339
|
+
}),
|
|
9074
9340
|
AteUploadProgress.configure({
|
|
9075
9341
|
isUploading: () => this.editorCommandsService.isUploading(),
|
|
9076
9342
|
uploadProgress: () => this.editorCommandsService.uploadProgress(),
|
|
@@ -9353,7 +9619,7 @@ class AngularTiptapEditorComponent {
|
|
|
9353
9619
|
}
|
|
9354
9620
|
}
|
|
9355
9621
|
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: [
|
|
9622
|
+
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
9623
|
AteEditorCommandsService,
|
|
9358
9624
|
AteImageService,
|
|
9359
9625
|
AteColorPickerService,
|
|
@@ -9849,5 +10115,5 @@ const ATE_DEFAULT_TOC_CONFIG = {
|
|
|
9849
10115
|
* Generated bundle index. Do not edit.
|
|
9850
10116
|
*/
|
|
9851
10117
|
|
|
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 };
|
|
10118
|
+
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, AteLinkShortcut, AteMarksCalculator, AteNodeViewRenderer, AteNoopValueAccessorDirective, AtePastedImage, AteSelectionCalculator, AteStructureCalculator, AteTableCalculator, AteTableOfContentsComponent, AteTocNodeComponent, AteTocNodeOptions, AteTooltipDirective, classifyPastedImageSrc, createAngularComponentExtension, createDefaultSlashCommands, dataUriToFile, filterSlashCommands, getAteTocNodeExtension, isLinkShortcut, provideAteEditor, provideAteIcons, registerAngularComponent, sanitizePastedImages };
|
|
9853
10119
|
//# sourceMappingURL=flogeez-angular-tiptap-editor.mjs.map
|