@flogeez/angular-tiptap-editor 3.6.0 → 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 +18 -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/directives/ate-tooltip.directive.mjs +37 -2
- 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 +333 -28
- 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();
|
|
@@ -3608,6 +3821,14 @@ const AteTiptapStateExtension = Extension.create({
|
|
|
3608
3821
|
|
|
3609
3822
|
// Pre-calculate platform once to avoid repeated checks
|
|
3610
3823
|
const IS_MAC = typeof window !== "undefined" && /Mac|iPod|iPhone|iPad/.test(navigator.platform);
|
|
3824
|
+
const DURATION = [100, 100];
|
|
3825
|
+
// After a tooltip closes, the next one still opens at once if hovered within this gap
|
|
3826
|
+
const WARM_GAP = 300;
|
|
3827
|
+
// Shared by every tooltip: the first one waits for its delay, the next ones open at once,
|
|
3828
|
+
// without animation, as long as the pointer moves from one control to the next.
|
|
3829
|
+
let openTooltip = null;
|
|
3830
|
+
let warm = false;
|
|
3831
|
+
let coolTimeout;
|
|
3611
3832
|
class AteTooltipDirective {
|
|
3612
3833
|
constructor() {
|
|
3613
3834
|
this.el = inject(ElementRef);
|
|
@@ -3699,7 +3920,7 @@ class AteTooltipDirective {
|
|
|
3699
3920
|
allowHTML,
|
|
3700
3921
|
placement,
|
|
3701
3922
|
delay,
|
|
3702
|
-
duration:
|
|
3923
|
+
duration: DURATION,
|
|
3703
3924
|
offset: [0, 6],
|
|
3704
3925
|
theme: "ate-tooltip",
|
|
3705
3926
|
touch: ["hold", 500],
|
|
@@ -3708,6 +3929,30 @@ class AteTooltipDirective {
|
|
|
3708
3929
|
aria: {
|
|
3709
3930
|
content: "describedby",
|
|
3710
3931
|
},
|
|
3932
|
+
onTrigger: (instance, event) => {
|
|
3933
|
+
const base = this.delay();
|
|
3934
|
+
const instant = warm && event.type === "mouseenter";
|
|
3935
|
+
instance.setProps({
|
|
3936
|
+
delay: instant ? [0, Array.isArray(base) ? base[1] : base] : base,
|
|
3937
|
+
duration: instant ? [0, DURATION[1]] : DURATION,
|
|
3938
|
+
});
|
|
3939
|
+
},
|
|
3940
|
+
onShow: instance => {
|
|
3941
|
+
// Only one tooltip at a time: the previous one goes away at once
|
|
3942
|
+
if (openTooltip && openTooltip !== instance) {
|
|
3943
|
+
openTooltip.unmount();
|
|
3944
|
+
}
|
|
3945
|
+
openTooltip = instance;
|
|
3946
|
+
warm = true;
|
|
3947
|
+
clearTimeout(coolTimeout);
|
|
3948
|
+
},
|
|
3949
|
+
onHidden: instance => {
|
|
3950
|
+
if (openTooltip !== instance) {
|
|
3951
|
+
return;
|
|
3952
|
+
}
|
|
3953
|
+
openTooltip = null;
|
|
3954
|
+
coolTimeout = setTimeout(() => (warm = false), WARM_GAP);
|
|
3955
|
+
},
|
|
3711
3956
|
popperOptions: {
|
|
3712
3957
|
modifiers: [
|
|
3713
3958
|
{
|
|
@@ -3723,6 +3968,9 @@ class AteTooltipDirective {
|
|
|
3723
3968
|
}
|
|
3724
3969
|
destroyTippy() {
|
|
3725
3970
|
if (this.tippyInstance) {
|
|
3971
|
+
if (openTooltip === this.tippyInstance) {
|
|
3972
|
+
openTooltip = null;
|
|
3973
|
+
}
|
|
3726
3974
|
this.tippyInstance.destroy();
|
|
3727
3975
|
this.tippyInstance = null;
|
|
3728
3976
|
}
|
|
@@ -3868,7 +4116,7 @@ class AteImageService {
|
|
|
3868
4116
|
this.isImageSelected = computed(() => this.selectedImage() !== null);
|
|
3869
4117
|
/** Resizing state */
|
|
3870
4118
|
this.isResizing = signal(false);
|
|
3871
|
-
this.i18n = inject(
|
|
4119
|
+
this.i18n = inject(AteEditorI18n);
|
|
3872
4120
|
this.t = this.i18n.imageUpload;
|
|
3873
4121
|
/** Upload state signals */
|
|
3874
4122
|
this.isUploading = signal(false);
|
|
@@ -3879,6 +4127,7 @@ class AteImageService {
|
|
|
3879
4127
|
* If set, this handler replaces the default base64 conversion.
|
|
3880
4128
|
*/
|
|
3881
4129
|
this.uploadHandler = null;
|
|
4130
|
+
this.srcResolver = null;
|
|
3882
4131
|
this.currentEditor = null;
|
|
3883
4132
|
}
|
|
3884
4133
|
/** Select and track an image from the editor */
|
|
@@ -3975,7 +4224,10 @@ class AteImageService {
|
|
|
3975
4224
|
img.onload = () => {
|
|
3976
4225
|
this.resizeImage(editor, { width: img.naturalWidth, height: img.naturalHeight });
|
|
3977
4226
|
};
|
|
3978
|
-
|
|
4227
|
+
const storedSrc = editor.getAttributes("resizableImage")["src"];
|
|
4228
|
+
ateResolveImageSrc(this.srcResolver, storedSrc).then(src => {
|
|
4229
|
+
img.src = src;
|
|
4230
|
+
});
|
|
3979
4231
|
}
|
|
3980
4232
|
/** Get current image dimensions */
|
|
3981
4233
|
getImageDimensions(editor) {
|
|
@@ -4001,8 +4253,10 @@ class AteImageService {
|
|
|
4001
4253
|
if (!attrs || !attrs["src"]) {
|
|
4002
4254
|
return;
|
|
4003
4255
|
}
|
|
4004
|
-
const src = attrs["src"];
|
|
4005
4256
|
const fileName = attrs["alt"] || "image";
|
|
4257
|
+
ateResolveImageSrc(this.srcResolver, attrs["src"]).then(src => this.downloadResolvedImage(src, fileName));
|
|
4258
|
+
}
|
|
4259
|
+
downloadResolvedImage(src, fileName) {
|
|
4006
4260
|
// Detect if it's base64 or remote URL
|
|
4007
4261
|
if (src.startsWith("data:") ||
|
|
4008
4262
|
src.startsWith("blob:") ||
|
|
@@ -5031,6 +5285,12 @@ class AteEditorCommandsService {
|
|
|
5031
5285
|
set uploadHandler(handler) {
|
|
5032
5286
|
this.imageService.uploadHandler = handler;
|
|
5033
5287
|
}
|
|
5288
|
+
get srcResolver() {
|
|
5289
|
+
return this.imageService.srcResolver;
|
|
5290
|
+
}
|
|
5291
|
+
set srcResolver(resolver) {
|
|
5292
|
+
this.imageService.srcResolver = resolver;
|
|
5293
|
+
}
|
|
5034
5294
|
/** Update state (called by TiptapStateExtension) */
|
|
5035
5295
|
updateState(state) {
|
|
5036
5296
|
this._editorState.set(state);
|
|
@@ -5464,7 +5724,7 @@ class AteColorPickerComponent {
|
|
|
5464
5724
|
this.disabled = input(false);
|
|
5465
5725
|
this.anchorToText = input(false);
|
|
5466
5726
|
this.colorPickerSvc = inject(AteColorPickerService);
|
|
5467
|
-
this.i18nService = inject(
|
|
5727
|
+
this.i18nService = inject(AteEditorI18n);
|
|
5468
5728
|
this.editorCommands = inject(AteEditorCommandsService);
|
|
5469
5729
|
this.t = this.i18nService.toolbar;
|
|
5470
5730
|
this.state = this.editorCommands.editorState;
|
|
@@ -5578,7 +5838,7 @@ class AteToolbarComponent {
|
|
|
5578
5838
|
this.config = input.required();
|
|
5579
5839
|
this.imageUpload = input({});
|
|
5580
5840
|
this.floating = input(false);
|
|
5581
|
-
this.i18nService = inject(
|
|
5841
|
+
this.i18nService = inject(AteEditorI18n);
|
|
5582
5842
|
this.editorCommands = inject(AteEditorCommandsService);
|
|
5583
5843
|
this.t = this.i18nService.toolbar;
|
|
5584
5844
|
this.state = this.editorCommands.editorState;
|
|
@@ -6183,6 +6443,11 @@ const ATE_DEFAULT_IMAGE_UPLOAD_CONFIG = {
|
|
|
6183
6443
|
allowedTypes: ["image/jpeg", "image/png", "image/gif", "image/webp"],
|
|
6184
6444
|
quality: 0.8,
|
|
6185
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
|
+
};
|
|
6186
6451
|
/**
|
|
6187
6452
|
* Ultimate default configuration for the Angular Tiptap Editor.
|
|
6188
6453
|
* This serves as the 'Level 4' fallback in the configuration hierarchy:
|
|
@@ -6221,6 +6486,7 @@ const ATE_DEFAULT_CONFIG = {
|
|
|
6221
6486
|
bubbleMenu: ATE_DEFAULT_BUBBLE_MENU_CONFIG,
|
|
6222
6487
|
imageBubbleMenu: ATE_DEFAULT_IMAGE_BUBBLE_MENU_CONFIG,
|
|
6223
6488
|
imageUpload: ATE_DEFAULT_IMAGE_UPLOAD_CONFIG,
|
|
6489
|
+
paste: ATE_DEFAULT_PASTE_CONFIG,
|
|
6224
6490
|
tableBubbleMenu: ATE_DEFAULT_TABLE_MENU_CONFIG,
|
|
6225
6491
|
cellBubbleMenu: ATE_DEFAULT_CELL_MENU_CONFIG,
|
|
6226
6492
|
slashCommands: {},
|
|
@@ -6237,7 +6503,7 @@ const ATE_DEFAULT_CONFIG = {
|
|
|
6237
6503
|
*/
|
|
6238
6504
|
class AteBaseBubbleMenu {
|
|
6239
6505
|
constructor() {
|
|
6240
|
-
this.i18nService = inject(
|
|
6506
|
+
this.i18nService = inject(AteEditorI18n);
|
|
6241
6507
|
this.editorCommands = inject(AteEditorCommandsService);
|
|
6242
6508
|
// Core Inputs
|
|
6243
6509
|
this.editor = input.required();
|
|
@@ -7442,7 +7708,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
7442
7708
|
*/
|
|
7443
7709
|
class AteBaseSubBubbleMenu {
|
|
7444
7710
|
constructor() {
|
|
7445
|
-
this.i18nService = inject(
|
|
7711
|
+
this.i18nService = inject(AteEditorI18n);
|
|
7446
7712
|
this.editorCommands = inject(AteEditorCommandsService);
|
|
7447
7713
|
// Core Inputs
|
|
7448
7714
|
this.editor = input.required();
|
|
@@ -8337,7 +8603,7 @@ function filterSlashCommands(config, i18n, commands, imageOptions) {
|
|
|
8337
8603
|
// Default command definitions are now centralized in src/lib/config/slash-commands.config.ts
|
|
8338
8604
|
class AteSlashCommandsComponent {
|
|
8339
8605
|
constructor() {
|
|
8340
|
-
this.i18nService = inject(
|
|
8606
|
+
this.i18nService = inject(AteEditorI18n);
|
|
8341
8607
|
this.editor = input.required();
|
|
8342
8608
|
this.config = input(undefined);
|
|
8343
8609
|
this.menuRef = viewChild.required("menuRef");
|
|
@@ -8683,7 +8949,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
8683
8949
|
*/
|
|
8684
8950
|
class AteBlockControlsComponent {
|
|
8685
8951
|
constructor() {
|
|
8686
|
-
this.i18n = inject(
|
|
8952
|
+
this.i18n = inject(AteEditorI18n);
|
|
8687
8953
|
this.editor = input.required();
|
|
8688
8954
|
this.hoveredData = input(null);
|
|
8689
8955
|
this.menuRef = viewChild.required("menuRef");
|
|
@@ -9521,6 +9787,8 @@ const ATE_BUILTIN_UI_DEPENDENCIES = {
|
|
|
9521
9787
|
ateLinkShortcut: "Mod+K link editor shortcut",
|
|
9522
9788
|
highlight: "toolbar/bubble menu highlight picker, AteMarksCalculator",
|
|
9523
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",
|
|
9524
9792
|
atePastedImage: "pasted HTML image sanitization and base64 re-hosting",
|
|
9525
9793
|
ateUploadProgress: "image upload progress overlay",
|
|
9526
9794
|
tableExtension: "toolbar/slash menu table insertion, table/cell bubble menus, AteTableCalculator",
|
|
@@ -9635,6 +9903,11 @@ class AngularTiptapEditorComponent {
|
|
|
9635
9903
|
this.stateCalculators = input(undefined);
|
|
9636
9904
|
// Nouveau input pour la configuration de l'upload d'images
|
|
9637
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);
|
|
9638
9911
|
/**
|
|
9639
9912
|
* Custom handler for image uploads.
|
|
9640
9913
|
* When provided, images will be processed through this handler instead of being converted to base64.
|
|
@@ -9655,6 +9928,11 @@ class AngularTiptapEditorComponent {
|
|
|
9655
9928
|
* ```
|
|
9656
9929
|
*/
|
|
9657
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);
|
|
9658
9936
|
/**
|
|
9659
9937
|
* Optional unique identifier for the editor instance in the registry.
|
|
9660
9938
|
* If not specified, a unique ID is automatically generated.
|
|
@@ -9814,7 +10092,7 @@ class AngularTiptapEditorComponent {
|
|
|
9814
10092
|
? fromInputOptions
|
|
9815
10093
|
: fromConfigOptions;
|
|
9816
10094
|
return {
|
|
9817
|
-
commands: filterSlashCommands(baseConfig || {}, this.
|
|
10095
|
+
commands: filterSlashCommands(baseConfig || {}, this.editorI18n, this.editorCommandsService, this.finalImageUploadConfig()),
|
|
9818
10096
|
};
|
|
9819
10097
|
});
|
|
9820
10098
|
// Behavior
|
|
@@ -9833,6 +10111,12 @@ class AngularTiptapEditorComponent {
|
|
|
9833
10111
|
this.finalAngularNodesConfig = computed(() => this.effectiveConfig().angularNodes ?? [], {
|
|
9834
10112
|
equal: shallowArrayEqual,
|
|
9835
10113
|
});
|
|
10114
|
+
// Paste
|
|
10115
|
+
this.finalPasteConfig = computed(() => ({
|
|
10116
|
+
...ATE_DEFAULT_PASTE_CONFIG,
|
|
10117
|
+
...this.effectiveConfig().paste,
|
|
10118
|
+
...this.paste(),
|
|
10119
|
+
}));
|
|
9836
10120
|
// Image Upload
|
|
9837
10121
|
this.finalImageUploadConfig = computed(() => {
|
|
9838
10122
|
const fromInput = this.imageUpload();
|
|
@@ -9848,15 +10132,11 @@ class AngularTiptapEditorComponent {
|
|
|
9848
10132
|
maxSize: (merged.maxSize ?? 5) * 1024 * 1024, // Convert MB to bytes for internal service
|
|
9849
10133
|
};
|
|
9850
10134
|
});
|
|
10135
|
+
this.finalImageSrcResolver = computed(() => this.imageSrcResolver() ?? this.effectiveConfig().imageSrcResolver);
|
|
9851
10136
|
this.finalImageUploadHandler = computed(() => this.imageUploadHandler() ?? this.effectiveConfig().imageUpload?.handler);
|
|
9852
|
-
|
|
9853
|
-
|
|
9854
|
-
|
|
9855
|
-
if (localeOverride) {
|
|
9856
|
-
return this.i18nService.getTranslations(localeOverride) ?? this.i18nService.translations();
|
|
9857
|
-
}
|
|
9858
|
-
return this.i18nService.translations();
|
|
9859
|
-
});
|
|
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;
|
|
9860
10140
|
this._destroyRef = inject(DestroyRef);
|
|
9861
10141
|
// NgControl for management of FormControls
|
|
9862
10142
|
this.ngControl = inject(NgControl, { self: true, optional: true });
|
|
@@ -9880,6 +10160,7 @@ class AngularTiptapEditorComponent {
|
|
|
9880
10160
|
const fromGlobal = this.globalConfig || {};
|
|
9881
10161
|
return { ...ATE_DEFAULT_CONFIG, ...fromGlobal, ...fromInput };
|
|
9882
10162
|
});
|
|
10163
|
+
this.editorI18n.bindLocale(this.finalLocale);
|
|
9883
10164
|
// Effect to update editor content (with anti-echo)
|
|
9884
10165
|
effect(() => {
|
|
9885
10166
|
const content = this.content(); // Sole reactive dependency
|
|
@@ -9935,6 +10216,23 @@ class AngularTiptapEditorComponent {
|
|
|
9935
10216
|
const handler = this.finalImageUploadHandler();
|
|
9936
10217
|
this.editorCommandsService.uploadHandler = handler || null;
|
|
9937
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
|
+
});
|
|
9938
10236
|
// Effect to update character count limit dynamically
|
|
9939
10237
|
effect(() => {
|
|
9940
10238
|
const editor = this.editor();
|
|
@@ -9993,6 +10291,7 @@ class AngularTiptapEditorComponent {
|
|
|
9993
10291
|
}
|
|
9994
10292
|
}
|
|
9995
10293
|
initEditor() {
|
|
10294
|
+
this.editorCommandsService.srcResolver = this.finalImageSrcResolver() ?? null;
|
|
9996
10295
|
const starterKitOptions = this.finalStarterKitOptions();
|
|
9997
10296
|
const customExtensions = this.finalTiptapExtensions();
|
|
9998
10297
|
const customNames = new Set(customExtensions.map(getExtensionName).filter((name) => !!name));
|
|
@@ -10038,7 +10337,7 @@ class AngularTiptapEditorComponent {
|
|
|
10038
10337
|
types: ["textStyle"],
|
|
10039
10338
|
}),
|
|
10040
10339
|
Placeholder.configure({
|
|
10041
|
-
placeholder: this.finalPlaceholder(),
|
|
10340
|
+
placeholder: () => this.finalPlaceholder(),
|
|
10042
10341
|
}),
|
|
10043
10342
|
Superscript,
|
|
10044
10343
|
Subscript,
|
|
@@ -10049,6 +10348,9 @@ class AngularTiptapEditorComponent {
|
|
|
10049
10348
|
AteBlockShortcuts.configure({
|
|
10050
10349
|
enabled: () => this.finalEnableBlockShortcuts(),
|
|
10051
10350
|
}),
|
|
10351
|
+
AtePaste.configure({
|
|
10352
|
+
config: () => this.finalPasteConfig(),
|
|
10353
|
+
}),
|
|
10052
10354
|
AteLinkShortcut.configure({
|
|
10053
10355
|
canOpen: () => this.editorCommandsService.editorState().can.toggleLink,
|
|
10054
10356
|
open: editor => this.editorCommandsService.execute(editor, "toggleLink"),
|
|
@@ -10065,6 +10367,7 @@ class AngularTiptapEditorComponent {
|
|
|
10065
10367
|
HTMLAttributes: {
|
|
10066
10368
|
class: "ate-image",
|
|
10067
10369
|
},
|
|
10370
|
+
srcResolver: () => this.editorCommandsService.srcResolver,
|
|
10068
10371
|
}),
|
|
10069
10372
|
AtePastedImage.configure({
|
|
10070
10373
|
shouldRehost: () => this.editorCommandsService.hasUploadHandler,
|
|
@@ -10377,12 +10680,13 @@ class AngularTiptapEditorComponent {
|
|
|
10377
10680
|
}
|
|
10378
10681
|
}
|
|
10379
10682
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AngularTiptapEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
10380
|
-
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: [
|
|
10381
10684
|
AteEditorCommandsService,
|
|
10382
10685
|
AteImageService,
|
|
10383
10686
|
AteColorPickerService,
|
|
10384
10687
|
AteLinkService,
|
|
10385
10688
|
AteExportService,
|
|
10689
|
+
AteEditorI18n,
|
|
10386
10690
|
], viewQueries: [{ propertyName: "editorElement", first: true, predicate: ["editorElement"], descendants: true, isSignal: true }], hostDirectives: [{ directive: AteNoopValueAccessorDirective }], ngImport: i0, template: `
|
|
10387
10691
|
<div class="ate-editor">
|
|
10388
10692
|
<!-- Toolbar -->
|
|
@@ -10552,6 +10856,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
10552
10856
|
AteColorPickerService,
|
|
10553
10857
|
AteLinkService,
|
|
10554
10858
|
AteExportService,
|
|
10859
|
+
AteEditorI18n,
|
|
10555
10860
|
], template: `
|
|
10556
10861
|
<div class="ate-editor">
|
|
10557
10862
|
<!-- Toolbar -->
|
|
@@ -10873,5 +11178,5 @@ const ATE_DEFAULT_TOC_CONFIG = {
|
|
|
10873
11178
|
* Generated bundle index. Do not edit.
|
|
10874
11179
|
*/
|
|
10875
11180
|
|
|
10876
|
-
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 };
|
|
10877
11182
|
//# sourceMappingURL=flogeez-angular-tiptap-editor.mjs.map
|