@flogeez/angular-tiptap-editor 3.2.0 → 3.2.2
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/esm2022/lib/components/bubble-menus/base/ate-base-bubble-menu.mjs +1 -1
- package/esm2022/lib/components/bubble-menus/base/ate-base-sub-bubble-menu.mjs +1 -1
- package/esm2022/lib/components/bubble-menus/link/ate-link-bubble-menu.component.mjs +1 -1
- package/esm2022/lib/components/editor/angular-tiptap-editor.component.mjs +19 -3
- package/esm2022/lib/components/slash-commands/ate-slash-commands.component.mjs +1 -1
- package/esm2022/lib/extensions/ate-resizable-image.extension.mjs +20 -14
- package/esm2022/lib/models/ate-editor-ref.mjs +1 -1
- package/esm2022/lib/services/ate-editor-commands.service.mjs +4 -1
- package/esm2022/lib/services/ate-image.service.mjs +4 -1
- package/esm2022/lib/utils/ate-markdown.utils.mjs +2 -4
- package/fesm2022/flogeez-angular-tiptap-editor.mjs +44 -18
- package/fesm2022/flogeez-angular-tiptap-editor.mjs.map +1 -1
- package/lib/components/editor/angular-tiptap-editor.component.d.ts +3 -2
- package/lib/services/ate-editor-commands.service.d.ts +2 -1
- package/lib/services/ate-image.service.d.ts +1 -0
- package/package.json +1 -1
|
@@ -119,28 +119,29 @@ const AteResizableImage = Node$1.create({
|
|
|
119
119
|
},
|
|
120
120
|
addNodeView() {
|
|
121
121
|
return ({ node, getPos, editor }) => {
|
|
122
|
+
let currentNode = node;
|
|
122
123
|
const wrapper = document.createElement("div");
|
|
123
124
|
wrapper.className = "resizable-image-wrapper";
|
|
124
125
|
wrapper.style.display = "block";
|
|
125
|
-
if (
|
|
126
|
-
wrapper.style.textAlign =
|
|
127
|
-
wrapper.setAttribute("data-align",
|
|
126
|
+
if (currentNode.attrs["textAlign"]) {
|
|
127
|
+
wrapper.style.textAlign = currentNode.attrs["textAlign"];
|
|
128
|
+
wrapper.setAttribute("data-align", currentNode.attrs["textAlign"]);
|
|
128
129
|
}
|
|
129
130
|
const container = document.createElement("div");
|
|
130
131
|
container.className = "resizable-image-container";
|
|
131
132
|
container.style.position = "relative";
|
|
132
133
|
container.style.display = "inline-block";
|
|
133
134
|
const img = document.createElement("img");
|
|
134
|
-
img.src =
|
|
135
|
-
img.alt =
|
|
136
|
-
img.title =
|
|
135
|
+
img.src = currentNode.attrs["src"];
|
|
136
|
+
img.alt = currentNode.attrs["alt"] || "";
|
|
137
|
+
img.title = currentNode.attrs["title"] || "";
|
|
137
138
|
img.className = "ate-image";
|
|
138
139
|
img.style.display = "inline-block"; // Ensure it respects container text-align
|
|
139
|
-
if (
|
|
140
|
-
img.width =
|
|
140
|
+
if (currentNode.attrs["width"]) {
|
|
141
|
+
img.width = currentNode.attrs["width"];
|
|
141
142
|
}
|
|
142
|
-
if (
|
|
143
|
-
img.height =
|
|
143
|
+
if (currentNode.attrs["height"]) {
|
|
144
|
+
img.height = currentNode.attrs["height"];
|
|
144
145
|
}
|
|
145
146
|
wrapper.appendChild(container);
|
|
146
147
|
container.appendChild(img);
|
|
@@ -187,9 +188,13 @@ const AteResizableImage = Node$1.create({
|
|
|
187
188
|
startX = e.clientX;
|
|
188
189
|
// Use current image dimensions instead of initial ones
|
|
189
190
|
startWidth =
|
|
190
|
-
parseInt(img.getAttribute("width") || "0") ||
|
|
191
|
+
parseInt(img.getAttribute("width") || "0") ||
|
|
192
|
+
currentNode.attrs["width"] ||
|
|
193
|
+
img.naturalWidth;
|
|
191
194
|
startHeight =
|
|
192
|
-
parseInt(img.getAttribute("height") || "0") ||
|
|
195
|
+
parseInt(img.getAttribute("height") || "0") ||
|
|
196
|
+
currentNode.attrs["height"] ||
|
|
197
|
+
img.naturalHeight;
|
|
193
198
|
// Add resizing class to body
|
|
194
199
|
document.body.classList.add("resizing");
|
|
195
200
|
const handleMouseMove = (e) => {
|
|
@@ -227,7 +232,7 @@ const AteResizableImage = Node$1.create({
|
|
|
227
232
|
const finalHeight = parseInt(img.getAttribute("height") || "0");
|
|
228
233
|
if (finalWidth && finalHeight) {
|
|
229
234
|
editor.view.dispatch(editor.view.state.tr.setNodeMarkup(pos, undefined, {
|
|
230
|
-
...
|
|
235
|
+
...currentNode.attrs,
|
|
231
236
|
width: finalWidth,
|
|
232
237
|
height: finalHeight,
|
|
233
238
|
}));
|
|
@@ -268,6 +273,7 @@ const AteResizableImage = Node$1.create({
|
|
|
268
273
|
if (updatedNode.type.name !== "resizableImage") {
|
|
269
274
|
return false;
|
|
270
275
|
}
|
|
276
|
+
currentNode = updatedNode;
|
|
271
277
|
img.src = updatedNode.attrs["src"];
|
|
272
278
|
img.alt = updatedNode.attrs["alt"] || "";
|
|
273
279
|
img.title = updatedNode.attrs["title"] || "";
|
|
@@ -1660,6 +1666,9 @@ class AteImageService {
|
|
|
1660
1666
|
this.forceEditorUpdate();
|
|
1661
1667
|
// Final insertion
|
|
1662
1668
|
insertionStrategy(editor, result);
|
|
1669
|
+
if (this.onImageUploadedCallback) {
|
|
1670
|
+
this.onImageUploadedCallback(result);
|
|
1671
|
+
}
|
|
1663
1672
|
this.resetUploadState();
|
|
1664
1673
|
}
|
|
1665
1674
|
catch (error) {
|
|
@@ -2219,9 +2228,7 @@ function convertNode(node, ctx) {
|
|
|
2219
2228
|
if (tag === "pre") {
|
|
2220
2229
|
// Extract language from code class e.g. "language-typescript"
|
|
2221
2230
|
const codeEl = el.querySelector("code");
|
|
2222
|
-
const lang = codeEl
|
|
2223
|
-
? (codeEl.className.match(/language-(\S+)/) || [])[1] || ""
|
|
2224
|
-
: "";
|
|
2231
|
+
const lang = codeEl ? (codeEl.className.match(/language-(\S+)/) || [])[1] || "" : "";
|
|
2225
2232
|
const code = codeEl ? codeEl.textContent || "" : el.textContent || "";
|
|
2226
2233
|
return `\n\n\`\`\`${lang}\n${code}\n\`\`\`\n\n`;
|
|
2227
2234
|
}
|
|
@@ -2492,6 +2499,9 @@ class AteEditorCommandsService {
|
|
|
2492
2499
|
setToolbarInteracting(value) {
|
|
2493
2500
|
this._isToolbarInteracting.set(value);
|
|
2494
2501
|
}
|
|
2502
|
+
set onImageUploaded(callback) {
|
|
2503
|
+
this.imageService.onImageUploadedCallback = callback || undefined;
|
|
2504
|
+
}
|
|
2495
2505
|
set uploadHandler(handler) {
|
|
2496
2506
|
this.imageService.uploadHandler = handler;
|
|
2497
2507
|
}
|
|
@@ -7773,6 +7783,7 @@ class AngularTiptapEditorComponent {
|
|
|
7773
7783
|
this.editorFocus = output();
|
|
7774
7784
|
this.editorBlur = output();
|
|
7775
7785
|
this.editableChange = output();
|
|
7786
|
+
this.imageUploaded = output();
|
|
7776
7787
|
// ViewChild with signal
|
|
7777
7788
|
this.editorElement = viewChild.required("editorElement");
|
|
7778
7789
|
// Private signals for internal state
|
|
@@ -8057,6 +8068,9 @@ class AngularTiptapEditorComponent {
|
|
|
8057
8068
|
}
|
|
8058
8069
|
});
|
|
8059
8070
|
}, { allowSignalWrites: true });
|
|
8071
|
+
this.editorCommandsService.onImageUploaded = result => {
|
|
8072
|
+
this.imageUploaded.emit(result);
|
|
8073
|
+
};
|
|
8060
8074
|
}
|
|
8061
8075
|
ngAfterViewInit() {
|
|
8062
8076
|
// La vue est déjà complètement initialisée dans ngAfterViewInit
|
|
@@ -8393,7 +8407,13 @@ class AngularTiptapEditorComponent {
|
|
|
8393
8407
|
}
|
|
8394
8408
|
}
|
|
8395
8409
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AngularTiptapEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
8396
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: AngularTiptapEditorComponent, isStandalone: true, selector: "angular-tiptap-editor", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null }, content: { classPropertyName: "content", publicName: "content", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, editable: { classPropertyName: "editable", publicName: "editable", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, minHeight: { classPropertyName: "minHeight", publicName: "minHeight", isSignal: true, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null }, maxHeight: { classPropertyName: "maxHeight", publicName: "maxHeight", isSignal: true, isRequired: false, transformFunction: null }, fillContainer: { classPropertyName: "fillContainer", publicName: "fillContainer", isSignal: true, isRequired: false, transformFunction: null }, showToolbar: { classPropertyName: "showToolbar", publicName: "showToolbar", isSignal: true, isRequired: false, transformFunction: null }, showFooter: { classPropertyName: "showFooter", publicName: "showFooter", isSignal: true, isRequired: false, transformFunction: null }, showCharacterCount: { classPropertyName: "showCharacterCount", publicName: "showCharacterCount", isSignal: true, isRequired: false, transformFunction: null }, showWordCount: { classPropertyName: "showWordCount", publicName: "showWordCount", isSignal: true, isRequired: false, transformFunction: null }, maxCharacters: { classPropertyName: "maxCharacters", publicName: "maxCharacters", isSignal: true, isRequired: false, transformFunction: null }, enableOfficePaste: { classPropertyName: "enableOfficePaste", publicName: "enableOfficePaste", isSignal: true, isRequired: false, transformFunction: null }, enableSlashCommands: { classPropertyName: "enableSlashCommands", publicName: "enableSlashCommands", isSignal: true, isRequired: false, transformFunction: null }, slashCommands: { classPropertyName: "slashCommands", publicName: "slashCommands", isSignal: true, isRequired: false, transformFunction: null }, customSlashCommands: { classPropertyName: "customSlashCommands", publicName: "customSlashCommands", isSignal: true, isRequired: false, transformFunction: null }, blockControls: { classPropertyName: "blockControls", publicName: "blockControls", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, autofocus: { classPropertyName: "autofocus", publicName: "autofocus", isSignal: true, isRequired: false, transformFunction: null }, seamless: { classPropertyName: "seamless", publicName: "seamless", isSignal: true, isRequired: false, transformFunction: null }, floatingToolbar: { classPropertyName: "floatingToolbar", publicName: "floatingToolbar", isSignal: true, isRequired: false, transformFunction: null }, showEditToggle: { classPropertyName: "showEditToggle", publicName: "showEditToggle", isSignal: true, isRequired: false, transformFunction: null }, spellcheck: { classPropertyName: "spellcheck", publicName: "spellcheck", isSignal: true, isRequired: false, transformFunction: null }, tiptapExtensions: { classPropertyName: "tiptapExtensions", publicName: "tiptapExtensions", isSignal: true, isRequired: false, transformFunction: null }, tiptapOptions: { classPropertyName: "tiptapOptions", publicName: "tiptapOptions", isSignal: true, isRequired: false, transformFunction: null }, showBubbleMenu: { classPropertyName: "showBubbleMenu", publicName: "showBubbleMenu", isSignal: true, isRequired: false, transformFunction: null }, bubbleMenu: { classPropertyName: "bubbleMenu", publicName: "bubbleMenu", isSignal: true, isRequired: false, transformFunction: null }, showImageBubbleMenu: { classPropertyName: "showImageBubbleMenu", publicName: "showImageBubbleMenu", isSignal: true, isRequired: false, transformFunction: null }, imageBubbleMenu: { classPropertyName: "imageBubbleMenu", publicName: "imageBubbleMenu", isSignal: true, isRequired: false, transformFunction: null }, toolbar: { classPropertyName: "toolbar", publicName: "toolbar", isSignal: true, isRequired: false, transformFunction: null }, showTableBubbleMenu: { classPropertyName: "showTableBubbleMenu", publicName: "showTableBubbleMenu", isSignal: true, isRequired: false, transformFunction: null }, tableBubbleMenu: { classPropertyName: "tableBubbleMenu", publicName: "tableBubbleMenu", isSignal: true, isRequired: false, transformFunction: null }, showCellBubbleMenu: { classPropertyName: "showCellBubbleMenu", publicName: "showCellBubbleMenu", isSignal: true, isRequired: false, transformFunction: null }, cellBubbleMenu: { classPropertyName: "cellBubbleMenu", publicName: "cellBubbleMenu", isSignal: true, isRequired: false, transformFunction: null }, stateCalculators: { classPropertyName: "stateCalculators", publicName: "stateCalculators", isSignal: true, isRequired: false, transformFunction: null }, imageUpload: { classPropertyName: "imageUpload", publicName: "imageUpload", isSignal: true, isRequired: false, transformFunction: null }, imageUploadHandler: { classPropertyName: "imageUploadHandler", publicName: "imageUploadHandler", isSignal: true, isRequired: false, transformFunction: null }, editorId: { classPropertyName: "editorId", publicName: "editorId", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { contentChange: "contentChange", editorCreated: "editorCreated", editorUpdate: "editorUpdate", editorFocus: "editorFocus", editorBlur: "editorBlur", editableChange: "editableChange" }, host: { properties: { "class.fill-container": "finalFillContainer()", "class.floating-toolbar": "finalFloatingToolbar()", "class.is-readonly": "!finalEditable() && !mergedDisabled()", "class.is-disabled": "mergedDisabled()", "style.--ate-border-width": "finalSeamless() || mergedDisabled() ? '0' : null", "style.--ate-background": "finalSeamless() ? 'transparent' : (mergedDisabled() ? 'var(--ate-surface-tertiary)' : null)", "style.--ate-toolbar-border-color": "finalSeamless() ? 'transparent' : null", "style.--ate-counter-background": "finalSeamless() ? 'transparent' : null", "style.--ate-counter-border-color": "finalSeamless() ? 'transparent' : null", "class.dark": "config().theme === 'dark'", "class.ate-blocks-inside": "finalBlockControls() === 'inside'", "class.ate-blocks-outside": "finalBlockControls() === 'outside'", "attr.data-theme": "config().theme" } }, providers: [
|
|
8410
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: AngularTiptapEditorComponent, isStandalone: true, selector: "angular-tiptap-editor", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null }, content: { classPropertyName: "content", publicName: "content", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, editable: { classPropertyName: "editable", publicName: "editable", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, minHeight: { classPropertyName: "minHeight", publicName: "minHeight", isSignal: true, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null }, maxHeight: { classPropertyName: "maxHeight", publicName: "maxHeight", isSignal: true, isRequired: false, transformFunction: null }, fillContainer: { classPropertyName: "fillContainer", publicName: "fillContainer", isSignal: true, isRequired: false, transformFunction: null }, showToolbar: { classPropertyName: "showToolbar", publicName: "showToolbar", isSignal: true, isRequired: false, transformFunction: null }, showFooter: { classPropertyName: "showFooter", publicName: "showFooter", isSignal: true, isRequired: false, transformFunction: null }, showCharacterCount: { classPropertyName: "showCharacterCount", publicName: "showCharacterCount", isSignal: true, isRequired: false, transformFunction: null }, showWordCount: { classPropertyName: "showWordCount", publicName: "showWordCount", isSignal: true, isRequired: false, transformFunction: null }, maxCharacters: { classPropertyName: "maxCharacters", publicName: "maxCharacters", isSignal: true, isRequired: false, transformFunction: null }, enableOfficePaste: { classPropertyName: "enableOfficePaste", publicName: "enableOfficePaste", isSignal: true, isRequired: false, transformFunction: null }, enableSlashCommands: { classPropertyName: "enableSlashCommands", publicName: "enableSlashCommands", isSignal: true, isRequired: false, transformFunction: null }, slashCommands: { classPropertyName: "slashCommands", publicName: "slashCommands", isSignal: true, isRequired: false, transformFunction: null }, customSlashCommands: { classPropertyName: "customSlashCommands", publicName: "customSlashCommands", isSignal: true, isRequired: false, transformFunction: null }, blockControls: { classPropertyName: "blockControls", publicName: "blockControls", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, autofocus: { classPropertyName: "autofocus", publicName: "autofocus", isSignal: true, isRequired: false, transformFunction: null }, seamless: { classPropertyName: "seamless", publicName: "seamless", isSignal: true, isRequired: false, transformFunction: null }, floatingToolbar: { classPropertyName: "floatingToolbar", publicName: "floatingToolbar", isSignal: true, isRequired: false, transformFunction: null }, showEditToggle: { classPropertyName: "showEditToggle", publicName: "showEditToggle", isSignal: true, isRequired: false, transformFunction: null }, spellcheck: { classPropertyName: "spellcheck", publicName: "spellcheck", isSignal: true, isRequired: false, transformFunction: null }, tiptapExtensions: { classPropertyName: "tiptapExtensions", publicName: "tiptapExtensions", isSignal: true, isRequired: false, transformFunction: null }, tiptapOptions: { classPropertyName: "tiptapOptions", publicName: "tiptapOptions", isSignal: true, isRequired: false, transformFunction: null }, showBubbleMenu: { classPropertyName: "showBubbleMenu", publicName: "showBubbleMenu", isSignal: true, isRequired: false, transformFunction: null }, bubbleMenu: { classPropertyName: "bubbleMenu", publicName: "bubbleMenu", isSignal: true, isRequired: false, transformFunction: null }, showImageBubbleMenu: { classPropertyName: "showImageBubbleMenu", publicName: "showImageBubbleMenu", isSignal: true, isRequired: false, transformFunction: null }, imageBubbleMenu: { classPropertyName: "imageBubbleMenu", publicName: "imageBubbleMenu", isSignal: true, isRequired: false, transformFunction: null }, toolbar: { classPropertyName: "toolbar", publicName: "toolbar", isSignal: true, isRequired: false, transformFunction: null }, showTableBubbleMenu: { classPropertyName: "showTableBubbleMenu", publicName: "showTableBubbleMenu", isSignal: true, isRequired: false, transformFunction: null }, tableBubbleMenu: { classPropertyName: "tableBubbleMenu", publicName: "tableBubbleMenu", isSignal: true, isRequired: false, transformFunction: null }, showCellBubbleMenu: { classPropertyName: "showCellBubbleMenu", publicName: "showCellBubbleMenu", isSignal: true, isRequired: false, transformFunction: null }, cellBubbleMenu: { classPropertyName: "cellBubbleMenu", publicName: "cellBubbleMenu", isSignal: true, isRequired: false, transformFunction: null }, stateCalculators: { classPropertyName: "stateCalculators", publicName: "stateCalculators", isSignal: true, isRequired: false, transformFunction: null }, imageUpload: { classPropertyName: "imageUpload", publicName: "imageUpload", isSignal: true, isRequired: false, transformFunction: null }, imageUploadHandler: { classPropertyName: "imageUploadHandler", publicName: "imageUploadHandler", isSignal: true, isRequired: false, transformFunction: null }, editorId: { classPropertyName: "editorId", publicName: "editorId", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { contentChange: "contentChange", editorCreated: "editorCreated", editorUpdate: "editorUpdate", editorFocus: "editorFocus", editorBlur: "editorBlur", editableChange: "editableChange", imageUploaded: "imageUploaded" }, host: { properties: { "class.fill-container": "finalFillContainer()", "class.floating-toolbar": "finalFloatingToolbar()", "class.is-readonly": "!finalEditable() && !mergedDisabled()", "class.is-disabled": "mergedDisabled()", "style.--ate-border-width": "finalSeamless() || mergedDisabled() ? '0' : null", "style.--ate-background": "finalSeamless() ? 'transparent' : (mergedDisabled() ? 'var(--ate-surface-tertiary)' : null)", "style.--ate-toolbar-border-color": "finalSeamless() ? 'transparent' : null", "style.--ate-counter-background": "finalSeamless() ? 'transparent' : null", "style.--ate-counter-border-color": "finalSeamless() ? 'transparent' : null", "class.dark": "config().theme === 'dark'", "class.ate-blocks-inside": "finalBlockControls() === 'inside'", "class.ate-blocks-outside": "finalBlockControls() === 'outside'", "attr.data-theme": "config().theme" } }, providers: [
|
|
8411
|
+
AteEditorCommandsService,
|
|
8412
|
+
AteImageService,
|
|
8413
|
+
AteColorPickerService,
|
|
8414
|
+
AteLinkService,
|
|
8415
|
+
AteExportService,
|
|
8416
|
+
], viewQueries: [{ propertyName: "editorElement", first: true, predicate: ["editorElement"], descendants: true, isSignal: true }], hostDirectives: [{ directive: AteNoopValueAccessorDirective }], ngImport: i0, template: `
|
|
8397
8417
|
<div class="ate-editor">
|
|
8398
8418
|
<!-- Toolbar -->
|
|
8399
8419
|
@if (finalEditable() && !mergedDisabled() && finalShowToolbar() && editor()) {
|
|
@@ -8548,7 +8568,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
8548
8568
|
AteColorBubbleMenuComponent,
|
|
8549
8569
|
AteEditToggleComponent,
|
|
8550
8570
|
AteBlockControlsComponent,
|
|
8551
|
-
], providers: [
|
|
8571
|
+
], providers: [
|
|
8572
|
+
AteEditorCommandsService,
|
|
8573
|
+
AteImageService,
|
|
8574
|
+
AteColorPickerService,
|
|
8575
|
+
AteLinkService,
|
|
8576
|
+
AteExportService,
|
|
8577
|
+
], template: `
|
|
8552
8578
|
<div class="ate-editor">
|
|
8553
8579
|
<!-- Toolbar -->
|
|
8554
8580
|
@if (finalEditable() && !mergedDisabled() && finalShowToolbar() && editor()) {
|