@flogeez/angular-tiptap-editor 3.6.1 → 3.7.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.
- package/CHANGELOG.md +12 -0
- package/README.md +6 -2
- package/esm2022/lib/components/bubble-menus/base/ate-base-bubble-menu.mjs +3 -3
- package/esm2022/lib/components/bubble-menus/base/ate-base-sub-bubble-menu.mjs +3 -3
- package/esm2022/lib/components/color-picker/ate-color-picker.component.mjs +3 -3
- package/esm2022/lib/components/editor/angular-tiptap-editor.component.mjs +52 -13
- package/esm2022/lib/components/editor/ate-block-controls.component.mjs +3 -3
- package/esm2022/lib/components/slash-commands/ate-slash-commands.component.mjs +3 -3
- package/esm2022/lib/components/table-of-contents/ate-table-of-contents.component.mjs +3 -3
- package/esm2022/lib/components/toolbar/ate-toolbar.component.mjs +3 -3
- package/esm2022/lib/config/ate-editor.config.mjs +7 -1
- package/esm2022/lib/config/ate-slash-commands.config.mjs +1 -1
- package/esm2022/lib/extensions/ate-paste.extension.mjs +125 -0
- package/esm2022/lib/extensions/ate-resizable-image.extension.mjs +44 -3
- package/esm2022/lib/models/ate-editor-config.model.mjs +1 -1
- package/esm2022/lib/models/ate-image.model.mjs +1 -1
- package/esm2022/lib/models/ate-paste.model.mjs +2 -0
- package/esm2022/lib/services/ate-editor-commands.service.mjs +7 -1
- package/esm2022/lib/services/ate-editor-i18n.service.mjs +36 -0
- package/esm2022/lib/services/ate-image.service.mjs +12 -5
- package/esm2022/lib/utils/ate-extensions.utils.mjs +3 -1
- package/esm2022/lib/utils/ate-image-src-resolver.utils.mjs +21 -0
- package/esm2022/public-api.mjs +2 -1
- package/fesm2022/flogeez-angular-tiptap-editor.mjs +297 -27
- package/fesm2022/flogeez-angular-tiptap-editor.mjs.map +1 -1
- package/lib/components/bubble-menus/base/ate-base-bubble-menu.d.ts +2 -2
- package/lib/components/bubble-menus/base/ate-base-sub-bubble-menu.d.ts +2 -2
- package/lib/components/bubble-menus/table/ate-cell-bubble-menu.component.d.ts +1 -1
- package/lib/components/editor/angular-tiptap-editor.component.d.ts +18 -2
- package/lib/components/editor/ate-block-controls.component.d.ts +2 -2
- package/lib/components/slash-commands/ate-slash-commands.component.d.ts +2 -2
- package/lib/config/ate-editor.config.d.ts +3 -0
- package/lib/config/ate-slash-commands.config.d.ts +2 -2
- package/lib/extensions/ate-paste.extension.d.ts +24 -0
- package/lib/extensions/ate-resizable-image.extension.d.ts +10 -1
- package/lib/models/ate-editor-config.model.d.ts +6 -1
- package/lib/models/ate-image.model.d.ts +12 -0
- package/lib/models/ate-paste.model.d.ts +36 -0
- package/lib/services/ate-editor-commands.service.d.ts +3 -1
- package/lib/services/ate-editor-i18n.service.d.ts +208 -0
- package/lib/services/ate-image.service.d.ts +3 -1
- package/lib/utils/ate-image-src-resolver.utils.d.ts +2 -0
- package/package.json +1 -1
- package/public-api.d.ts +1 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { InjectionToken, signal, inject, Injectable, computed, Directive, ApplicationRef, EnvironmentInjector, createComponent, input, booleanAttribute, effect, untracked, Component, ChangeDetectionStrategy, HostListener, ElementRef, ViewEncapsulation, output, viewChild, DestroyRef, Injector,
|
|
2
|
+
import { isDevMode, InjectionToken, signal, inject, Injectable, computed, Directive, ApplicationRef, EnvironmentInjector, createComponent, input, booleanAttribute, effect, untracked, Component, ChangeDetectionStrategy, HostListener, ElementRef, ViewEncapsulation, output, viewChild, DestroyRef, Injector, makeEnvironmentProviders, APP_INITIALIZER } from '@angular/core';
|
|
3
3
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
4
4
|
import { Node as Node$1, mergeAttributes, nodeInputRule, Extension, getAttributes, Editor } from '@tiptap/core';
|
|
5
5
|
import StarterKit from '@tiptap/starter-kit';
|
|
@@ -11,11 +11,11 @@ import { Highlight } from '@tiptap/extension-highlight';
|
|
|
11
11
|
import { TextStyle } from '@tiptap/extension-text-style';
|
|
12
12
|
import { Color } from '@tiptap/extension-color';
|
|
13
13
|
import OfficePaste from '@intevation/tiptap-extension-office-paste';
|
|
14
|
+
import { isObservable, firstValueFrom, Subscription, concat, defer, of, tap } from 'rxjs';
|
|
14
15
|
import { Plugin, PluginKey, NodeSelection, TextSelection } from '@tiptap/pm/state';
|
|
15
16
|
import { DecorationSet, Decoration } from '@tiptap/pm/view';
|
|
16
|
-
import { Fragment, Slice } from '@tiptap/pm/model';
|
|
17
|
+
import { Fragment, Slice, DOMSerializer } from '@tiptap/pm/model';
|
|
17
18
|
import { Table, TableRow, TableHeader, TableCell } from '@tiptap/extension-table';
|
|
18
|
-
import { Subscription, isObservable, firstValueFrom, concat, defer, of, tap } from 'rxjs';
|
|
19
19
|
import tippy, { sticky } from 'tippy.js';
|
|
20
20
|
import { DomSanitizer } from '@angular/platform-browser';
|
|
21
21
|
import { CommonModule } from '@angular/common';
|
|
@@ -23,6 +23,25 @@ import * as i1 from '@angular/forms';
|
|
|
23
23
|
import { FormsModule, NG_VALUE_ACCESSOR, NgControl } from '@angular/forms';
|
|
24
24
|
import { CellSelection } from '@tiptap/pm/tables';
|
|
25
25
|
|
|
26
|
+
async function ateResolveImageSrc(resolver, src) {
|
|
27
|
+
if (!resolver || !src) {
|
|
28
|
+
return src;
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
const result = resolver(src);
|
|
32
|
+
const resolved = isObservable(result) ? await firstValueFrom(result) : await result;
|
|
33
|
+
if (typeof resolved === "string" && resolved) {
|
|
34
|
+
return resolved;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
if (isDevMode()) {
|
|
39
|
+
console.warn("[ATE] imageSrcResolver failed, showing the original src instead.", src, error);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return src;
|
|
43
|
+
}
|
|
44
|
+
|
|
26
45
|
const AteResizableImage = Node$1.create({
|
|
27
46
|
name: "resizableImage",
|
|
28
47
|
addOptions() {
|
|
@@ -30,6 +49,12 @@ const AteResizableImage = Node$1.create({
|
|
|
30
49
|
inline: false,
|
|
31
50
|
allowBase64: false,
|
|
32
51
|
HTMLAttributes: {},
|
|
52
|
+
srcResolver: () => null,
|
|
53
|
+
};
|
|
54
|
+
},
|
|
55
|
+
addStorage() {
|
|
56
|
+
return {
|
|
57
|
+
srcRefreshers: new Set(),
|
|
33
58
|
};
|
|
34
59
|
},
|
|
35
60
|
inline() {
|
|
@@ -120,8 +145,13 @@ const AteResizableImage = Node$1.create({
|
|
|
120
145
|
];
|
|
121
146
|
},
|
|
122
147
|
addNodeView() {
|
|
148
|
+
const options = this.options;
|
|
149
|
+
const storage = this.storage;
|
|
123
150
|
return ({ node, getPos, editor }) => {
|
|
124
151
|
let currentNode = node;
|
|
152
|
+
let requestedSrc = null;
|
|
153
|
+
let requestedWith = null;
|
|
154
|
+
let destroyed = false;
|
|
125
155
|
const wrapper = document.createElement("div");
|
|
126
156
|
wrapper.className = "resizable-image-wrapper";
|
|
127
157
|
wrapper.style.display = "block";
|
|
@@ -134,7 +164,6 @@ const AteResizableImage = Node$1.create({
|
|
|
134
164
|
container.style.position = "relative";
|
|
135
165
|
container.style.display = "inline-block";
|
|
136
166
|
const img = document.createElement("img");
|
|
137
|
-
img.src = currentNode.attrs["src"];
|
|
138
167
|
img.alt = currentNode.attrs["alt"] || "";
|
|
139
168
|
img.title = currentNode.attrs["title"] || "";
|
|
140
169
|
img.className = "ate-image";
|
|
@@ -145,6 +174,32 @@ const AteResizableImage = Node$1.create({
|
|
|
145
174
|
if (currentNode.attrs["height"]) {
|
|
146
175
|
img.height = currentNode.attrs["height"];
|
|
147
176
|
}
|
|
177
|
+
const applySrc = (src) => {
|
|
178
|
+
const resolver = options.srcResolver() ?? null;
|
|
179
|
+
if (!resolver || !src) {
|
|
180
|
+
requestedSrc = null;
|
|
181
|
+
requestedWith = null;
|
|
182
|
+
img.src = src ?? "";
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
if (src === requestedSrc && resolver === requestedWith) {
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
// A new resolver for the same src keeps the current image until the new URL is ready, so it does not blink
|
|
189
|
+
if (src !== requestedSrc) {
|
|
190
|
+
img.removeAttribute("src");
|
|
191
|
+
}
|
|
192
|
+
requestedSrc = src;
|
|
193
|
+
requestedWith = resolver;
|
|
194
|
+
ateResolveImageSrc(resolver, src).then(resolved => {
|
|
195
|
+
if (!destroyed && requestedSrc === src && requestedWith === resolver) {
|
|
196
|
+
img.src = resolved;
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
};
|
|
200
|
+
const refreshSrc = () => applySrc(currentNode.attrs["src"]);
|
|
201
|
+
refreshSrc();
|
|
202
|
+
storage.srcRefreshers.add(refreshSrc);
|
|
148
203
|
wrapper.appendChild(container);
|
|
149
204
|
container.appendChild(img);
|
|
150
205
|
// Allow selection in read-only mode to show bubble menu/download
|
|
@@ -276,7 +331,7 @@ const AteResizableImage = Node$1.create({
|
|
|
276
331
|
return false;
|
|
277
332
|
}
|
|
278
333
|
currentNode = updatedNode;
|
|
279
|
-
|
|
334
|
+
applySrc(updatedNode.attrs["src"]);
|
|
280
335
|
img.alt = updatedNode.attrs["alt"] || "";
|
|
281
336
|
img.title = updatedNode.attrs["title"] || "";
|
|
282
337
|
if (updatedNode.attrs["width"]) {
|
|
@@ -300,6 +355,10 @@ const AteResizableImage = Node$1.create({
|
|
|
300
355
|
return !!target.closest(".resize-controls");
|
|
301
356
|
},
|
|
302
357
|
ignoreMutation: () => true,
|
|
358
|
+
destroy: () => {
|
|
359
|
+
destroyed = true;
|
|
360
|
+
storage.srcRefreshers.delete(refreshSrc);
|
|
361
|
+
},
|
|
303
362
|
};
|
|
304
363
|
};
|
|
305
364
|
},
|
|
@@ -996,6 +1055,127 @@ const AteBlockShortcuts = Extension.create({
|
|
|
996
1055
|
},
|
|
997
1056
|
});
|
|
998
1057
|
|
|
1058
|
+
/** Set on HTML copied from an editor, so a later paste knows it comes from an editor */
|
|
1059
|
+
const EDITOR_CLIPBOARD_MARKER = "data-ate-copy";
|
|
1060
|
+
const OFFICE_HTML = /urn:schemas-microsoft-com:office|class="?Mso|mso-/i;
|
|
1061
|
+
/** Detects where clipboard HTML comes from. Must run on the HTML as copied, before any cleanup */
|
|
1062
|
+
function detectPasteSource(html) {
|
|
1063
|
+
if (html.includes(EDITOR_CLIPBOARD_MARKER)) {
|
|
1064
|
+
return "editor";
|
|
1065
|
+
}
|
|
1066
|
+
return OFFICE_HTML.test(html) ? "office" : "external";
|
|
1067
|
+
}
|
|
1068
|
+
/** Removes the formats turned off in `config` (`colors`, `highlights`) from pasted HTML */
|
|
1069
|
+
function stripPastedFormats(html, config) {
|
|
1070
|
+
const keepColors = config.colors !== false;
|
|
1071
|
+
const keepHighlights = config.highlights !== false;
|
|
1072
|
+
if (keepColors && keepHighlights) {
|
|
1073
|
+
return html;
|
|
1074
|
+
}
|
|
1075
|
+
const template = document.createElement("template");
|
|
1076
|
+
template.innerHTML = html;
|
|
1077
|
+
const content = template.content;
|
|
1078
|
+
const styleProperties = [
|
|
1079
|
+
...(keepColors ? [] : ["color"]),
|
|
1080
|
+
...(keepHighlights ? [] : ["background-color", "background"]),
|
|
1081
|
+
];
|
|
1082
|
+
content.querySelectorAll("[style]").forEach(element => {
|
|
1083
|
+
styleProperties.forEach(property => element.style.removeProperty(property));
|
|
1084
|
+
if (!element.getAttribute("style")?.trim()) {
|
|
1085
|
+
element.removeAttribute("style");
|
|
1086
|
+
}
|
|
1087
|
+
});
|
|
1088
|
+
if (!keepColors) {
|
|
1089
|
+
content.querySelectorAll("font[color]").forEach(font => font.removeAttribute("color"));
|
|
1090
|
+
}
|
|
1091
|
+
if (!keepHighlights) {
|
|
1092
|
+
content.querySelectorAll("[bgcolor]").forEach(element => element.removeAttribute("bgcolor"));
|
|
1093
|
+
content
|
|
1094
|
+
.querySelectorAll("mark")
|
|
1095
|
+
.forEach(mark => mark.replaceWith(...Array.from(mark.childNodes)));
|
|
1096
|
+
}
|
|
1097
|
+
return template.innerHTML;
|
|
1098
|
+
}
|
|
1099
|
+
/**
|
|
1100
|
+
* Runs before every other paste cleanup (the Office cleanup removes the markers it relies on):
|
|
1101
|
+
* records the source of each paste, and marks HTML copied from the editor.
|
|
1102
|
+
*/
|
|
1103
|
+
const AtePasteSourceTracker = Extension.create({
|
|
1104
|
+
name: "atePasteSourceTracker",
|
|
1105
|
+
priority: 100000,
|
|
1106
|
+
addProseMirrorPlugins() {
|
|
1107
|
+
const editor = this.editor;
|
|
1108
|
+
const serializer = DOMSerializer.fromSchema(editor.schema);
|
|
1109
|
+
return [
|
|
1110
|
+
new Plugin({
|
|
1111
|
+
key: new PluginKey("atePasteSourceTracker"),
|
|
1112
|
+
props: {
|
|
1113
|
+
transformPastedHTML: html => {
|
|
1114
|
+
editor.storage.atePaste.source = detectPasteSource(html);
|
|
1115
|
+
return html;
|
|
1116
|
+
},
|
|
1117
|
+
clipboardSerializer: {
|
|
1118
|
+
serializeFragment: (fragment, options) => {
|
|
1119
|
+
const dom = serializer.serializeFragment(fragment, options);
|
|
1120
|
+
dom.firstElementChild?.setAttribute(EDITOR_CLIPBOARD_MARKER, "");
|
|
1121
|
+
return dom;
|
|
1122
|
+
},
|
|
1123
|
+
},
|
|
1124
|
+
},
|
|
1125
|
+
}),
|
|
1126
|
+
];
|
|
1127
|
+
},
|
|
1128
|
+
});
|
|
1129
|
+
/**
|
|
1130
|
+
* Applies `AtePasteConfig` to pasted and dropped HTML, after the Office cleanup:
|
|
1131
|
+
* removes the formats turned off for content from other apps, then calls `transformHTML`.
|
|
1132
|
+
*/
|
|
1133
|
+
const AtePaste = Extension.create({
|
|
1134
|
+
name: "atePaste",
|
|
1135
|
+
addOptions() {
|
|
1136
|
+
return {
|
|
1137
|
+
config: () => ({}),
|
|
1138
|
+
};
|
|
1139
|
+
},
|
|
1140
|
+
addStorage() {
|
|
1141
|
+
return {
|
|
1142
|
+
source: "external",
|
|
1143
|
+
};
|
|
1144
|
+
},
|
|
1145
|
+
addExtensions() {
|
|
1146
|
+
return [AtePasteSourceTracker];
|
|
1147
|
+
},
|
|
1148
|
+
addProseMirrorPlugins() {
|
|
1149
|
+
const options = this.options;
|
|
1150
|
+
const storage = this.storage;
|
|
1151
|
+
return [
|
|
1152
|
+
new Plugin({
|
|
1153
|
+
key: new PluginKey("atePaste"),
|
|
1154
|
+
props: {
|
|
1155
|
+
transformPastedHTML: html => {
|
|
1156
|
+
const config = options.config();
|
|
1157
|
+
const source = storage.source;
|
|
1158
|
+
const stripped = source === "editor" ? html : stripPastedFormats(html, config);
|
|
1159
|
+
if (!config.transformHTML) {
|
|
1160
|
+
return stripped;
|
|
1161
|
+
}
|
|
1162
|
+
try {
|
|
1163
|
+
const transformed = config.transformHTML(stripped, { source });
|
|
1164
|
+
return typeof transformed === "string" ? transformed : stripped;
|
|
1165
|
+
}
|
|
1166
|
+
catch (error) {
|
|
1167
|
+
if (isDevMode()) {
|
|
1168
|
+
console.warn("[ATE] paste.transformHTML failed, inserting the HTML unchanged.", error);
|
|
1169
|
+
}
|
|
1170
|
+
return stripped;
|
|
1171
|
+
}
|
|
1172
|
+
},
|
|
1173
|
+
},
|
|
1174
|
+
}),
|
|
1175
|
+
];
|
|
1176
|
+
},
|
|
1177
|
+
});
|
|
1178
|
+
|
|
999
1179
|
const AteTableExtension = Extension.create({
|
|
1000
1180
|
name: "tableExtension",
|
|
1001
1181
|
addExtensions() {
|
|
@@ -2995,6 +3175,39 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
2995
3175
|
}]
|
|
2996
3176
|
}], ctorParameters: () => [] });
|
|
2997
3177
|
|
|
3178
|
+
/**
|
|
3179
|
+
* Translations seen by one editor instance. The editor provides its own copy and binds its
|
|
3180
|
+
* `locale` input to it; without a locale (or outside an editor) it follows the global
|
|
3181
|
+
* `AteI18nService` locale. Internal: not part of the public API.
|
|
3182
|
+
*/
|
|
3183
|
+
class AteEditorI18n {
|
|
3184
|
+
constructor() {
|
|
3185
|
+
this.global = inject(AteI18nService);
|
|
3186
|
+
this.localeSource = signal(() => undefined);
|
|
3187
|
+
this.translations = computed(() => {
|
|
3188
|
+
const locale = this.localeSource()();
|
|
3189
|
+
return (locale && this.global.getTranslations(locale)) || this.global.translations();
|
|
3190
|
+
});
|
|
3191
|
+
this.toolbar = computed(() => this.translations().toolbar);
|
|
3192
|
+
this.bubbleMenu = computed(() => this.translations().bubbleMenu);
|
|
3193
|
+
this.slashCommands = computed(() => this.translations().slashCommands);
|
|
3194
|
+
this.table = computed(() => this.translations().table);
|
|
3195
|
+
this.imageUpload = computed(() => this.translations().imageUpload);
|
|
3196
|
+
this.editor = computed(() => this.translations().editor);
|
|
3197
|
+
this.common = computed(() => this.translations().common);
|
|
3198
|
+
this.export = computed(() => this.translations().export);
|
|
3199
|
+
}
|
|
3200
|
+
bindLocale(source) {
|
|
3201
|
+
this.localeSource.set(source);
|
|
3202
|
+
}
|
|
3203
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AteEditorI18n, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
3204
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AteEditorI18n, providedIn: "root" }); }
|
|
3205
|
+
}
|
|
3206
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AteEditorI18n, decorators: [{
|
|
3207
|
+
type: Injectable,
|
|
3208
|
+
args: [{ providedIn: "root" }]
|
|
3209
|
+
}] });
|
|
3210
|
+
|
|
2998
3211
|
/**
|
|
2999
3212
|
* Table of Contents Component (Notion-style)
|
|
3000
3213
|
* Dynamically extracts headings from the active editor and displays them.
|
|
@@ -3046,7 +3259,7 @@ class AteTableOfContentsComponent {
|
|
|
3046
3259
|
},
|
|
3047
3260
|
});
|
|
3048
3261
|
this.registry = inject(AteEditorRegistry);
|
|
3049
|
-
this.i18n = inject(
|
|
3262
|
+
this.i18n = inject(AteEditorI18n);
|
|
3050
3263
|
// Computed header title with fallback to i18n
|
|
3051
3264
|
this.headerTitle = computed(() => {
|
|
3052
3265
|
const custom = this.title();
|
|
@@ -3903,7 +4116,7 @@ class AteImageService {
|
|
|
3903
4116
|
this.isImageSelected = computed(() => this.selectedImage() !== null);
|
|
3904
4117
|
/** Resizing state */
|
|
3905
4118
|
this.isResizing = signal(false);
|
|
3906
|
-
this.i18n = inject(
|
|
4119
|
+
this.i18n = inject(AteEditorI18n);
|
|
3907
4120
|
this.t = this.i18n.imageUpload;
|
|
3908
4121
|
/** Upload state signals */
|
|
3909
4122
|
this.isUploading = signal(false);
|
|
@@ -3914,6 +4127,7 @@ class AteImageService {
|
|
|
3914
4127
|
* If set, this handler replaces the default base64 conversion.
|
|
3915
4128
|
*/
|
|
3916
4129
|
this.uploadHandler = null;
|
|
4130
|
+
this.srcResolver = null;
|
|
3917
4131
|
this.currentEditor = null;
|
|
3918
4132
|
}
|
|
3919
4133
|
/** Select and track an image from the editor */
|
|
@@ -4010,7 +4224,10 @@ class AteImageService {
|
|
|
4010
4224
|
img.onload = () => {
|
|
4011
4225
|
this.resizeImage(editor, { width: img.naturalWidth, height: img.naturalHeight });
|
|
4012
4226
|
};
|
|
4013
|
-
|
|
4227
|
+
const storedSrc = editor.getAttributes("resizableImage")["src"];
|
|
4228
|
+
ateResolveImageSrc(this.srcResolver, storedSrc).then(src => {
|
|
4229
|
+
img.src = src;
|
|
4230
|
+
});
|
|
4014
4231
|
}
|
|
4015
4232
|
/** Get current image dimensions */
|
|
4016
4233
|
getImageDimensions(editor) {
|
|
@@ -4036,8 +4253,10 @@ class AteImageService {
|
|
|
4036
4253
|
if (!attrs || !attrs["src"]) {
|
|
4037
4254
|
return;
|
|
4038
4255
|
}
|
|
4039
|
-
const src = attrs["src"];
|
|
4040
4256
|
const fileName = attrs["alt"] || "image";
|
|
4257
|
+
ateResolveImageSrc(this.srcResolver, attrs["src"]).then(src => this.downloadResolvedImage(src, fileName));
|
|
4258
|
+
}
|
|
4259
|
+
downloadResolvedImage(src, fileName) {
|
|
4041
4260
|
// Detect if it's base64 or remote URL
|
|
4042
4261
|
if (src.startsWith("data:") ||
|
|
4043
4262
|
src.startsWith("blob:") ||
|
|
@@ -5066,6 +5285,12 @@ class AteEditorCommandsService {
|
|
|
5066
5285
|
set uploadHandler(handler) {
|
|
5067
5286
|
this.imageService.uploadHandler = handler;
|
|
5068
5287
|
}
|
|
5288
|
+
get srcResolver() {
|
|
5289
|
+
return this.imageService.srcResolver;
|
|
5290
|
+
}
|
|
5291
|
+
set srcResolver(resolver) {
|
|
5292
|
+
this.imageService.srcResolver = resolver;
|
|
5293
|
+
}
|
|
5069
5294
|
/** Update state (called by TiptapStateExtension) */
|
|
5070
5295
|
updateState(state) {
|
|
5071
5296
|
this._editorState.set(state);
|
|
@@ -5499,7 +5724,7 @@ class AteColorPickerComponent {
|
|
|
5499
5724
|
this.disabled = input(false);
|
|
5500
5725
|
this.anchorToText = input(false);
|
|
5501
5726
|
this.colorPickerSvc = inject(AteColorPickerService);
|
|
5502
|
-
this.i18nService = inject(
|
|
5727
|
+
this.i18nService = inject(AteEditorI18n);
|
|
5503
5728
|
this.editorCommands = inject(AteEditorCommandsService);
|
|
5504
5729
|
this.t = this.i18nService.toolbar;
|
|
5505
5730
|
this.state = this.editorCommands.editorState;
|
|
@@ -5613,7 +5838,7 @@ class AteToolbarComponent {
|
|
|
5613
5838
|
this.config = input.required();
|
|
5614
5839
|
this.imageUpload = input({});
|
|
5615
5840
|
this.floating = input(false);
|
|
5616
|
-
this.i18nService = inject(
|
|
5841
|
+
this.i18nService = inject(AteEditorI18n);
|
|
5617
5842
|
this.editorCommands = inject(AteEditorCommandsService);
|
|
5618
5843
|
this.t = this.i18nService.toolbar;
|
|
5619
5844
|
this.state = this.editorCommands.editorState;
|
|
@@ -6218,6 +6443,11 @@ const ATE_DEFAULT_IMAGE_UPLOAD_CONFIG = {
|
|
|
6218
6443
|
allowedTypes: ["image/jpeg", "image/png", "image/gif", "image/webp"],
|
|
6219
6444
|
quality: 0.8,
|
|
6220
6445
|
};
|
|
6446
|
+
/** Default paste settings: everything pasted from other apps is kept */
|
|
6447
|
+
const ATE_DEFAULT_PASTE_CONFIG = {
|
|
6448
|
+
colors: true,
|
|
6449
|
+
highlights: true,
|
|
6450
|
+
};
|
|
6221
6451
|
/**
|
|
6222
6452
|
* Ultimate default configuration for the Angular Tiptap Editor.
|
|
6223
6453
|
* This serves as the 'Level 4' fallback in the configuration hierarchy:
|
|
@@ -6256,6 +6486,7 @@ const ATE_DEFAULT_CONFIG = {
|
|
|
6256
6486
|
bubbleMenu: ATE_DEFAULT_BUBBLE_MENU_CONFIG,
|
|
6257
6487
|
imageBubbleMenu: ATE_DEFAULT_IMAGE_BUBBLE_MENU_CONFIG,
|
|
6258
6488
|
imageUpload: ATE_DEFAULT_IMAGE_UPLOAD_CONFIG,
|
|
6489
|
+
paste: ATE_DEFAULT_PASTE_CONFIG,
|
|
6259
6490
|
tableBubbleMenu: ATE_DEFAULT_TABLE_MENU_CONFIG,
|
|
6260
6491
|
cellBubbleMenu: ATE_DEFAULT_CELL_MENU_CONFIG,
|
|
6261
6492
|
slashCommands: {},
|
|
@@ -6272,7 +6503,7 @@ const ATE_DEFAULT_CONFIG = {
|
|
|
6272
6503
|
*/
|
|
6273
6504
|
class AteBaseBubbleMenu {
|
|
6274
6505
|
constructor() {
|
|
6275
|
-
this.i18nService = inject(
|
|
6506
|
+
this.i18nService = inject(AteEditorI18n);
|
|
6276
6507
|
this.editorCommands = inject(AteEditorCommandsService);
|
|
6277
6508
|
// Core Inputs
|
|
6278
6509
|
this.editor = input.required();
|
|
@@ -7477,7 +7708,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
7477
7708
|
*/
|
|
7478
7709
|
class AteBaseSubBubbleMenu {
|
|
7479
7710
|
constructor() {
|
|
7480
|
-
this.i18nService = inject(
|
|
7711
|
+
this.i18nService = inject(AteEditorI18n);
|
|
7481
7712
|
this.editorCommands = inject(AteEditorCommandsService);
|
|
7482
7713
|
// Core Inputs
|
|
7483
7714
|
this.editor = input.required();
|
|
@@ -8372,7 +8603,7 @@ function filterSlashCommands(config, i18n, commands, imageOptions) {
|
|
|
8372
8603
|
// Default command definitions are now centralized in src/lib/config/slash-commands.config.ts
|
|
8373
8604
|
class AteSlashCommandsComponent {
|
|
8374
8605
|
constructor() {
|
|
8375
|
-
this.i18nService = inject(
|
|
8606
|
+
this.i18nService = inject(AteEditorI18n);
|
|
8376
8607
|
this.editor = input.required();
|
|
8377
8608
|
this.config = input(undefined);
|
|
8378
8609
|
this.menuRef = viewChild.required("menuRef");
|
|
@@ -8718,7 +8949,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
8718
8949
|
*/
|
|
8719
8950
|
class AteBlockControlsComponent {
|
|
8720
8951
|
constructor() {
|
|
8721
|
-
this.i18n = inject(
|
|
8952
|
+
this.i18n = inject(AteEditorI18n);
|
|
8722
8953
|
this.editor = input.required();
|
|
8723
8954
|
this.hoveredData = input(null);
|
|
8724
8955
|
this.menuRef = viewChild.required("menuRef");
|
|
@@ -9556,6 +9787,8 @@ const ATE_BUILTIN_UI_DEPENDENCIES = {
|
|
|
9556
9787
|
ateLinkShortcut: "Mod+K link editor shortcut",
|
|
9557
9788
|
highlight: "toolbar/bubble menu highlight picker, AteMarksCalculator",
|
|
9558
9789
|
resizableImage: "image node view, image bubble menu, image upload/resize service, AteImageCalculator",
|
|
9790
|
+
atePaste: "paste settings (`paste` input / config): format filters and `transformHTML`",
|
|
9791
|
+
atePasteSourceTracker: "paste source detection (`editor` / `office` / `external`) for the `paste` settings",
|
|
9559
9792
|
atePastedImage: "pasted HTML image sanitization and base64 re-hosting",
|
|
9560
9793
|
ateUploadProgress: "image upload progress overlay",
|
|
9561
9794
|
tableExtension: "toolbar/slash menu table insertion, table/cell bubble menus, AteTableCalculator",
|
|
@@ -9670,6 +9903,11 @@ class AngularTiptapEditorComponent {
|
|
|
9670
9903
|
this.stateCalculators = input(undefined);
|
|
9671
9904
|
// Nouveau input pour la configuration de l'upload d'images
|
|
9672
9905
|
this.imageUpload = input(undefined);
|
|
9906
|
+
/**
|
|
9907
|
+
* What is kept from HTML pasted or dropped from other apps (`colors`, `highlights`),
|
|
9908
|
+
* and an optional `transformHTML` hook. Merged over `config.paste`.
|
|
9909
|
+
*/
|
|
9910
|
+
this.paste = input(undefined);
|
|
9673
9911
|
/**
|
|
9674
9912
|
* Custom handler for image uploads.
|
|
9675
9913
|
* When provided, images will be processed through this handler instead of being converted to base64.
|
|
@@ -9690,6 +9928,11 @@ class AngularTiptapEditorComponent {
|
|
|
9690
9928
|
* ```
|
|
9691
9929
|
*/
|
|
9692
9930
|
this.imageUploadHandler = input(undefined);
|
|
9931
|
+
/**
|
|
9932
|
+
* Maps the `src` stored in the document to the URL the editor displays and downloads.
|
|
9933
|
+
* The document, `getHTML()` and exports keep the original `src`.
|
|
9934
|
+
*/
|
|
9935
|
+
this.imageSrcResolver = input(undefined);
|
|
9693
9936
|
/**
|
|
9694
9937
|
* Optional unique identifier for the editor instance in the registry.
|
|
9695
9938
|
* If not specified, a unique ID is automatically generated.
|
|
@@ -9849,7 +10092,7 @@ class AngularTiptapEditorComponent {
|
|
|
9849
10092
|
? fromInputOptions
|
|
9850
10093
|
: fromConfigOptions;
|
|
9851
10094
|
return {
|
|
9852
|
-
commands: filterSlashCommands(baseConfig || {}, this.
|
|
10095
|
+
commands: filterSlashCommands(baseConfig || {}, this.editorI18n, this.editorCommandsService, this.finalImageUploadConfig()),
|
|
9853
10096
|
};
|
|
9854
10097
|
});
|
|
9855
10098
|
// Behavior
|
|
@@ -9868,6 +10111,12 @@ class AngularTiptapEditorComponent {
|
|
|
9868
10111
|
this.finalAngularNodesConfig = computed(() => this.effectiveConfig().angularNodes ?? [], {
|
|
9869
10112
|
equal: shallowArrayEqual,
|
|
9870
10113
|
});
|
|
10114
|
+
// Paste
|
|
10115
|
+
this.finalPasteConfig = computed(() => ({
|
|
10116
|
+
...ATE_DEFAULT_PASTE_CONFIG,
|
|
10117
|
+
...this.effectiveConfig().paste,
|
|
10118
|
+
...this.paste(),
|
|
10119
|
+
}));
|
|
9871
10120
|
// Image Upload
|
|
9872
10121
|
this.finalImageUploadConfig = computed(() => {
|
|
9873
10122
|
const fromInput = this.imageUpload();
|
|
@@ -9883,15 +10132,11 @@ class AngularTiptapEditorComponent {
|
|
|
9883
10132
|
maxSize: (merged.maxSize ?? 5) * 1024 * 1024, // Convert MB to bytes for internal service
|
|
9884
10133
|
};
|
|
9885
10134
|
});
|
|
10135
|
+
this.finalImageSrcResolver = computed(() => this.imageSrcResolver() ?? this.effectiveConfig().imageSrcResolver);
|
|
9886
10136
|
this.finalImageUploadHandler = computed(() => this.imageUploadHandler() ?? this.effectiveConfig().imageUpload?.handler);
|
|
9887
|
-
|
|
9888
|
-
|
|
9889
|
-
|
|
9890
|
-
if (localeOverride) {
|
|
9891
|
-
return this.i18nService.getTranslations(localeOverride) ?? this.i18nService.translations();
|
|
9892
|
-
}
|
|
9893
|
-
return this.i18nService.translations();
|
|
9894
|
-
});
|
|
10137
|
+
this.editorI18n = inject(AteEditorI18n);
|
|
10138
|
+
// Current translations (per-instance override via config or input, else the global locale)
|
|
10139
|
+
this.currentTranslations = this.editorI18n.translations;
|
|
9895
10140
|
this._destroyRef = inject(DestroyRef);
|
|
9896
10141
|
// NgControl for management of FormControls
|
|
9897
10142
|
this.ngControl = inject(NgControl, { self: true, optional: true });
|
|
@@ -9915,6 +10160,7 @@ class AngularTiptapEditorComponent {
|
|
|
9915
10160
|
const fromGlobal = this.globalConfig || {};
|
|
9916
10161
|
return { ...ATE_DEFAULT_CONFIG, ...fromGlobal, ...fromInput };
|
|
9917
10162
|
});
|
|
10163
|
+
this.editorI18n.bindLocale(this.finalLocale);
|
|
9918
10164
|
// Effect to update editor content (with anti-echo)
|
|
9919
10165
|
effect(() => {
|
|
9920
10166
|
const content = this.content(); // Sole reactive dependency
|
|
@@ -9970,6 +10216,23 @@ class AngularTiptapEditorComponent {
|
|
|
9970
10216
|
const handler = this.finalImageUploadHandler();
|
|
9971
10217
|
this.editorCommandsService.uploadHandler = handler || null;
|
|
9972
10218
|
}, { allowSignalWrites: true });
|
|
10219
|
+
// Effect to refresh the placeholder decoration when its resolved text changes
|
|
10220
|
+
effect(() => {
|
|
10221
|
+
const editor = this.editor();
|
|
10222
|
+
this.finalPlaceholder();
|
|
10223
|
+
if (editor && !editor.isDestroyed) {
|
|
10224
|
+
untracked(() => editor.view.dispatch(editor.state.tr));
|
|
10225
|
+
}
|
|
10226
|
+
});
|
|
10227
|
+
// Effect to re-apply the image src resolver to the displayed images when it changes
|
|
10228
|
+
// (e.g. a resolver set after the editor was created, or a new one after a token refresh)
|
|
10229
|
+
effect(() => {
|
|
10230
|
+
this.editorCommandsService.srcResolver = this.finalImageSrcResolver() ?? null;
|
|
10231
|
+
const editor = untracked(() => this.editor());
|
|
10232
|
+
if (editor && !editor.isDestroyed) {
|
|
10233
|
+
editor.storage.resizableImage?.srcRefreshers.forEach(refresh => refresh());
|
|
10234
|
+
}
|
|
10235
|
+
});
|
|
9973
10236
|
// Effect to update character count limit dynamically
|
|
9974
10237
|
effect(() => {
|
|
9975
10238
|
const editor = this.editor();
|
|
@@ -10028,6 +10291,7 @@ class AngularTiptapEditorComponent {
|
|
|
10028
10291
|
}
|
|
10029
10292
|
}
|
|
10030
10293
|
initEditor() {
|
|
10294
|
+
this.editorCommandsService.srcResolver = this.finalImageSrcResolver() ?? null;
|
|
10031
10295
|
const starterKitOptions = this.finalStarterKitOptions();
|
|
10032
10296
|
const customExtensions = this.finalTiptapExtensions();
|
|
10033
10297
|
const customNames = new Set(customExtensions.map(getExtensionName).filter((name) => !!name));
|
|
@@ -10073,7 +10337,7 @@ class AngularTiptapEditorComponent {
|
|
|
10073
10337
|
types: ["textStyle"],
|
|
10074
10338
|
}),
|
|
10075
10339
|
Placeholder.configure({
|
|
10076
|
-
placeholder: this.finalPlaceholder(),
|
|
10340
|
+
placeholder: () => this.finalPlaceholder(),
|
|
10077
10341
|
}),
|
|
10078
10342
|
Superscript,
|
|
10079
10343
|
Subscript,
|
|
@@ -10084,6 +10348,9 @@ class AngularTiptapEditorComponent {
|
|
|
10084
10348
|
AteBlockShortcuts.configure({
|
|
10085
10349
|
enabled: () => this.finalEnableBlockShortcuts(),
|
|
10086
10350
|
}),
|
|
10351
|
+
AtePaste.configure({
|
|
10352
|
+
config: () => this.finalPasteConfig(),
|
|
10353
|
+
}),
|
|
10087
10354
|
AteLinkShortcut.configure({
|
|
10088
10355
|
canOpen: () => this.editorCommandsService.editorState().can.toggleLink,
|
|
10089
10356
|
open: editor => this.editorCommandsService.execute(editor, "toggleLink"),
|
|
@@ -10100,6 +10367,7 @@ class AngularTiptapEditorComponent {
|
|
|
10100
10367
|
HTMLAttributes: {
|
|
10101
10368
|
class: "ate-image",
|
|
10102
10369
|
},
|
|
10370
|
+
srcResolver: () => this.editorCommandsService.srcResolver,
|
|
10103
10371
|
}),
|
|
10104
10372
|
AtePastedImage.configure({
|
|
10105
10373
|
shouldRehost: () => this.editorCommandsService.hasUploadHandler,
|
|
@@ -10412,12 +10680,13 @@ class AngularTiptapEditorComponent {
|
|
|
10412
10680
|
}
|
|
10413
10681
|
}
|
|
10414
10682
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AngularTiptapEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
10415
|
-
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 }, enableBlockShortcuts: { classPropertyName: "enableBlockShortcuts", publicName: "enableBlockShortcuts", 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 }, starterKitOptions: { classPropertyName: "starterKitOptions", publicName: "starterKitOptions", 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", imageRejected: "imageRejected", 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: [
|
|
10683
|
+
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 }, enableBlockShortcuts: { classPropertyName: "enableBlockShortcuts", publicName: "enableBlockShortcuts", 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 }, starterKitOptions: { classPropertyName: "starterKitOptions", publicName: "starterKitOptions", 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 }, paste: { classPropertyName: "paste", publicName: "paste", isSignal: true, isRequired: false, transformFunction: null }, imageUploadHandler: { classPropertyName: "imageUploadHandler", publicName: "imageUploadHandler", isSignal: true, isRequired: false, transformFunction: null }, imageSrcResolver: { classPropertyName: "imageSrcResolver", publicName: "imageSrcResolver", 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", imageRejected: "imageRejected", 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: [
|
|
10416
10684
|
AteEditorCommandsService,
|
|
10417
10685
|
AteImageService,
|
|
10418
10686
|
AteColorPickerService,
|
|
10419
10687
|
AteLinkService,
|
|
10420
10688
|
AteExportService,
|
|
10689
|
+
AteEditorI18n,
|
|
10421
10690
|
], viewQueries: [{ propertyName: "editorElement", first: true, predicate: ["editorElement"], descendants: true, isSignal: true }], hostDirectives: [{ directive: AteNoopValueAccessorDirective }], ngImport: i0, template: `
|
|
10422
10691
|
<div class="ate-editor">
|
|
10423
10692
|
<!-- Toolbar -->
|
|
@@ -10587,6 +10856,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
10587
10856
|
AteColorPickerService,
|
|
10588
10857
|
AteLinkService,
|
|
10589
10858
|
AteExportService,
|
|
10859
|
+
AteEditorI18n,
|
|
10590
10860
|
], template: `
|
|
10591
10861
|
<div class="ate-editor">
|
|
10592
10862
|
<!-- Toolbar -->
|
|
@@ -10908,5 +11178,5 @@ const ATE_DEFAULT_TOC_CONFIG = {
|
|
|
10908
11178
|
* Generated bundle index. Do not edit.
|
|
10909
11179
|
*/
|
|
10910
11180
|
|
|
10911
|
-
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, AteBlockShortcuts, AteColorPickerService, AteDiscoveryCalculator, AteEditorCommandsService, AteEditorRef, AteEditorRegistry, AteExportService, AteI18nService, AteIconComponent, AteIconRegistry, AteImageCalculator, AteImageService, AteImageValidationError, AteLinkService, AteLinkShortcut, AteMarksCalculator, AteNodeViewRenderer, AteNoopValueAccessorDirective, AtePastedImage, AteSelectionCalculator, AteStructureCalculator, AteTableCalculator, AteTableOfContentsComponent, AteTocNodeComponent, AteTocNodeOptions, AteTooltipDirective, classifyPastedImageSrc, createAngularComponentExtension, createDefaultSlashCommands, dataUriToFile, filterSlashCommands, getAteTocNodeExtension, isLinkShortcut, provideAteEditor, provideAteIcons, registerAngularComponent, sanitizePastedImages };
|
|
11181
|
+
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_PASTE_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, AteBlockShortcuts, AteColorPickerService, AteDiscoveryCalculator, AteEditorCommandsService, AteEditorRef, AteEditorRegistry, AteExportService, AteI18nService, AteIconComponent, AteIconRegistry, AteImageCalculator, AteImageService, AteImageValidationError, AteLinkService, AteLinkShortcut, AteMarksCalculator, AteNodeViewRenderer, AteNoopValueAccessorDirective, AtePastedImage, AteSelectionCalculator, AteStructureCalculator, AteTableCalculator, AteTableOfContentsComponent, AteTocNodeComponent, AteTocNodeOptions, AteTooltipDirective, classifyPastedImageSrc, createAngularComponentExtension, createDefaultSlashCommands, dataUriToFile, filterSlashCommands, getAteTocNodeExtension, isLinkShortcut, provideAteEditor, provideAteIcons, registerAngularComponent, sanitizePastedImages };
|
|
10912
11182
|
//# sourceMappingURL=flogeez-angular-tiptap-editor.mjs.map
|