@kolkov/angular-editor 3.0.4 → 3.1.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.
@@ -1,23 +1,20 @@
1
1
  import * as i0 from '@angular/core';
2
- import { DOCUMENT, Inject, Injectable, EventEmitter, forwardRef, HostListener, ViewChild, Output, HostBinding, Input, Component, SecurityContext, ContentChild, Attribute, ViewEncapsulation, NgModule } from '@angular/core';
3
- import * as i1 from '@angular/common/http';
4
- import * as i3 from '@angular/forms';
2
+ import { inject, DOCUMENT, Injectable, EventEmitter, ElementRef, Renderer2, forwardRef, HostListener, ViewChild, Output, HostBinding, Input, Component, ChangeDetectorRef, SecurityContext, ContentChild, Attribute, ViewEncapsulation, NgModule } from '@angular/core';
3
+ import { HttpClient, HttpResponse } from '@angular/common/http';
4
+ import * as i1$1 from '@angular/forms';
5
5
  import { NG_VALUE_ACCESSOR, FormsModule, ReactiveFormsModule } from '@angular/forms';
6
- import * as i2 from '@angular/platform-browser';
7
- import * as i1$1 from '@angular/common';
6
+ import { DomSanitizer } from '@angular/platform-browser';
7
+ import * as i1 from '@angular/common';
8
8
  import { CommonModule } from '@angular/common';
9
9
 
10
10
  class AngularEditorService {
11
- http;
12
- doc;
13
- savedSelection;
14
- selectedText;
15
- uploadUrl;
16
- uploadWithCredentials;
17
- constructor(http, doc) {
18
- this.http = http;
19
- this.doc = doc;
20
- }
11
+ savedSelection = null;
12
+ selectedText = '';
13
+ uploadUrl = '';
14
+ uploadWithCredentials = false;
15
+ http = inject(HttpClient);
16
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
17
+ doc = inject(DOCUMENT);
21
18
  /**
22
19
  * Executed command from editor header buttons exclude toggleEditorMode
23
20
  * @param command string from triggerCommand
@@ -96,9 +93,6 @@ class AngularEditorService {
96
93
  this.selectedText = sel.toString();
97
94
  }
98
95
  }
99
- else if (this.doc.getSelection && this.doc.createRange) {
100
- this.savedSelection = document.createRange();
101
- }
102
96
  else {
103
97
  this.savedSelection = null;
104
98
  }
@@ -116,14 +110,8 @@ class AngularEditorService {
116
110
  sel.addRange(this.savedSelection);
117
111
  return true;
118
112
  }
119
- else if (this.doc.getSelection /*&& this.savedSelection.select*/) {
120
- // this.savedSelection.select();
121
- return true;
122
- }
123
- }
124
- else {
125
- return false;
126
113
  }
114
+ return false;
127
115
  }
128
116
  /**
129
117
  * setTimeout used for execute 'saveSelection' method in next event loop iteration
@@ -132,7 +120,11 @@ class AngularEditorService {
132
120
  setTimeout(callbackFn, timeout);
133
121
  }
134
122
  /** check any selection is made or not */
123
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
135
124
  checkSelection() {
125
+ if (!this.savedSelection) {
126
+ throw new Error('No Selection Made');
127
+ }
136
128
  const selectedText = this.savedSelection.toString();
137
129
  if (selectedText.length === 0) {
138
130
  throw new Error('No Selection Made');
@@ -162,14 +154,189 @@ class AngularEditorService {
162
154
  setDefaultParagraphSeparator(separator) {
163
155
  this.doc.execCommand('defaultParagraphSeparator', false, separator);
164
156
  }
157
+ /**
158
+ * Apply custom class to selection with enterprise-level HTML structure preservation.
159
+ * Supports three modes:
160
+ * - 'inline': Wrap selection in a single element (legacy behavior)
161
+ * - 'block': Apply class to each block element in selection
162
+ * - 'auto': Smart detection based on selection span (default)
163
+ *
164
+ * @param customClass The custom class configuration
165
+ */
165
166
  createCustomClass(customClass) {
166
- let newTag = this.selectedText;
167
- if (customClass) {
168
- const tagName = customClass.tag ? customClass.tag : 'span';
169
- newTag = '<' + tagName + ' class="' + customClass.class + '">' + this.selectedText + '</' + tagName + '>';
167
+ if (!customClass || !this.savedSelection) {
168
+ return;
169
+ }
170
+ const mode = customClass.mode || 'auto';
171
+ const range = this.savedSelection;
172
+ // Restore selection before applying
173
+ this.restoreSelection();
174
+ if (mode === 'inline') {
175
+ this.applyClassInline(range, customClass);
176
+ }
177
+ else if (mode === 'block') {
178
+ this.applyClassToBlocks(range, customClass);
179
+ }
180
+ else {
181
+ // Auto mode: detect if selection spans multiple blocks
182
+ const blocks = this.getBlockElementsInRange(range);
183
+ if (blocks.length > 1) {
184
+ this.applyClassToBlocks(range, customClass);
185
+ }
186
+ else {
187
+ this.applyClassInline(range, customClass);
188
+ }
170
189
  }
190
+ }
191
+ /**
192
+ * Apply class inline by wrapping selection in a single element.
193
+ * Uses extractContents + insertNode pattern for safety.
194
+ */
195
+ applyClassInline(range, customClass) {
196
+ const tagName = customClass.tag || 'span';
197
+ try {
198
+ // Create wrapper element
199
+ const wrapper = this.doc.createElement(tagName);
200
+ wrapper.className = customClass.class;
201
+ // Extract contents and wrap (safer than surroundContents)
202
+ const contents = range.extractContents();
203
+ wrapper.appendChild(contents);
204
+ range.insertNode(wrapper);
205
+ // Normalize to merge adjacent text nodes
206
+ if (wrapper.parentNode) {
207
+ wrapper.parentNode.normalize();
208
+ }
209
+ // Update selection to the new wrapper
210
+ range.selectNodeContents(wrapper);
211
+ const sel = this.doc.getSelection();
212
+ sel.removeAllRanges();
213
+ sel.addRange(range);
214
+ }
215
+ catch (e) {
216
+ // Fallback to legacy method if DOM manipulation fails
217
+ console.warn('applyClassInline failed, using fallback:', e);
218
+ this.applyClassInlineFallback(customClass);
219
+ }
220
+ }
221
+ /**
222
+ * Fallback method for inline class application (legacy behavior).
223
+ */
224
+ applyClassInlineFallback(customClass) {
225
+ const tagName = customClass.tag || 'span';
226
+ const newTag = '<' + tagName + ' class="' + customClass.class + '">' + this.selectedText + '</' + tagName + '>';
171
227
  this.insertHtml(newTag);
172
228
  }
229
+ /**
230
+ * Apply class to each block element in selection.
231
+ * Preserves HTML structure by adding class to existing elements.
232
+ */
233
+ applyClassToBlocks(range, customClass) {
234
+ const blocks = this.getBlockElementsInRange(range);
235
+ if (blocks.length === 0) {
236
+ // No blocks found, fall back to inline
237
+ this.applyClassInline(range, customClass);
238
+ return;
239
+ }
240
+ // Apply class to each block element
241
+ blocks.forEach(block => {
242
+ // Toggle class: remove if present, add if not
243
+ if (block.classList.contains(customClass.class)) {
244
+ block.classList.remove(customClass.class);
245
+ }
246
+ else {
247
+ block.classList.add(customClass.class);
248
+ }
249
+ });
250
+ // Trigger change detection by moving cursor
251
+ const sel = this.doc.getSelection();
252
+ if (sel && blocks.length > 0) {
253
+ // Reselect the original range
254
+ sel.removeAllRanges();
255
+ sel.addRange(range);
256
+ }
257
+ }
258
+ /**
259
+ * Get all block-level elements within a range.
260
+ * Returns elements that are fully or partially selected.
261
+ */
262
+ getBlockElementsInRange(range) {
263
+ const blockTags = [
264
+ 'P', 'DIV', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6',
265
+ 'LI', 'BLOCKQUOTE', 'PRE', 'ADDRESS', 'ARTICLE',
266
+ 'ASIDE', 'FIGCAPTION', 'FIGURE', 'FOOTER', 'HEADER',
267
+ 'MAIN', 'NAV', 'SECTION'
268
+ ];
269
+ const blocks = [];
270
+ const seen = new Set();
271
+ // Get the common ancestor
272
+ const container = range.commonAncestorContainer;
273
+ const root = container.nodeType === Node.ELEMENT_NODE
274
+ ? container
275
+ : container.parentElement;
276
+ if (!root) {
277
+ return blocks;
278
+ }
279
+ // If root itself is a block element and fully contains the range
280
+ if (blockTags.includes(root.tagName) && this.isNodeFullyInRange(root, range)) {
281
+ return [root];
282
+ }
283
+ // Find all block elements within the range using TreeWalker
284
+ const walker = this.doc.createTreeWalker(root, NodeFilter.SHOW_ELEMENT, {
285
+ acceptNode: (node) => {
286
+ if (!blockTags.includes(node.tagName)) {
287
+ return NodeFilter.FILTER_SKIP;
288
+ }
289
+ // Check if node intersects with selection
290
+ if (range.intersectsNode(node)) {
291
+ return NodeFilter.FILTER_ACCEPT;
292
+ }
293
+ return NodeFilter.FILTER_SKIP;
294
+ }
295
+ });
296
+ let node;
297
+ while ((node = walker.nextNode())) {
298
+ const element = node;
299
+ // Avoid duplicates and nested blocks
300
+ if (!seen.has(element) && !this.hasAncestorInSet(element, seen)) {
301
+ seen.add(element);
302
+ blocks.push(element);
303
+ }
304
+ }
305
+ // If no blocks found, check if we're inside a block
306
+ if (blocks.length === 0) {
307
+ let parent = root;
308
+ while (parent && parent !== this.doc.body) {
309
+ if (blockTags.includes(parent.tagName)) {
310
+ blocks.push(parent);
311
+ break;
312
+ }
313
+ parent = parent.parentElement;
314
+ }
315
+ }
316
+ return blocks;
317
+ }
318
+ /**
319
+ * Check if a node is fully contained within a range.
320
+ */
321
+ isNodeFullyInRange(node, range) {
322
+ const nodeRange = this.doc.createRange();
323
+ nodeRange.selectNodeContents(node);
324
+ return range.compareBoundaryPoints(Range.START_TO_START, nodeRange) <= 0 &&
325
+ range.compareBoundaryPoints(Range.END_TO_END, nodeRange) >= 0;
326
+ }
327
+ /**
328
+ * Check if element has an ancestor in the given set.
329
+ */
330
+ hasAncestorInSet(element, set) {
331
+ let parent = element.parentElement;
332
+ while (parent) {
333
+ if (set.has(parent)) {
334
+ return true;
335
+ }
336
+ parent = parent.parentElement;
337
+ }
338
+ return false;
339
+ }
173
340
  insertVideo(videoUrl) {
174
341
  if (videoUrl.match('www.youtube.com') || videoUrl.match('youtu.be')) {
175
342
  this.insertYouTubeVideoTag(videoUrl);
@@ -199,6 +366,7 @@ class AngularEditorService {
199
366
  this.insertHtml(thumbnail);
200
367
  }
201
368
  insertVimeoVideoTag(videoUrl) {
369
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
202
370
  const sub = this.http.get(`https://vimeo.com/api/oembed.json?url=${videoUrl}`).subscribe(data => {
203
371
  const imageUrl = data.thumbnail_url_with_play_button;
204
372
  const thumbnail = `<div>
@@ -210,6 +378,7 @@ class AngularEditorService {
210
378
  sub.unsubscribe();
211
379
  });
212
380
  }
381
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
213
382
  nextNode(node) {
214
383
  if (node.hasChildNodes()) {
215
384
  return node.firstChild;
@@ -224,9 +393,11 @@ class AngularEditorService {
224
393
  return node.nextSibling;
225
394
  }
226
395
  }
396
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
227
397
  getRangeSelectedNodes(range, includePartiallySelectedContainers) {
228
398
  let node = range.startContainer;
229
399
  const endNode = range.endContainer;
400
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
230
401
  let rangeNodes = [];
231
402
  // Special case for a range that is contained within a single node
232
403
  if (node === endNode) {
@@ -254,16 +425,19 @@ class AngularEditorService {
254
425
  }
255
426
  return rangeNodes;
256
427
  }
428
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
257
429
  getSelectedNodes() {
430
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
258
431
  const nodes = [];
259
432
  if (this.doc.getSelection) {
260
433
  const sel = this.doc.getSelection();
261
434
  for (let i = 0, len = sel.rangeCount; i < len; ++i) {
262
- nodes.push.apply(nodes, this.getRangeSelectedNodes(sel.getRangeAt(i), true));
435
+ nodes.push(...this.getRangeSelectedNodes(sel.getRangeAt(i), true));
263
436
  }
264
437
  }
265
438
  return nodes;
266
439
  }
440
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
267
441
  replaceWithOwnChildren(el) {
268
442
  const parent = el.parentNode;
269
443
  while (el.hasChildNodes()) {
@@ -271,6 +445,7 @@ class AngularEditorService {
271
445
  }
272
446
  parent.removeChild(el);
273
447
  }
448
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
274
449
  removeSelectedElements(tagNames) {
275
450
  const tagNamesArray = tagNames.toLowerCase().split(',');
276
451
  this.getSelectedNodes().forEach((node) => {
@@ -281,15 +456,12 @@ class AngularEditorService {
281
456
  }
282
457
  });
283
458
  }
284
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: AngularEditorService, deps: [{ token: i1.HttpClient }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Injectable });
285
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: AngularEditorService });
459
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: AngularEditorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
460
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: AngularEditorService });
286
461
  }
287
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: AngularEditorService, decorators: [{
462
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: AngularEditorService, decorators: [{
288
463
  type: Injectable
289
- }], ctorParameters: () => [{ type: i1.HttpClient }, { type: undefined, decorators: [{
290
- type: Inject,
291
- args: [DOCUMENT]
292
- }] }] });
464
+ }] });
293
465
 
294
466
  const angularEditorConfig = {
295
467
  editable: true,
@@ -332,16 +504,14 @@ function isDefined(value) {
332
504
  }
333
505
 
334
506
  class AeSelectComponent {
335
- elRef;
336
- r;
337
507
  options = [];
338
508
  // eslint-disable-next-line @angular-eslint/no-input-rename
339
- isHidden;
509
+ isHidden = false;
340
510
  selectedOption;
341
511
  disabled = false;
342
512
  optionId = 0;
343
513
  get label() {
344
- return this.selectedOption && this.selectedOption.hasOwnProperty('label') ? this.selectedOption.label : 'Select';
514
+ return this.selectedOption && Object.prototype.hasOwnProperty.call(this.selectedOption, 'label') ? this.selectedOption.label : 'Select';
345
515
  }
346
516
  opened = false;
347
517
  get value() {
@@ -351,10 +521,8 @@ class AeSelectComponent {
351
521
  // eslint-disable-next-line @angular-eslint/no-output-native, @angular-eslint/no-output-rename
352
522
  changeEvent = new EventEmitter();
353
523
  labelButton;
354
- constructor(elRef, r) {
355
- this.elRef = elRef;
356
- this.r = r;
357
- }
524
+ elRef = inject(ElementRef);
525
+ r = inject(Renderer2);
358
526
  ngOnInit() {
359
527
  this.selectedOption = this.options[0];
360
528
  if (isDefined(this.isHidden) && this.isHidden) {
@@ -395,12 +563,14 @@ class AeSelectComponent {
395
563
  get isOpen() {
396
564
  return this.opened;
397
565
  }
566
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
398
567
  writeValue(value) {
399
568
  if (!value || typeof value !== 'string') {
400
569
  return;
401
570
  }
402
571
  this.setValue(value);
403
572
  }
573
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
404
574
  setValue(value) {
405
575
  let index = 0;
406
576
  const selectedEl = this.options.find((el, i) => {
@@ -412,13 +582,15 @@ class AeSelectComponent {
412
582
  this.optionId = index;
413
583
  }
414
584
  }
415
- onChange = () => {
416
- };
417
- onTouched = () => {
418
- };
585
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
586
+ onChange = () => { };
587
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
588
+ onTouched = () => { };
589
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
419
590
  registerOnChange(fn) {
420
591
  this.onChange = fn;
421
592
  }
593
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
422
594
  registerOnTouched(fn) {
423
595
  this.onTouched = fn;
424
596
  }
@@ -463,35 +635,40 @@ class AeSelectComponent {
463
635
  // this._keyPress$.next($event.key.toLocaleLowerCase());
464
636
  // }
465
637
  }
638
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
466
639
  _handleArrowDown($event) {
467
640
  if (this.optionId < this.options.length - 1) {
468
641
  this.optionId++;
469
642
  }
470
643
  }
644
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
471
645
  _handleArrowUp($event) {
472
646
  if (this.optionId >= 1) {
473
647
  this.optionId--;
474
648
  }
475
649
  }
650
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
476
651
  _handleSpace($event) {
477
652
  }
653
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
478
654
  _handleEnter($event) {
479
655
  this.optionSelect(this.options[this.optionId], $event);
480
656
  }
657
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
481
658
  _handleTab($event) {
482
659
  }
483
660
  _handleBackspace() {
484
661
  }
485
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: AeSelectComponent, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component });
486
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.13", type: AeSelectComponent, isStandalone: false, selector: "ae-select", inputs: { options: "options", isHidden: ["hidden", "isHidden"] }, outputs: { changeEvent: "change" }, host: { listeners: { "document:click": "onClick($event)", "keydown": "handleKeyDown($event)" }, properties: { "style.display": "this.hidden" } }, providers: [
662
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: AeSelectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
663
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: AeSelectComponent, isStandalone: false, selector: "ae-select", inputs: { options: "options", isHidden: ["hidden", "isHidden"] }, outputs: { changeEvent: "change" }, host: { listeners: { "document:click": "onClick($event)", "keydown": "handleKeyDown($event)" }, properties: { "style.display": "this.hidden" } }, providers: [
487
664
  {
488
665
  provide: NG_VALUE_ACCESSOR,
489
666
  useExisting: forwardRef(() => AeSelectComponent),
490
667
  multi: true,
491
668
  }
492
- ], viewQueries: [{ propertyName: "labelButton", first: true, predicate: ["labelButton"], descendants: true, static: true }], ngImport: i0, template: "<span class=\"ae-picker\" [ngClass]=\"{'ae-expanded':isOpen}\">\n <button [tabIndex]=\"-1\" #labelButton tabindex=\"-1\" type=\"button\" role=\"button\" class=\"ae-picker-label\" (click)=\"toggleOpen($event);\">{{label}}\n <svg>\n <use [attr.href]=\"'assets/ae-icons/icons.svg#sort'\" [attr.xlink:href]=\"'assets/ae-icons/icons.svg#sort'\"></use>\n </svg>\n </button>\n <span class=\"ae-picker-options\">\n <span tabindex=\"-1\" type=\"button\" role=\"button\" class=\"ae-picker-item\"\n *ngFor=\"let item of options; let i = index\"\n [ngClass]=\"{'selected': item.value === value, 'focused': i === optionId}\"\n (mousedown)=\"optionSelect(item, $event)\">\n {{item.label}}\n </span>\n <span class=\"dropdown-item\" *ngIf=\"!options.length\">No items for select</span>\n </span>\n</span>\n", styles: ["a{cursor:pointer}svg{width:100%;height:100%}.ae-picker{color:var(--ae-picker-color, #444);display:inline-block;float:left;width:100%;position:relative;vertical-align:middle}.ae-picker-label{cursor:pointer;display:inline-block;padding-left:8px;padding-right:10px;position:relative;width:100%;line-height:1.8rem;vertical-align:middle;font-size:85%;text-align:left;background-color:var(--ae-picker-label-color, white);min-width:2rem;float:left;border:1px solid #ddd;border-radius:var(--ae-button-radius, 4px);text-overflow:clip;overflow:hidden;white-space:nowrap;height:2rem}.ae-picker-label:before{content:\"\";position:absolute;right:0;top:0;width:20px;height:100%;background:linear-gradient(to right,var(--ae-picker-label-color, white),var(--ae-picker-label-color, white) 100%)}.ae-picker-label:focus{outline:none}.ae-picker-label:hover{cursor:pointer;background-color:#f1f1f1;transition:.2s ease}.ae-picker-label:hover:before{background:linear-gradient(to right,#f5f5f5 100%,#fff)}.ae-picker-label:disabled{background-color:#f5f5f5;pointer-events:none;cursor:not-allowed}.ae-picker-label:disabled:before{background:linear-gradient(to right,#f5f5f5 100%,#fff)}.ae-picker-label svg{position:absolute;right:0;width:1rem}.ae-picker-label svg:not(:root){overflow:hidden}.ae-picker-label svg .ae-stroke{fill:none;stroke:#444;stroke-linecap:round;stroke-linejoin:round;stroke-width:2}.ae-picker-options{background-color:var(--ae-picker-option-bg-color, #fff);display:none;min-width:100%;position:absolute;white-space:nowrap;z-index:3;border:1px solid transparent;box-shadow:#0003 0 2px 8px}.ae-picker-options .ae-picker-item{cursor:pointer;display:block;padding:5px;z-index:3;text-align:left;background-color:transparent;min-width:2rem;border:0 solid #ddd}.ae-picker-options .ae-picker-item.selected{color:#06c;background-color:var(--ae-picker-option-active-bg-color, #fff4c2)}.ae-picker-options .ae-picker-item.focused{background-color:var(--ae-picker-option-focused-bg-color, #fbf9b0)}.ae-picker-options .ae-picker-item:hover{background-color:var(--ae-picker-option-hover-bg-color, #fffa98)}.ae-expanded{display:block;margin-top:-1px;z-index:1}.ae-expanded .ae-picker-label{color:#ccc;z-index:2}.ae-expanded .ae-picker-label svg{color:#ccc;z-index:2}.ae-expanded .ae-picker-label svg .ae-stroke{stroke:#ccc}.ae-expanded .ae-picker-options{display:flex;flex-direction:column;margin-top:-1px;top:100%;z-index:3;border-color:#ccc}\n"], dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
669
+ ], viewQueries: [{ propertyName: "labelButton", first: true, predicate: ["labelButton"], descendants: true, static: true }], ngImport: i0, template: "<span class=\"ae-picker\" [ngClass]=\"{'ae-expanded':isOpen}\">\n <button [tabIndex]=\"-1\" #labelButton tabindex=\"-1\" type=\"button\" role=\"button\" class=\"ae-picker-label\" (click)=\"toggleOpen($event);\">{{label}}\n <svg>\n <use [attr.href]=\"'assets/ae-icons/icons.svg#sort'\" [attr.xlink:href]=\"'assets/ae-icons/icons.svg#sort'\"></use>\n </svg>\n </button>\n <span class=\"ae-picker-options\">\n @for (item of options; track item.value; let i = $index) {\n <span tabindex=\"-1\" type=\"button\" role=\"button\" class=\"ae-picker-item\"\n [ngClass]=\"{'selected': item.value === value, 'focused': i === optionId}\"\n (mousedown)=\"optionSelect(item, $event)\">\n {{item.label}}\n </span>\n }\n @if (!options.length) {\n <span class=\"dropdown-item\">No items for select</span>\n }\n </span>\n</span>\n", styles: ["a{cursor:pointer}svg{width:100%;height:100%}.ae-picker{color:var(--ae-picker-color, #444);display:inline-block;float:left;width:100%;position:relative;vertical-align:middle}.ae-picker-label{cursor:pointer;display:inline-block;padding-left:8px;padding-right:10px;position:relative;width:100%;line-height:1.8rem;vertical-align:middle;font-size:85%;text-align:left;background-color:var(--ae-picker-label-color, white);min-width:2rem;float:left;border:1px solid #ddd;border-radius:var(--ae-button-radius, 4px);text-overflow:clip;overflow:hidden;white-space:nowrap;height:2rem}.ae-picker-label:before{content:\"\";position:absolute;right:0;top:0;width:20px;height:100%;background:linear-gradient(to right,var(--ae-picker-label-color, white),var(--ae-picker-label-color, white) 100%)}.ae-picker-label:focus{outline:none}.ae-picker-label:hover{cursor:pointer;background-color:#f1f1f1;transition:.2s ease}.ae-picker-label:hover:before{background:linear-gradient(to right,#f5f5f5 100%,#fff)}.ae-picker-label:disabled{background-color:#f5f5f5;pointer-events:none;cursor:not-allowed}.ae-picker-label:disabled:before{background:linear-gradient(to right,#f5f5f5 100%,#fff)}.ae-picker-label svg{position:absolute;right:0;width:1rem}.ae-picker-label svg:not(:root){overflow:hidden}.ae-picker-label svg .ae-stroke{fill:none;stroke:#444;stroke-linecap:round;stroke-linejoin:round;stroke-width:2}.ae-picker-options{background-color:var(--ae-picker-option-bg-color, #fff);display:none;min-width:100%;position:absolute;white-space:nowrap;z-index:3;border:1px solid transparent;box-shadow:#0003 0 2px 8px}.ae-picker-options .ae-picker-item{cursor:pointer;display:block;padding:5px;z-index:3;text-align:left;background-color:transparent;min-width:2rem;border:0 solid #ddd}.ae-picker-options .ae-picker-item.selected{color:#06c;background-color:var(--ae-picker-option-active-bg-color, #fff4c2)}.ae-picker-options .ae-picker-item.focused{background-color:var(--ae-picker-option-focused-bg-color, #fbf9b0)}.ae-picker-options .ae-picker-item:hover{background-color:var(--ae-picker-option-hover-bg-color, #fffa98)}.ae-expanded{display:block;margin-top:-1px;z-index:1}.ae-expanded .ae-picker-label{color:#ccc;z-index:2}.ae-expanded .ae-picker-label svg{color:#ccc;z-index:2}.ae-expanded .ae-picker-label svg .ae-stroke{stroke:#ccc}.ae-expanded .ae-picker-options{display:flex;flex-direction:column;margin-top:-1px;top:100%;z-index:3;border-color:#ccc}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
493
670
  }
494
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: AeSelectComponent, decorators: [{
671
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: AeSelectComponent, decorators: [{
495
672
  type: Component,
496
673
  args: [{ selector: 'ae-select', providers: [
497
674
  {
@@ -499,8 +676,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.13", ngImpo
499
676
  useExisting: forwardRef(() => AeSelectComponent),
500
677
  multi: true,
501
678
  }
502
- ], standalone: false, template: "<span class=\"ae-picker\" [ngClass]=\"{'ae-expanded':isOpen}\">\n <button [tabIndex]=\"-1\" #labelButton tabindex=\"-1\" type=\"button\" role=\"button\" class=\"ae-picker-label\" (click)=\"toggleOpen($event);\">{{label}}\n <svg>\n <use [attr.href]=\"'assets/ae-icons/icons.svg#sort'\" [attr.xlink:href]=\"'assets/ae-icons/icons.svg#sort'\"></use>\n </svg>\n </button>\n <span class=\"ae-picker-options\">\n <span tabindex=\"-1\" type=\"button\" role=\"button\" class=\"ae-picker-item\"\n *ngFor=\"let item of options; let i = index\"\n [ngClass]=\"{'selected': item.value === value, 'focused': i === optionId}\"\n (mousedown)=\"optionSelect(item, $event)\">\n {{item.label}}\n </span>\n <span class=\"dropdown-item\" *ngIf=\"!options.length\">No items for select</span>\n </span>\n</span>\n", styles: ["a{cursor:pointer}svg{width:100%;height:100%}.ae-picker{color:var(--ae-picker-color, #444);display:inline-block;float:left;width:100%;position:relative;vertical-align:middle}.ae-picker-label{cursor:pointer;display:inline-block;padding-left:8px;padding-right:10px;position:relative;width:100%;line-height:1.8rem;vertical-align:middle;font-size:85%;text-align:left;background-color:var(--ae-picker-label-color, white);min-width:2rem;float:left;border:1px solid #ddd;border-radius:var(--ae-button-radius, 4px);text-overflow:clip;overflow:hidden;white-space:nowrap;height:2rem}.ae-picker-label:before{content:\"\";position:absolute;right:0;top:0;width:20px;height:100%;background:linear-gradient(to right,var(--ae-picker-label-color, white),var(--ae-picker-label-color, white) 100%)}.ae-picker-label:focus{outline:none}.ae-picker-label:hover{cursor:pointer;background-color:#f1f1f1;transition:.2s ease}.ae-picker-label:hover:before{background:linear-gradient(to right,#f5f5f5 100%,#fff)}.ae-picker-label:disabled{background-color:#f5f5f5;pointer-events:none;cursor:not-allowed}.ae-picker-label:disabled:before{background:linear-gradient(to right,#f5f5f5 100%,#fff)}.ae-picker-label svg{position:absolute;right:0;width:1rem}.ae-picker-label svg:not(:root){overflow:hidden}.ae-picker-label svg .ae-stroke{fill:none;stroke:#444;stroke-linecap:round;stroke-linejoin:round;stroke-width:2}.ae-picker-options{background-color:var(--ae-picker-option-bg-color, #fff);display:none;min-width:100%;position:absolute;white-space:nowrap;z-index:3;border:1px solid transparent;box-shadow:#0003 0 2px 8px}.ae-picker-options .ae-picker-item{cursor:pointer;display:block;padding:5px;z-index:3;text-align:left;background-color:transparent;min-width:2rem;border:0 solid #ddd}.ae-picker-options .ae-picker-item.selected{color:#06c;background-color:var(--ae-picker-option-active-bg-color, #fff4c2)}.ae-picker-options .ae-picker-item.focused{background-color:var(--ae-picker-option-focused-bg-color, #fbf9b0)}.ae-picker-options .ae-picker-item:hover{background-color:var(--ae-picker-option-hover-bg-color, #fffa98)}.ae-expanded{display:block;margin-top:-1px;z-index:1}.ae-expanded .ae-picker-label{color:#ccc;z-index:2}.ae-expanded .ae-picker-label svg{color:#ccc;z-index:2}.ae-expanded .ae-picker-label svg .ae-stroke{stroke:#ccc}.ae-expanded .ae-picker-options{display:flex;flex-direction:column;margin-top:-1px;top:100%;z-index:3;border-color:#ccc}\n"] }]
503
- }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }], propDecorators: { options: [{
679
+ ], standalone: false, template: "<span class=\"ae-picker\" [ngClass]=\"{'ae-expanded':isOpen}\">\n <button [tabIndex]=\"-1\" #labelButton tabindex=\"-1\" type=\"button\" role=\"button\" class=\"ae-picker-label\" (click)=\"toggleOpen($event);\">{{label}}\n <svg>\n <use [attr.href]=\"'assets/ae-icons/icons.svg#sort'\" [attr.xlink:href]=\"'assets/ae-icons/icons.svg#sort'\"></use>\n </svg>\n </button>\n <span class=\"ae-picker-options\">\n @for (item of options; track item.value; let i = $index) {\n <span tabindex=\"-1\" type=\"button\" role=\"button\" class=\"ae-picker-item\"\n [ngClass]=\"{'selected': item.value === value, 'focused': i === optionId}\"\n (mousedown)=\"optionSelect(item, $event)\">\n {{item.label}}\n </span>\n }\n @if (!options.length) {\n <span class=\"dropdown-item\">No items for select</span>\n }\n </span>\n</span>\n", styles: ["a{cursor:pointer}svg{width:100%;height:100%}.ae-picker{color:var(--ae-picker-color, #444);display:inline-block;float:left;width:100%;position:relative;vertical-align:middle}.ae-picker-label{cursor:pointer;display:inline-block;padding-left:8px;padding-right:10px;position:relative;width:100%;line-height:1.8rem;vertical-align:middle;font-size:85%;text-align:left;background-color:var(--ae-picker-label-color, white);min-width:2rem;float:left;border:1px solid #ddd;border-radius:var(--ae-button-radius, 4px);text-overflow:clip;overflow:hidden;white-space:nowrap;height:2rem}.ae-picker-label:before{content:\"\";position:absolute;right:0;top:0;width:20px;height:100%;background:linear-gradient(to right,var(--ae-picker-label-color, white),var(--ae-picker-label-color, white) 100%)}.ae-picker-label:focus{outline:none}.ae-picker-label:hover{cursor:pointer;background-color:#f1f1f1;transition:.2s ease}.ae-picker-label:hover:before{background:linear-gradient(to right,#f5f5f5 100%,#fff)}.ae-picker-label:disabled{background-color:#f5f5f5;pointer-events:none;cursor:not-allowed}.ae-picker-label:disabled:before{background:linear-gradient(to right,#f5f5f5 100%,#fff)}.ae-picker-label svg{position:absolute;right:0;width:1rem}.ae-picker-label svg:not(:root){overflow:hidden}.ae-picker-label svg .ae-stroke{fill:none;stroke:#444;stroke-linecap:round;stroke-linejoin:round;stroke-width:2}.ae-picker-options{background-color:var(--ae-picker-option-bg-color, #fff);display:none;min-width:100%;position:absolute;white-space:nowrap;z-index:3;border:1px solid transparent;box-shadow:#0003 0 2px 8px}.ae-picker-options .ae-picker-item{cursor:pointer;display:block;padding:5px;z-index:3;text-align:left;background-color:transparent;min-width:2rem;border:0 solid #ddd}.ae-picker-options .ae-picker-item.selected{color:#06c;background-color:var(--ae-picker-option-active-bg-color, #fff4c2)}.ae-picker-options .ae-picker-item.focused{background-color:var(--ae-picker-option-focused-bg-color, #fbf9b0)}.ae-picker-options .ae-picker-item:hover{background-color:var(--ae-picker-option-hover-bg-color, #fffa98)}.ae-expanded{display:block;margin-top:-1px;z-index:1}.ae-expanded .ae-picker-label{color:#ccc;z-index:2}.ae-expanded .ae-picker-label svg{color:#ccc;z-index:2}.ae-expanded .ae-picker-label svg .ae-stroke{stroke:#ccc}.ae-expanded .ae-picker-options{display:flex;flex-direction:column;margin-top:-1px;top:100%;z-index:3;border-color:#ccc}\n"] }]
680
+ }], propDecorators: { options: [{
504
681
  type: Input
505
682
  }], isHidden: [{
506
683
  type: Input,
@@ -524,29 +701,27 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.13", ngImpo
524
701
 
525
702
  class AeButtonComponent {
526
703
  iconName = '';
527
- constructor() {
528
- }
529
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: AeButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
530
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.13", type: AeButtonComponent, isStandalone: false, selector: "ae-button, button[aeButton]", inputs: { iconName: "iconName" }, host: { properties: { "tabIndex": "-1", "type": "\"button\"" }, classAttribute: "angular-editor-button" }, ngImport: i0, template: "<ng-container *ngIf=\"iconName; else contentTemplate\">\n <svg>\n <use [attr.href]=\"'assets/ae-icons/icons.svg#' + iconName\" [attr.xlink:href]=\"'assets/ae-icons/icons.svg#' + iconName\"></use>\n </svg>\n</ng-container>\n<ng-template #contentTemplate>\n <ng-content></ng-content>\n</ng-template>\n", styles: ["a{cursor:pointer}:host.angular-editor-button{background-color:var(--ae-button-bg-color, white);vertical-align:middle;border:var(--ae-button-border, 1px solid #ddd);border-radius:var(--ae-button-radius, 4px);padding:.4rem;float:left;width:2rem;height:2rem}:host.angular-editor-button svg{width:100%;height:100%}:host.angular-editor-button:hover{cursor:pointer;background-color:var(--ae-button-hover-bg-color, #f1f1f1);transition:.2s ease}:host.angular-editor-button:focus,:host.angular-editor-button.focus{outline:0}:host.angular-editor-button:disabled{background-color:var(--ae-button-disabled-bg-color, #f5f5f5);pointer-events:none;cursor:not-allowed}:host.angular-editor-button:disabled>.color-label{pointer-events:none;cursor:not-allowed}:host.angular-editor-button:disabled>.color-label.foreground :after{background:#555}:host.angular-editor-button:disabled>.color-label.background{background:#555}:host.angular-editor-button.active{background:var(--ae-button-active-bg-color, #fffbd3)}:host.angular-editor-button.active:hover{background-color:var(--ae-button-active-hover-bg-color, #fffaad)}\n"], dependencies: [{ kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
704
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: AeButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
705
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: AeButtonComponent, isStandalone: false, selector: "ae-button, button[aeButton]", inputs: { iconName: "iconName" }, host: { properties: { "attr.tabIndex": "-1", "attr.type": "\"button\"" }, classAttribute: "angular-editor-button" }, ngImport: i0, template: "@if (iconName) {\n <svg>\n <use [attr.href]=\"'assets/ae-icons/icons.svg#' + iconName\" [attr.xlink:href]=\"'assets/ae-icons/icons.svg#' + iconName\"></use>\n </svg>\n} @else {\n <ng-content></ng-content>\n}\n", styles: ["a{cursor:pointer}:host.angular-editor-button{background-color:var(--ae-button-bg-color, white);vertical-align:middle;border:var(--ae-button-border, 1px solid #ddd);border-radius:var(--ae-button-radius, 4px);padding:.4rem;float:left;width:2rem;height:2rem}:host.angular-editor-button svg{width:100%;height:100%}:host.angular-editor-button:hover{cursor:pointer;background-color:var(--ae-button-hover-bg-color, #f1f1f1);transition:.2s ease}:host.angular-editor-button:focus,:host.angular-editor-button.focus{outline:0}:host.angular-editor-button:disabled{background-color:var(--ae-button-disabled-bg-color, #f5f5f5);pointer-events:none;cursor:not-allowed}:host.angular-editor-button:disabled>.color-label{pointer-events:none;cursor:not-allowed}:host.angular-editor-button:disabled>.color-label.foreground :after{background:#555}:host.angular-editor-button:disabled>.color-label.background{background:#555}:host.angular-editor-button.active{background:var(--ae-button-active-bg-color, #fffbd3)}:host.angular-editor-button.active:hover{background-color:var(--ae-button-active-hover-bg-color, #fffaad)}\n"] });
531
706
  }
532
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: AeButtonComponent, decorators: [{
707
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: AeButtonComponent, decorators: [{
533
708
  type: Component,
534
709
  args: [{ selector: 'ae-button, button[aeButton]', host: {
535
710
  'class': 'angular-editor-button',
536
- '[tabIndex]': '-1',
537
- '[type]': '"button"',
538
- }, standalone: false, template: "<ng-container *ngIf=\"iconName; else contentTemplate\">\n <svg>\n <use [attr.href]=\"'assets/ae-icons/icons.svg#' + iconName\" [attr.xlink:href]=\"'assets/ae-icons/icons.svg#' + iconName\"></use>\n </svg>\n</ng-container>\n<ng-template #contentTemplate>\n <ng-content></ng-content>\n</ng-template>\n", styles: ["a{cursor:pointer}:host.angular-editor-button{background-color:var(--ae-button-bg-color, white);vertical-align:middle;border:var(--ae-button-border, 1px solid #ddd);border-radius:var(--ae-button-radius, 4px);padding:.4rem;float:left;width:2rem;height:2rem}:host.angular-editor-button svg{width:100%;height:100%}:host.angular-editor-button:hover{cursor:pointer;background-color:var(--ae-button-hover-bg-color, #f1f1f1);transition:.2s ease}:host.angular-editor-button:focus,:host.angular-editor-button.focus{outline:0}:host.angular-editor-button:disabled{background-color:var(--ae-button-disabled-bg-color, #f5f5f5);pointer-events:none;cursor:not-allowed}:host.angular-editor-button:disabled>.color-label{pointer-events:none;cursor:not-allowed}:host.angular-editor-button:disabled>.color-label.foreground :after{background:#555}:host.angular-editor-button:disabled>.color-label.background{background:#555}:host.angular-editor-button.active{background:var(--ae-button-active-bg-color, #fffbd3)}:host.angular-editor-button.active:hover{background-color:var(--ae-button-active-hover-bg-color, #fffaad)}\n"] }]
539
- }], ctorParameters: () => [], propDecorators: { iconName: [{
711
+ '[attr.tabIndex]': '-1',
712
+ '[attr.type]': '"button"',
713
+ }, standalone: false, template: "@if (iconName) {\n <svg>\n <use [attr.href]=\"'assets/ae-icons/icons.svg#' + iconName\" [attr.xlink:href]=\"'assets/ae-icons/icons.svg#' + iconName\"></use>\n </svg>\n} @else {\n <ng-content></ng-content>\n}\n", styles: ["a{cursor:pointer}:host.angular-editor-button{background-color:var(--ae-button-bg-color, white);vertical-align:middle;border:var(--ae-button-border, 1px solid #ddd);border-radius:var(--ae-button-radius, 4px);padding:.4rem;float:left;width:2rem;height:2rem}:host.angular-editor-button svg{width:100%;height:100%}:host.angular-editor-button:hover{cursor:pointer;background-color:var(--ae-button-hover-bg-color, #f1f1f1);transition:.2s ease}:host.angular-editor-button:focus,:host.angular-editor-button.focus{outline:0}:host.angular-editor-button:disabled{background-color:var(--ae-button-disabled-bg-color, #f5f5f5);pointer-events:none;cursor:not-allowed}:host.angular-editor-button:disabled>.color-label{pointer-events:none;cursor:not-allowed}:host.angular-editor-button:disabled>.color-label.foreground :after{background:#555}:host.angular-editor-button:disabled>.color-label.background{background:#555}:host.angular-editor-button.active{background:var(--ae-button-active-bg-color, #fffbd3)}:host.angular-editor-button.active:hover{background-color:var(--ae-button-active-hover-bg-color, #fffaad)}\n"] }]
714
+ }], propDecorators: { iconName: [{
540
715
  type: Input
541
716
  }] } });
542
717
 
543
718
  class AeToolbarSetComponent {
544
719
  constructor() {
545
720
  }
546
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: AeToolbarSetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
547
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.13", type: AeToolbarSetComponent, isStandalone: false, selector: "ae-toolbar-set, [aeToolbarSet]", host: { classAttribute: "angular-editor-toolbar-set" }, ngImport: i0, template: "<ng-content></ng-content>\n", styles: ["a{cursor:pointer}:host.angular-editor-toolbar-set{display:flex;gap:1px;width:fit-content;vertical-align:baseline}\n"] });
721
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: AeToolbarSetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
722
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.7", type: AeToolbarSetComponent, isStandalone: false, selector: "ae-toolbar-set, [aeToolbarSet]", host: { classAttribute: "angular-editor-toolbar-set" }, ngImport: i0, template: "<ng-content></ng-content>\n", styles: ["a{cursor:pointer}:host.angular-editor-toolbar-set{display:flex;gap:1px;width:fit-content;vertical-align:baseline}\n"] });
548
723
  }
549
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: AeToolbarSetComponent, decorators: [{
724
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: AeToolbarSetComponent, decorators: [{
550
725
  type: Component,
551
726
  args: [{ selector: 'ae-toolbar-set, [aeToolbarSet]', host: {
552
727
  'class': 'angular-editor-toolbar-set'
@@ -554,17 +729,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.13", ngImpo
554
729
  }], ctorParameters: () => [] });
555
730
 
556
731
  class AeToolbarComponent {
557
- r;
558
- editorService;
559
- er;
560
- doc;
561
732
  htmlMode = false;
562
733
  linkSelected = false;
563
734
  block = 'default';
564
735
  fontName = 'Times New Roman';
565
736
  fontSize = '3';
566
- foreColour;
567
- backColor;
737
+ foreColour = '';
738
+ backColor = '';
568
739
  headings = [
569
740
  {
570
741
  label: 'Heading 1',
@@ -638,10 +809,8 @@ class AeToolbarComponent {
638
809
  }
639
810
  ];
640
811
  customClassId = '-1';
641
- // eslint-disable-next-line no-underscore-dangle, id-blacklist, id-match
642
- _customClasses;
812
+ _customClasses = [];
643
813
  customClassList = [{ label: '', value: '' }];
644
- // uploadUrl: string;
645
814
  tagMap = {
646
815
  BLOCKQUOTE: 'indent',
647
816
  A: 'link'
@@ -649,10 +818,10 @@ class AeToolbarComponent {
649
818
  select = ['H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'P', 'PRE', 'DIV'];
650
819
  buttons = ['bold', 'italic', 'underline', 'strikeThrough', 'subscript', 'superscript', 'justifyLeft', 'justifyCenter',
651
820
  'justifyRight', 'justifyFull', 'indent', 'outdent', 'insertUnorderedList', 'insertOrderedList', 'link'];
652
- id;
653
- uploadUrl;
821
+ id = '';
822
+ uploadUrl = '';
654
823
  upload;
655
- showToolbar;
824
+ showToolbar = false;
656
825
  fonts = [{ label: '', value: '' }];
657
826
  set customClasses(classes) {
658
827
  if (classes) {
@@ -671,18 +840,17 @@ class AeToolbarComponent {
671
840
  this.fontSize = value;
672
841
  }
673
842
  }
674
- hiddenButtons;
843
+ hiddenButtons = [];
675
844
  execute = new EventEmitter();
676
845
  myInputFile;
677
846
  get isLinkButtonDisabled() {
678
- return this.htmlMode || !Boolean(this.editorService.selectedText);
679
- }
680
- constructor(r, editorService, er, doc) {
681
- this.r = r;
682
- this.editorService = editorService;
683
- this.er = er;
684
- this.doc = doc;
847
+ return this.htmlMode || !this.editorService.selectedText;
685
848
  }
849
+ r = inject(Renderer2);
850
+ editorService = inject(AngularEditorService);
851
+ er = inject(ElementRef);
852
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
853
+ doc = inject(DOCUMENT);
686
854
  /**
687
855
  * Trigger command from editor header buttons
688
856
  * @param command string from toolbar buttons
@@ -736,6 +904,7 @@ class AeToolbarComponent {
736
904
  if (x instanceof Element) {
737
905
  return x.className === y.class;
738
906
  }
907
+ return false;
739
908
  });
740
909
  if (node !== undefined) {
741
910
  if (found === false) {
@@ -767,9 +936,9 @@ class AeToolbarComponent {
767
936
  * insert URL link
768
937
  */
769
938
  insertUrl() {
770
- let url = 'https:\/\/';
939
+ let url = 'https://';
771
940
  const selection = this.editorService.savedSelection;
772
- if (selection && selection.commonAncestorContainer.parentElement.nodeName === 'A') {
941
+ if (selection && selection.commonAncestorContainer.parentElement?.nodeName === 'A') {
773
942
  const parent = selection.commonAncestorContainer.parentElement;
774
943
  // Use getAttribute to preserve relative URLs instead of href which returns absolute URL
775
944
  const href = parent.getAttribute('href');
@@ -777,9 +946,9 @@ class AeToolbarComponent {
777
946
  url = href;
778
947
  }
779
948
  }
780
- url = prompt('Insert URL link', url);
781
- if (url && url !== '' && url !== 'https://') {
782
- this.editorService.createLink(url);
949
+ const promptUrl = prompt('Insert URL link', url);
950
+ if (promptUrl && promptUrl !== '' && promptUrl !== 'https://') {
951
+ this.editorService.createLink(promptUrl);
783
952
  }
784
953
  }
785
954
  /**
@@ -830,20 +999,31 @@ class AeToolbarComponent {
830
999
  /**
831
1000
  * Upload image when file is selected.
832
1001
  */
1002
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
833
1003
  onFileChanged(event) {
834
1004
  const file = event.target.files[0];
835
1005
  if (file.type.includes('image/')) {
836
1006
  if (this.upload) {
837
- this.upload(file).subscribe((response) => this.watchUploadImage(response, event));
1007
+ this.upload(file).subscribe((response) => {
1008
+ if (response instanceof HttpResponse) {
1009
+ this.watchUploadImage(response, event);
1010
+ }
1011
+ });
838
1012
  }
839
1013
  else if (this.uploadUrl) {
840
- this.editorService.uploadImage(file).subscribe((response) => this.watchUploadImage(response, event));
1014
+ this.editorService.uploadImage(file).subscribe((response) => {
1015
+ if (response instanceof HttpResponse) {
1016
+ this.watchUploadImage(response, event);
1017
+ }
1018
+ });
841
1019
  }
842
1020
  else {
843
1021
  const reader = new FileReader();
844
1022
  reader.onload = (e) => {
845
1023
  const fr = e.currentTarget;
846
- this.editorService.insertImage(fr.result.toString());
1024
+ if (fr.result !== null) {
1025
+ this.editorService.insertImage(fr.result.toString());
1026
+ }
847
1027
  // Reset input value to allow re-uploading the same file
848
1028
  event.target.value = null;
849
1029
  };
@@ -851,9 +1031,13 @@ class AeToolbarComponent {
851
1031
  }
852
1032
  }
853
1033
  }
1034
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
854
1035
  watchUploadImage(response, event) {
855
- const { imageUrl } = response.body;
856
- this.editorService.insertImage(imageUrl);
1036
+ const body = response.body;
1037
+ if (body) {
1038
+ const { imageUrl } = body;
1039
+ this.editorService.insertImage(imageUrl);
1040
+ }
857
1041
  event.srcElement.value = null;
858
1042
  }
859
1043
  /**
@@ -874,6 +1058,7 @@ class AeToolbarComponent {
874
1058
  if (!(this.hiddenButtons instanceof Array)) {
875
1059
  return false;
876
1060
  }
1061
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
877
1062
  let result;
878
1063
  for (const arr of this.hiddenButtons) {
879
1064
  if (arr instanceof Array) {
@@ -888,16 +1073,13 @@ class AeToolbarComponent {
888
1073
  focus() {
889
1074
  this.execute.emit('focus');
890
1075
  }
891
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: AeToolbarComponent, deps: [{ token: i0.Renderer2 }, { token: AngularEditorService }, { token: i0.ElementRef }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Component });
892
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.13", type: AeToolbarComponent, isStandalone: false, selector: "angular-editor-toolbar, ae-toolbar, div[aeToolbar]", inputs: { id: "id", uploadUrl: "uploadUrl", upload: "upload", showToolbar: "showToolbar", fonts: "fonts", customClasses: "customClasses", defaultFontName: "defaultFontName", defaultFontSize: "defaultFontSize", hiddenButtons: "hiddenButtons" }, outputs: { execute: "execute" }, viewQueries: [{ propertyName: "myInputFile", first: true, predicate: ["fileInput"], descendants: true, static: true }], ngImport: i0, template: "<div class=\"angular-editor-toolbar\" *ngIf=\"showToolbar\">\n <div aeToolbarSet>\n <button aeButton title=\"Undo\" iconName=\"undo\" (click)=\"triggerCommand('undo')\" [hidden]=\"isButtonHidden('undo')\">\n </button>\n <button aeButton title=\"Redo\" iconName=\"redo\" (click)=\"triggerCommand('redo')\"\n [hidden]=\"isButtonHidden('redo')\">\n </button>\n </div>\n <div aeToolbarSet>\n <button [id]=\"'bold-'+id\" aeButton title=\"Bold\" iconName=\"bold\" (click)=\"triggerCommand('bold')\"\n [disabled]=\"htmlMode\" [hidden]=\"isButtonHidden('bold')\">\n </button>\n <button [id]=\"'italic-'+id\" aeButton iconName=\"italic\" title=\"Italic\" (click)=\"triggerCommand('italic')\"\n [disabled]=\"htmlMode\" [hidden]=\"isButtonHidden('italic')\">\n </button>\n <button [id]=\"'underline-'+id\" aeButton title=\"Underline\" iconName=\"underline\"\n (click)=\"triggerCommand('underline')\" [disabled]=\"htmlMode\" [hidden]=\"isButtonHidden('underline')\">\n </button>\n <button [id]=\"'strikeThrough-'+id\" aeButton iconName=\"strikeThrough\" title=\"Strikethrough\"\n (click)=\"triggerCommand('strikeThrough')\" [disabled]=\"htmlMode\"\n [hidden]=\"isButtonHidden('strikeThrough')\">\n </button>\n <button [id]=\"'subscript-'+id\" aeButton title=\"Subscript\" iconName=\"subscript\"\n (click)=\"triggerCommand('subscript')\" [disabled]=\"htmlMode\" [hidden]=\"isButtonHidden('subscript')\">\n </button>\n <button [id]=\"'superscript-'+id\" aeButton iconName=\"superscript\" title=\"Superscript\"\n (click)=\"triggerCommand('superscript')\" [disabled]=\"htmlMode\"\n [hidden]=\"isButtonHidden('superscript')\">\n </button>\n </div>\n <div aeToolbarSet>\n <button [id]=\"'justifyLeft-'+id\" aeButton iconName=\"justifyLeft\" title=\"Justify Left\"\n (click)=\"triggerCommand('justifyLeft')\" [disabled]=\"htmlMode\"\n [hidden]=\"isButtonHidden('justifyLeft')\">\n </button>\n <button [id]=\"'justifyCenter-'+id\" aeButton iconName=\"justifyCenter\" title=\"Justify Center\"\n (click)=\"triggerCommand('justifyCenter')\" [disabled]=\"htmlMode\"\n [hidden]=\"isButtonHidden('justifyCenter')\">\n </button>\n <button [id]=\"'justifyRight-'+id\" aeButton iconName=\"justifyRight\" title=\"Justify Right\"\n (click)=\"triggerCommand('justifyRight')\" [disabled]=\"htmlMode\"\n [hidden]=\"isButtonHidden('justifyRight')\">\n </button>\n <button [id]=\"'justifyFull-'+id\" aeButton iconName=\"justifyFull\" title=\"Justify Full\"\n (click)=\"triggerCommand('justifyFull')\" [disabled]=\"htmlMode\"\n [hidden]=\"isButtonHidden('justifyFull')\">\n </button>\n </div>\n <div aeToolbarSet>\n <button [id]=\"'indent-'+id\" aeButton iconName=\"indent\" title=\"Indent\"\n (click)=\"triggerCommand('indent')\"\n [disabled]=\"htmlMode\" [hidden]=\"isButtonHidden('indent')\">\n </button>\n <button [id]=\"'outdent-'+id\" aeButton iconName=\"outdent\" title=\"Outdent\"\n (click)=\"triggerCommand('outdent')\"\n [disabled]=\"htmlMode\" [hidden]=\"isButtonHidden('outdent')\">\n </button>\n </div>\n <div aeToolbarSet>\n <button [id]=\"'insertUnorderedList-'+id\" aeButton iconName=\"unorderedList\" title=\"Unordered List\"\n (click)=\"triggerCommand('insertUnorderedList')\" [disabled]=\"htmlMode\"\n [hidden]=\"isButtonHidden('insertUnorderedList')\">\n </button>\n <button [id]=\"'insertOrderedList-'+id\" aeButton iconName=\"orderedList\" title=\"Ordered List\"\n (click)=\"triggerCommand('insertOrderedList')\" [disabled]=\"htmlMode\"\n [hidden]=\"isButtonHidden('insertOrderedList')\">\n </button>\n </div>\n <div aeToolbarSet>\n <ae-select class=\"select-heading\" [options]=\"headings\"\n [(ngModel)]=\"block\"\n (change)=\"triggerCommand(block)\"\n [disabled]=\"htmlMode\"\n [hidden]=\"isButtonHidden('heading')\"\n tabindex=\"-1\"></ae-select>\n </div>\n <div aeToolbarSet>\n <ae-select class=\"select-font\" [options]=\"fonts\"\n [(ngModel)]=\"fontName\"\n (change)=\"setFontName(fontName)\"\n [disabled]=\"htmlMode\"\n [hidden]=\"isButtonHidden('fontName')\"\n tabindex=\"-1\"></ae-select>\n </div>\n <div aeToolbarSet>\n <ae-select class=\"select-font-size\" [options]=\"fontSizes\"\n [(ngModel)]=\"fontSize\"\n (change)=\"setFontSize(fontSize)\"\n [disabled]=\"htmlMode\"\n [hidden]=\"isButtonHidden('fontSize')\"\n tabindex=\"-1\">\n </ae-select>\n </div>\n <div aeToolbarSet>\n <input\n style=\"display: none\"\n type=\"color\" (change)=\"insertColor(fgInput.value, 'textColor')\"\n #fgInput>\n <button [id]=\"'foregroundColorPicker-'+id\" aeButton iconName=\"textColor\"\n (click)=\"focus(); ; fgInput.click()\"\n title=\"Text Color\"\n [disabled]=\"htmlMode\" [hidden]=\"isButtonHidden('textColor')\">\n </button>\n <input\n style=\"display: none\"\n type=\"color\" (change)=\"insertColor(bgInput.value, 'backgroundColor')\"\n #bgInput>\n <button [id]=\"'backgroundColorPicker-'+id\" aeButton iconName=\"backgroundColor\"\n (click)=\"focus(); ; bgInput.click()\"\n title=\"Background Color\"\n [disabled]=\"htmlMode\" [hidden]=\"isButtonHidden('backgroundColor')\">\n </button>\n </div>\n <div *ngIf=\"_customClasses\" aeToolbarSet>\n <ae-select class=\"select-custom-style\" [options]=\"customClassList\"\n [(ngModel)]=\"customClassId\"\n (change)=\"setCustomClass(customClassId)\"\n [disabled]=\"htmlMode\"\n [hidden]=\"isButtonHidden('customClasses')\"\n tabindex=\"-1\"></ae-select>\n </div>\n <div aeToolbarSet>\n <button [id]=\"'link-'+id\" aeButton iconName=\"link\" (click)=\"insertUrl()\"\n title=\"Insert Link\" [disabled]=\"isLinkButtonDisabled\" [hidden]=\"isButtonHidden('link')\">\n </button>\n <button [id]=\"'unlink-'+id\" aeButton iconName=\"unlink\" (click)=\"triggerCommand('unlink')\"\n title=\"Unlink\" [disabled]=\"htmlMode || !linkSelected\" [hidden]=\"isButtonHidden('unlink')\">\n </button>\n <input\n style=\"display: none\"\n accept=\"image/*\"\n type=\"file\" (change)=\"onFileChanged($event)\"\n #fileInput>\n <button [id]=\"'insertImage-'+id\" aeButton iconName=\"image\" (click)=\"focus(); fileInput.click()\"\n title=\"Insert Image\"\n [disabled]=\"htmlMode\" [hidden]=\"isButtonHidden('insertImage')\">\n </button>\n <button [id]=\"'insertVideo-'+id\" aeButton iconName=\"video\"\n (click)=\"insertVideo()\" title=\"Insert Video\" [disabled]=\"htmlMode\"\n [hidden]=\"isButtonHidden('insertVideo')\">\n </button>\n <button [id]=\"'insertHorizontalRule-'+id\" aeButton iconName=\"horizontalLine\" title=\"Horizontal Line\"\n (click)=\"triggerCommand('insertHorizontalRule')\" [disabled]=\"htmlMode\"\n [hidden]=\"isButtonHidden('insertHorizontalRule')\">\n </button>\n </div>\n <div aeToolbarSet>\n <button [id]=\"'clearFormatting-'+id\" aeButton iconName=\"removeFormat\" title=\"Clear Formatting\"\n class=\"angular-editor-button\"\n (click)=\"triggerCommand('removeFormat')\" [disabled]=\"htmlMode\" [hidden]=\"isButtonHidden('removeFormat')\">\n </button>\n </div>\n <div aeToolbarSet>\n <button [id]=\"'toggleEditorMode-'+id\" aeButton iconName=\"htmlCode\" title=\"HTML Code\"\n (click)=\"triggerCommand('toggleEditorMode')\" [hidden]=\"isButtonHidden('toggleEditorMode')\">\n </button>\n </div>\n <ng-content></ng-content>\n</div>\n", styles: ["a{cursor:pointer}.angular-editor-toolbar{font:100 14px/15px Roboto,Arial,sans-serif;background-color:var(--ae-toolbar-bg-color, #f5f5f5);font-size:.8rem;padding:var(--ae-toolbar-padding, .2rem);border:var(--ae-toolbar-border-radius, 1px solid #ddd);display:flex;flex-wrap:wrap;gap:4px}.select-heading{display:inline-block;width:90px}@supports not (-moz-appearance: none){.select-heading optgroup{font-size:12px;background-color:#f4f4f4;padding:5px}.select-heading option{border:1px solid;background-color:#fff}}.select-heading:disabled{background-color:#f5f5f5;pointer-events:none;cursor:not-allowed}.select-heading:hover{cursor:pointer;background-color:#f1f1f1;transition:.2s ease}.select-font{display:inline-block;width:90px}@supports not (-moz-appearance: none){.select-font optgroup{font-size:12px;background-color:#f4f4f4;padding:5px}.select-font option{border:1px solid;background-color:#fff}}.select-font:disabled{background-color:#f5f5f5;pointer-events:none;cursor:not-allowed}.select-font:hover{cursor:pointer;background-color:#f1f1f1;transition:.2s ease}.select-font-size{display:inline-block;width:50px}@supports not (-moz-appearance: none){.select-font-size optgroup{font-size:12px;background-color:#f4f4f4;padding:5px}.select-font-size option{border:1px solid;background-color:#fff}.select-font-size .size1{font-size:10px}.select-font-size .size2{font-size:12px}.select-font-size .size3{font-size:14px}.select-font-size .size4{font-size:16px}.select-font-size .size5{font-size:18px}.select-font-size .size6{font-size:20px}.select-font-size .size7{font-size:22px}}.select-font-size:disabled{background-color:#f5f5f5;pointer-events:none;cursor:not-allowed}.select-font-size:hover{cursor:pointer;background-color:#f1f1f1;transition:.2s ease}.select-custom-style{display:inline-block;width:90px}@supports not (-moz-appearance: none){.select-custom-style optgroup{font-size:12px;background-color:#f4f4f4;padding:5px}.select-custom-style option{border:1px solid;background-color:#fff}}.select-custom-style:disabled{background-color:#f5f5f5;pointer-events:none;cursor:not-allowed}.select-custom-style:hover{cursor:pointer;background-color:#f1f1f1;transition:.2s ease}.color-label{position:relative;cursor:pointer}.background{font-size:smaller;background:#1b1b1b;color:#fff;padding:3px}.foreground :after{position:absolute;content:\"\";inset:auto auto -3px -1px;width:15px;height:2px;z-index:0;background:#1b1b1b}.default{font-size:16px}h1{font-size:24px}h2{font-size:20px}h3{font-size:16px}h4{font-size:15px}h5{font-size:14px}h6{font-size:13px}div,pre{font-size:12px}\n"], dependencies: [{ kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: AeSelectComponent, selector: "ae-select", inputs: ["options", "hidden"], outputs: ["change"] }, { kind: "component", type: AeButtonComponent, selector: "ae-button, button[aeButton]", inputs: ["iconName"] }, { kind: "component", type: AeToolbarSetComponent, selector: "ae-toolbar-set, [aeToolbarSet]" }] });
1076
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: AeToolbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1077
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: AeToolbarComponent, isStandalone: false, selector: "angular-editor-toolbar, ae-toolbar, div[aeToolbar]", inputs: { id: "id", uploadUrl: "uploadUrl", upload: "upload", showToolbar: "showToolbar", fonts: "fonts", customClasses: "customClasses", defaultFontName: "defaultFontName", defaultFontSize: "defaultFontSize", hiddenButtons: "hiddenButtons" }, outputs: { execute: "execute" }, viewQueries: [{ propertyName: "myInputFile", first: true, predicate: ["fileInput"], descendants: true, static: true }], ngImport: i0, template: "@if (showToolbar) {\n <div class=\"angular-editor-toolbar\">\n <div aeToolbarSet>\n <button aeButton title=\"Undo\" iconName=\"undo\" (click)=\"triggerCommand('undo')\" [hidden]=\"isButtonHidden('undo')\">\n </button>\n <button aeButton title=\"Redo\" iconName=\"redo\" (click)=\"triggerCommand('redo')\"\n [hidden]=\"isButtonHidden('redo')\">\n </button>\n </div>\n <div aeToolbarSet>\n <button [id]=\"'bold-'+id\" aeButton title=\"Bold\" iconName=\"bold\" (click)=\"triggerCommand('bold')\"\n [disabled]=\"htmlMode\" [hidden]=\"isButtonHidden('bold')\">\n </button>\n <button [id]=\"'italic-'+id\" aeButton iconName=\"italic\" title=\"Italic\" (click)=\"triggerCommand('italic')\"\n [disabled]=\"htmlMode\" [hidden]=\"isButtonHidden('italic')\">\n </button>\n <button [id]=\"'underline-'+id\" aeButton title=\"Underline\" iconName=\"underline\"\n (click)=\"triggerCommand('underline')\" [disabled]=\"htmlMode\" [hidden]=\"isButtonHidden('underline')\">\n </button>\n <button [id]=\"'strikeThrough-'+id\" aeButton iconName=\"strikeThrough\" title=\"Strikethrough\"\n (click)=\"triggerCommand('strikeThrough')\" [disabled]=\"htmlMode\"\n [hidden]=\"isButtonHidden('strikeThrough')\">\n </button>\n <button [id]=\"'subscript-'+id\" aeButton title=\"Subscript\" iconName=\"subscript\"\n (click)=\"triggerCommand('subscript')\" [disabled]=\"htmlMode\" [hidden]=\"isButtonHidden('subscript')\">\n </button>\n <button [id]=\"'superscript-'+id\" aeButton iconName=\"superscript\" title=\"Superscript\"\n (click)=\"triggerCommand('superscript')\" [disabled]=\"htmlMode\"\n [hidden]=\"isButtonHidden('superscript')\">\n </button>\n </div>\n <div aeToolbarSet>\n <button [id]=\"'justifyLeft-'+id\" aeButton iconName=\"justifyLeft\" title=\"Justify Left\"\n (click)=\"triggerCommand('justifyLeft')\" [disabled]=\"htmlMode\"\n [hidden]=\"isButtonHidden('justifyLeft')\">\n </button>\n <button [id]=\"'justifyCenter-'+id\" aeButton iconName=\"justifyCenter\" title=\"Justify Center\"\n (click)=\"triggerCommand('justifyCenter')\" [disabled]=\"htmlMode\"\n [hidden]=\"isButtonHidden('justifyCenter')\">\n </button>\n <button [id]=\"'justifyRight-'+id\" aeButton iconName=\"justifyRight\" title=\"Justify Right\"\n (click)=\"triggerCommand('justifyRight')\" [disabled]=\"htmlMode\"\n [hidden]=\"isButtonHidden('justifyRight')\">\n </button>\n <button [id]=\"'justifyFull-'+id\" aeButton iconName=\"justifyFull\" title=\"Justify Full\"\n (click)=\"triggerCommand('justifyFull')\" [disabled]=\"htmlMode\"\n [hidden]=\"isButtonHidden('justifyFull')\">\n </button>\n </div>\n <div aeToolbarSet>\n <button [id]=\"'indent-'+id\" aeButton iconName=\"indent\" title=\"Indent\"\n (click)=\"triggerCommand('indent')\"\n [disabled]=\"htmlMode\" [hidden]=\"isButtonHidden('indent')\">\n </button>\n <button [id]=\"'outdent-'+id\" aeButton iconName=\"outdent\" title=\"Outdent\"\n (click)=\"triggerCommand('outdent')\"\n [disabled]=\"htmlMode\" [hidden]=\"isButtonHidden('outdent')\">\n </button>\n </div>\n <div aeToolbarSet>\n <button [id]=\"'insertUnorderedList-'+id\" aeButton iconName=\"unorderedList\" title=\"Unordered List\"\n (click)=\"triggerCommand('insertUnorderedList')\" [disabled]=\"htmlMode\"\n [hidden]=\"isButtonHidden('insertUnorderedList')\">\n </button>\n <button [id]=\"'insertOrderedList-'+id\" aeButton iconName=\"orderedList\" title=\"Ordered List\"\n (click)=\"triggerCommand('insertOrderedList')\" [disabled]=\"htmlMode\"\n [hidden]=\"isButtonHidden('insertOrderedList')\">\n </button>\n </div>\n <div aeToolbarSet>\n <ae-select class=\"select-heading\" [options]=\"headings\"\n [(ngModel)]=\"block\"\n (change)=\"triggerCommand(block)\"\n [disabled]=\"htmlMode\"\n [hidden]=\"isButtonHidden('heading')\"\n tabindex=\"-1\"></ae-select>\n </div>\n <div aeToolbarSet>\n <ae-select class=\"select-font\" [options]=\"fonts\"\n [(ngModel)]=\"fontName\"\n (change)=\"setFontName(fontName)\"\n [disabled]=\"htmlMode\"\n [hidden]=\"isButtonHidden('fontName')\"\n tabindex=\"-1\"></ae-select>\n </div>\n <div aeToolbarSet>\n <ae-select class=\"select-font-size\" [options]=\"fontSizes\"\n [(ngModel)]=\"fontSize\"\n (change)=\"setFontSize(fontSize)\"\n [disabled]=\"htmlMode\"\n [hidden]=\"isButtonHidden('fontSize')\"\n tabindex=\"-1\">\n </ae-select>\n </div>\n <div aeToolbarSet>\n <input\n style=\"display: none\"\n type=\"color\" (change)=\"insertColor(fgInput.value, 'textColor')\"\n #fgInput>\n <button [id]=\"'foregroundColorPicker-'+id\" aeButton iconName=\"textColor\"\n (click)=\"focus(); fgInput.click()\"\n title=\"Text Color\"\n [disabled]=\"htmlMode\" [hidden]=\"isButtonHidden('textColor')\">\n </button>\n <input\n style=\"display: none\"\n type=\"color\" (change)=\"insertColor(bgInput.value, 'backgroundColor')\"\n #bgInput>\n <button [id]=\"'backgroundColorPicker-'+id\" aeButton iconName=\"backgroundColor\"\n (click)=\"focus(); bgInput.click()\"\n title=\"Background Color\"\n [disabled]=\"htmlMode\" [hidden]=\"isButtonHidden('backgroundColor')\">\n </button>\n </div>\n @if (_customClasses) {\n <div aeToolbarSet>\n <ae-select class=\"select-custom-style\" [options]=\"customClassList\"\n [(ngModel)]=\"customClassId\"\n (change)=\"setCustomClass(customClassId)\"\n [disabled]=\"htmlMode\"\n [hidden]=\"isButtonHidden('customClasses')\"\n tabindex=\"-1\"></ae-select>\n </div>\n }\n <div aeToolbarSet>\n <button [id]=\"'link-'+id\" aeButton iconName=\"link\" (click)=\"insertUrl()\"\n title=\"Insert Link\" [disabled]=\"isLinkButtonDisabled\" [hidden]=\"isButtonHidden('link')\">\n </button>\n <button [id]=\"'unlink-'+id\" aeButton iconName=\"unlink\" (click)=\"triggerCommand('unlink')\"\n title=\"Unlink\" [disabled]=\"htmlMode || !linkSelected\" [hidden]=\"isButtonHidden('unlink')\">\n </button>\n <input\n style=\"display: none\"\n accept=\"image/*\"\n type=\"file\" (change)=\"onFileChanged($event)\"\n #fileInput>\n <button [id]=\"'insertImage-'+id\" aeButton iconName=\"image\" (click)=\"focus(); fileInput.click()\"\n title=\"Insert Image\"\n [disabled]=\"htmlMode\" [hidden]=\"isButtonHidden('insertImage')\">\n </button>\n <button [id]=\"'insertVideo-'+id\" aeButton iconName=\"video\"\n (click)=\"insertVideo()\" title=\"Insert Video\" [disabled]=\"htmlMode\"\n [hidden]=\"isButtonHidden('insertVideo')\">\n </button>\n <button [id]=\"'insertHorizontalRule-'+id\" aeButton iconName=\"horizontalLine\" title=\"Horizontal Line\"\n (click)=\"triggerCommand('insertHorizontalRule')\" [disabled]=\"htmlMode\"\n [hidden]=\"isButtonHidden('insertHorizontalRule')\">\n </button>\n </div>\n <div aeToolbarSet>\n <button [id]=\"'clearFormatting-'+id\" aeButton iconName=\"removeFormat\" title=\"Clear Formatting\"\n class=\"angular-editor-button\"\n (click)=\"triggerCommand('removeFormat')\" [disabled]=\"htmlMode\" [hidden]=\"isButtonHidden('removeFormat')\">\n </button>\n </div>\n <div aeToolbarSet>\n <button [id]=\"'toggleEditorMode-'+id\" aeButton iconName=\"htmlCode\" title=\"HTML Code\"\n (click)=\"triggerCommand('toggleEditorMode')\" [hidden]=\"isButtonHidden('toggleEditorMode')\">\n </button>\n </div>\n <ng-content></ng-content>\n </div>\n}\n", styles: ["a{cursor:pointer}.angular-editor-toolbar{font:100 14px/15px Roboto,Arial,sans-serif;background-color:var(--ae-toolbar-bg-color, #f5f5f5);font-size:.8rem;padding:var(--ae-toolbar-padding, .2rem);border:var(--ae-toolbar-border-radius, 1px solid #ddd);display:flex;flex-wrap:wrap;gap:4px}.select-heading{display:inline-block;width:90px}@supports not (-moz-appearance: none){.select-heading optgroup{font-size:12px;background-color:#f4f4f4;padding:5px}.select-heading option{border:1px solid;background-color:#fff}}.select-heading:disabled{background-color:#f5f5f5;pointer-events:none;cursor:not-allowed}.select-heading:hover{cursor:pointer;background-color:#f1f1f1;transition:.2s ease}.select-font{display:inline-block;width:90px}@supports not (-moz-appearance: none){.select-font optgroup{font-size:12px;background-color:#f4f4f4;padding:5px}.select-font option{border:1px solid;background-color:#fff}}.select-font:disabled{background-color:#f5f5f5;pointer-events:none;cursor:not-allowed}.select-font:hover{cursor:pointer;background-color:#f1f1f1;transition:.2s ease}.select-font-size{display:inline-block;width:50px}@supports not (-moz-appearance: none){.select-font-size optgroup{font-size:12px;background-color:#f4f4f4;padding:5px}.select-font-size option{border:1px solid;background-color:#fff}.select-font-size .size1{font-size:10px}.select-font-size .size2{font-size:12px}.select-font-size .size3{font-size:14px}.select-font-size .size4{font-size:16px}.select-font-size .size5{font-size:18px}.select-font-size .size6{font-size:20px}.select-font-size .size7{font-size:22px}}.select-font-size:disabled{background-color:#f5f5f5;pointer-events:none;cursor:not-allowed}.select-font-size:hover{cursor:pointer;background-color:#f1f1f1;transition:.2s ease}.select-custom-style{display:inline-block;width:90px}@supports not (-moz-appearance: none){.select-custom-style optgroup{font-size:12px;background-color:#f4f4f4;padding:5px}.select-custom-style option{border:1px solid;background-color:#fff}}.select-custom-style:disabled{background-color:#f5f5f5;pointer-events:none;cursor:not-allowed}.select-custom-style:hover{cursor:pointer;background-color:#f1f1f1;transition:.2s ease}.color-label{position:relative;cursor:pointer}.background{font-size:smaller;background:#1b1b1b;color:#fff;padding:3px}.foreground :after{position:absolute;content:\"\";inset:auto auto -3px -1px;width:15px;height:2px;z-index:0;background:#1b1b1b}.default{font-size:16px}h1{font-size:24px}h2{font-size:20px}h3{font-size:16px}h4{font-size:15px}h5{font-size:14px}h6{font-size:13px}div,pre{font-size:12px}\n"], dependencies: [{ kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: AeSelectComponent, selector: "ae-select", inputs: ["options", "hidden"], outputs: ["change"] }, { kind: "component", type: AeButtonComponent, selector: "ae-button, button[aeButton]", inputs: ["iconName"] }, { kind: "component", type: AeToolbarSetComponent, selector: "ae-toolbar-set, [aeToolbarSet]" }] });
893
1078
  }
894
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: AeToolbarComponent, decorators: [{
1079
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: AeToolbarComponent, decorators: [{
895
1080
  type: Component,
896
- args: [{ selector: 'angular-editor-toolbar, ae-toolbar, div[aeToolbar]', standalone: false, template: "<div class=\"angular-editor-toolbar\" *ngIf=\"showToolbar\">\n <div aeToolbarSet>\n <button aeButton title=\"Undo\" iconName=\"undo\" (click)=\"triggerCommand('undo')\" [hidden]=\"isButtonHidden('undo')\">\n </button>\n <button aeButton title=\"Redo\" iconName=\"redo\" (click)=\"triggerCommand('redo')\"\n [hidden]=\"isButtonHidden('redo')\">\n </button>\n </div>\n <div aeToolbarSet>\n <button [id]=\"'bold-'+id\" aeButton title=\"Bold\" iconName=\"bold\" (click)=\"triggerCommand('bold')\"\n [disabled]=\"htmlMode\" [hidden]=\"isButtonHidden('bold')\">\n </button>\n <button [id]=\"'italic-'+id\" aeButton iconName=\"italic\" title=\"Italic\" (click)=\"triggerCommand('italic')\"\n [disabled]=\"htmlMode\" [hidden]=\"isButtonHidden('italic')\">\n </button>\n <button [id]=\"'underline-'+id\" aeButton title=\"Underline\" iconName=\"underline\"\n (click)=\"triggerCommand('underline')\" [disabled]=\"htmlMode\" [hidden]=\"isButtonHidden('underline')\">\n </button>\n <button [id]=\"'strikeThrough-'+id\" aeButton iconName=\"strikeThrough\" title=\"Strikethrough\"\n (click)=\"triggerCommand('strikeThrough')\" [disabled]=\"htmlMode\"\n [hidden]=\"isButtonHidden('strikeThrough')\">\n </button>\n <button [id]=\"'subscript-'+id\" aeButton title=\"Subscript\" iconName=\"subscript\"\n (click)=\"triggerCommand('subscript')\" [disabled]=\"htmlMode\" [hidden]=\"isButtonHidden('subscript')\">\n </button>\n <button [id]=\"'superscript-'+id\" aeButton iconName=\"superscript\" title=\"Superscript\"\n (click)=\"triggerCommand('superscript')\" [disabled]=\"htmlMode\"\n [hidden]=\"isButtonHidden('superscript')\">\n </button>\n </div>\n <div aeToolbarSet>\n <button [id]=\"'justifyLeft-'+id\" aeButton iconName=\"justifyLeft\" title=\"Justify Left\"\n (click)=\"triggerCommand('justifyLeft')\" [disabled]=\"htmlMode\"\n [hidden]=\"isButtonHidden('justifyLeft')\">\n </button>\n <button [id]=\"'justifyCenter-'+id\" aeButton iconName=\"justifyCenter\" title=\"Justify Center\"\n (click)=\"triggerCommand('justifyCenter')\" [disabled]=\"htmlMode\"\n [hidden]=\"isButtonHidden('justifyCenter')\">\n </button>\n <button [id]=\"'justifyRight-'+id\" aeButton iconName=\"justifyRight\" title=\"Justify Right\"\n (click)=\"triggerCommand('justifyRight')\" [disabled]=\"htmlMode\"\n [hidden]=\"isButtonHidden('justifyRight')\">\n </button>\n <button [id]=\"'justifyFull-'+id\" aeButton iconName=\"justifyFull\" title=\"Justify Full\"\n (click)=\"triggerCommand('justifyFull')\" [disabled]=\"htmlMode\"\n [hidden]=\"isButtonHidden('justifyFull')\">\n </button>\n </div>\n <div aeToolbarSet>\n <button [id]=\"'indent-'+id\" aeButton iconName=\"indent\" title=\"Indent\"\n (click)=\"triggerCommand('indent')\"\n [disabled]=\"htmlMode\" [hidden]=\"isButtonHidden('indent')\">\n </button>\n <button [id]=\"'outdent-'+id\" aeButton iconName=\"outdent\" title=\"Outdent\"\n (click)=\"triggerCommand('outdent')\"\n [disabled]=\"htmlMode\" [hidden]=\"isButtonHidden('outdent')\">\n </button>\n </div>\n <div aeToolbarSet>\n <button [id]=\"'insertUnorderedList-'+id\" aeButton iconName=\"unorderedList\" title=\"Unordered List\"\n (click)=\"triggerCommand('insertUnorderedList')\" [disabled]=\"htmlMode\"\n [hidden]=\"isButtonHidden('insertUnorderedList')\">\n </button>\n <button [id]=\"'insertOrderedList-'+id\" aeButton iconName=\"orderedList\" title=\"Ordered List\"\n (click)=\"triggerCommand('insertOrderedList')\" [disabled]=\"htmlMode\"\n [hidden]=\"isButtonHidden('insertOrderedList')\">\n </button>\n </div>\n <div aeToolbarSet>\n <ae-select class=\"select-heading\" [options]=\"headings\"\n [(ngModel)]=\"block\"\n (change)=\"triggerCommand(block)\"\n [disabled]=\"htmlMode\"\n [hidden]=\"isButtonHidden('heading')\"\n tabindex=\"-1\"></ae-select>\n </div>\n <div aeToolbarSet>\n <ae-select class=\"select-font\" [options]=\"fonts\"\n [(ngModel)]=\"fontName\"\n (change)=\"setFontName(fontName)\"\n [disabled]=\"htmlMode\"\n [hidden]=\"isButtonHidden('fontName')\"\n tabindex=\"-1\"></ae-select>\n </div>\n <div aeToolbarSet>\n <ae-select class=\"select-font-size\" [options]=\"fontSizes\"\n [(ngModel)]=\"fontSize\"\n (change)=\"setFontSize(fontSize)\"\n [disabled]=\"htmlMode\"\n [hidden]=\"isButtonHidden('fontSize')\"\n tabindex=\"-1\">\n </ae-select>\n </div>\n <div aeToolbarSet>\n <input\n style=\"display: none\"\n type=\"color\" (change)=\"insertColor(fgInput.value, 'textColor')\"\n #fgInput>\n <button [id]=\"'foregroundColorPicker-'+id\" aeButton iconName=\"textColor\"\n (click)=\"focus(); ; fgInput.click()\"\n title=\"Text Color\"\n [disabled]=\"htmlMode\" [hidden]=\"isButtonHidden('textColor')\">\n </button>\n <input\n style=\"display: none\"\n type=\"color\" (change)=\"insertColor(bgInput.value, 'backgroundColor')\"\n #bgInput>\n <button [id]=\"'backgroundColorPicker-'+id\" aeButton iconName=\"backgroundColor\"\n (click)=\"focus(); ; bgInput.click()\"\n title=\"Background Color\"\n [disabled]=\"htmlMode\" [hidden]=\"isButtonHidden('backgroundColor')\">\n </button>\n </div>\n <div *ngIf=\"_customClasses\" aeToolbarSet>\n <ae-select class=\"select-custom-style\" [options]=\"customClassList\"\n [(ngModel)]=\"customClassId\"\n (change)=\"setCustomClass(customClassId)\"\n [disabled]=\"htmlMode\"\n [hidden]=\"isButtonHidden('customClasses')\"\n tabindex=\"-1\"></ae-select>\n </div>\n <div aeToolbarSet>\n <button [id]=\"'link-'+id\" aeButton iconName=\"link\" (click)=\"insertUrl()\"\n title=\"Insert Link\" [disabled]=\"isLinkButtonDisabled\" [hidden]=\"isButtonHidden('link')\">\n </button>\n <button [id]=\"'unlink-'+id\" aeButton iconName=\"unlink\" (click)=\"triggerCommand('unlink')\"\n title=\"Unlink\" [disabled]=\"htmlMode || !linkSelected\" [hidden]=\"isButtonHidden('unlink')\">\n </button>\n <input\n style=\"display: none\"\n accept=\"image/*\"\n type=\"file\" (change)=\"onFileChanged($event)\"\n #fileInput>\n <button [id]=\"'insertImage-'+id\" aeButton iconName=\"image\" (click)=\"focus(); fileInput.click()\"\n title=\"Insert Image\"\n [disabled]=\"htmlMode\" [hidden]=\"isButtonHidden('insertImage')\">\n </button>\n <button [id]=\"'insertVideo-'+id\" aeButton iconName=\"video\"\n (click)=\"insertVideo()\" title=\"Insert Video\" [disabled]=\"htmlMode\"\n [hidden]=\"isButtonHidden('insertVideo')\">\n </button>\n <button [id]=\"'insertHorizontalRule-'+id\" aeButton iconName=\"horizontalLine\" title=\"Horizontal Line\"\n (click)=\"triggerCommand('insertHorizontalRule')\" [disabled]=\"htmlMode\"\n [hidden]=\"isButtonHidden('insertHorizontalRule')\">\n </button>\n </div>\n <div aeToolbarSet>\n <button [id]=\"'clearFormatting-'+id\" aeButton iconName=\"removeFormat\" title=\"Clear Formatting\"\n class=\"angular-editor-button\"\n (click)=\"triggerCommand('removeFormat')\" [disabled]=\"htmlMode\" [hidden]=\"isButtonHidden('removeFormat')\">\n </button>\n </div>\n <div aeToolbarSet>\n <button [id]=\"'toggleEditorMode-'+id\" aeButton iconName=\"htmlCode\" title=\"HTML Code\"\n (click)=\"triggerCommand('toggleEditorMode')\" [hidden]=\"isButtonHidden('toggleEditorMode')\">\n </button>\n </div>\n <ng-content></ng-content>\n</div>\n", styles: ["a{cursor:pointer}.angular-editor-toolbar{font:100 14px/15px Roboto,Arial,sans-serif;background-color:var(--ae-toolbar-bg-color, #f5f5f5);font-size:.8rem;padding:var(--ae-toolbar-padding, .2rem);border:var(--ae-toolbar-border-radius, 1px solid #ddd);display:flex;flex-wrap:wrap;gap:4px}.select-heading{display:inline-block;width:90px}@supports not (-moz-appearance: none){.select-heading optgroup{font-size:12px;background-color:#f4f4f4;padding:5px}.select-heading option{border:1px solid;background-color:#fff}}.select-heading:disabled{background-color:#f5f5f5;pointer-events:none;cursor:not-allowed}.select-heading:hover{cursor:pointer;background-color:#f1f1f1;transition:.2s ease}.select-font{display:inline-block;width:90px}@supports not (-moz-appearance: none){.select-font optgroup{font-size:12px;background-color:#f4f4f4;padding:5px}.select-font option{border:1px solid;background-color:#fff}}.select-font:disabled{background-color:#f5f5f5;pointer-events:none;cursor:not-allowed}.select-font:hover{cursor:pointer;background-color:#f1f1f1;transition:.2s ease}.select-font-size{display:inline-block;width:50px}@supports not (-moz-appearance: none){.select-font-size optgroup{font-size:12px;background-color:#f4f4f4;padding:5px}.select-font-size option{border:1px solid;background-color:#fff}.select-font-size .size1{font-size:10px}.select-font-size .size2{font-size:12px}.select-font-size .size3{font-size:14px}.select-font-size .size4{font-size:16px}.select-font-size .size5{font-size:18px}.select-font-size .size6{font-size:20px}.select-font-size .size7{font-size:22px}}.select-font-size:disabled{background-color:#f5f5f5;pointer-events:none;cursor:not-allowed}.select-font-size:hover{cursor:pointer;background-color:#f1f1f1;transition:.2s ease}.select-custom-style{display:inline-block;width:90px}@supports not (-moz-appearance: none){.select-custom-style optgroup{font-size:12px;background-color:#f4f4f4;padding:5px}.select-custom-style option{border:1px solid;background-color:#fff}}.select-custom-style:disabled{background-color:#f5f5f5;pointer-events:none;cursor:not-allowed}.select-custom-style:hover{cursor:pointer;background-color:#f1f1f1;transition:.2s ease}.color-label{position:relative;cursor:pointer}.background{font-size:smaller;background:#1b1b1b;color:#fff;padding:3px}.foreground :after{position:absolute;content:\"\";inset:auto auto -3px -1px;width:15px;height:2px;z-index:0;background:#1b1b1b}.default{font-size:16px}h1{font-size:24px}h2{font-size:20px}h3{font-size:16px}h4{font-size:15px}h5{font-size:14px}h6{font-size:13px}div,pre{font-size:12px}\n"] }]
897
- }], ctorParameters: () => [{ type: i0.Renderer2 }, { type: AngularEditorService }, { type: i0.ElementRef }, { type: undefined, decorators: [{
898
- type: Inject,
899
- args: [DOCUMENT]
900
- }] }], propDecorators: { id: [{
1081
+ args: [{ selector: 'angular-editor-toolbar, ae-toolbar, div[aeToolbar]', standalone: false, template: "@if (showToolbar) {\n <div class=\"angular-editor-toolbar\">\n <div aeToolbarSet>\n <button aeButton title=\"Undo\" iconName=\"undo\" (click)=\"triggerCommand('undo')\" [hidden]=\"isButtonHidden('undo')\">\n </button>\n <button aeButton title=\"Redo\" iconName=\"redo\" (click)=\"triggerCommand('redo')\"\n [hidden]=\"isButtonHidden('redo')\">\n </button>\n </div>\n <div aeToolbarSet>\n <button [id]=\"'bold-'+id\" aeButton title=\"Bold\" iconName=\"bold\" (click)=\"triggerCommand('bold')\"\n [disabled]=\"htmlMode\" [hidden]=\"isButtonHidden('bold')\">\n </button>\n <button [id]=\"'italic-'+id\" aeButton iconName=\"italic\" title=\"Italic\" (click)=\"triggerCommand('italic')\"\n [disabled]=\"htmlMode\" [hidden]=\"isButtonHidden('italic')\">\n </button>\n <button [id]=\"'underline-'+id\" aeButton title=\"Underline\" iconName=\"underline\"\n (click)=\"triggerCommand('underline')\" [disabled]=\"htmlMode\" [hidden]=\"isButtonHidden('underline')\">\n </button>\n <button [id]=\"'strikeThrough-'+id\" aeButton iconName=\"strikeThrough\" title=\"Strikethrough\"\n (click)=\"triggerCommand('strikeThrough')\" [disabled]=\"htmlMode\"\n [hidden]=\"isButtonHidden('strikeThrough')\">\n </button>\n <button [id]=\"'subscript-'+id\" aeButton title=\"Subscript\" iconName=\"subscript\"\n (click)=\"triggerCommand('subscript')\" [disabled]=\"htmlMode\" [hidden]=\"isButtonHidden('subscript')\">\n </button>\n <button [id]=\"'superscript-'+id\" aeButton iconName=\"superscript\" title=\"Superscript\"\n (click)=\"triggerCommand('superscript')\" [disabled]=\"htmlMode\"\n [hidden]=\"isButtonHidden('superscript')\">\n </button>\n </div>\n <div aeToolbarSet>\n <button [id]=\"'justifyLeft-'+id\" aeButton iconName=\"justifyLeft\" title=\"Justify Left\"\n (click)=\"triggerCommand('justifyLeft')\" [disabled]=\"htmlMode\"\n [hidden]=\"isButtonHidden('justifyLeft')\">\n </button>\n <button [id]=\"'justifyCenter-'+id\" aeButton iconName=\"justifyCenter\" title=\"Justify Center\"\n (click)=\"triggerCommand('justifyCenter')\" [disabled]=\"htmlMode\"\n [hidden]=\"isButtonHidden('justifyCenter')\">\n </button>\n <button [id]=\"'justifyRight-'+id\" aeButton iconName=\"justifyRight\" title=\"Justify Right\"\n (click)=\"triggerCommand('justifyRight')\" [disabled]=\"htmlMode\"\n [hidden]=\"isButtonHidden('justifyRight')\">\n </button>\n <button [id]=\"'justifyFull-'+id\" aeButton iconName=\"justifyFull\" title=\"Justify Full\"\n (click)=\"triggerCommand('justifyFull')\" [disabled]=\"htmlMode\"\n [hidden]=\"isButtonHidden('justifyFull')\">\n </button>\n </div>\n <div aeToolbarSet>\n <button [id]=\"'indent-'+id\" aeButton iconName=\"indent\" title=\"Indent\"\n (click)=\"triggerCommand('indent')\"\n [disabled]=\"htmlMode\" [hidden]=\"isButtonHidden('indent')\">\n </button>\n <button [id]=\"'outdent-'+id\" aeButton iconName=\"outdent\" title=\"Outdent\"\n (click)=\"triggerCommand('outdent')\"\n [disabled]=\"htmlMode\" [hidden]=\"isButtonHidden('outdent')\">\n </button>\n </div>\n <div aeToolbarSet>\n <button [id]=\"'insertUnorderedList-'+id\" aeButton iconName=\"unorderedList\" title=\"Unordered List\"\n (click)=\"triggerCommand('insertUnorderedList')\" [disabled]=\"htmlMode\"\n [hidden]=\"isButtonHidden('insertUnorderedList')\">\n </button>\n <button [id]=\"'insertOrderedList-'+id\" aeButton iconName=\"orderedList\" title=\"Ordered List\"\n (click)=\"triggerCommand('insertOrderedList')\" [disabled]=\"htmlMode\"\n [hidden]=\"isButtonHidden('insertOrderedList')\">\n </button>\n </div>\n <div aeToolbarSet>\n <ae-select class=\"select-heading\" [options]=\"headings\"\n [(ngModel)]=\"block\"\n (change)=\"triggerCommand(block)\"\n [disabled]=\"htmlMode\"\n [hidden]=\"isButtonHidden('heading')\"\n tabindex=\"-1\"></ae-select>\n </div>\n <div aeToolbarSet>\n <ae-select class=\"select-font\" [options]=\"fonts\"\n [(ngModel)]=\"fontName\"\n (change)=\"setFontName(fontName)\"\n [disabled]=\"htmlMode\"\n [hidden]=\"isButtonHidden('fontName')\"\n tabindex=\"-1\"></ae-select>\n </div>\n <div aeToolbarSet>\n <ae-select class=\"select-font-size\" [options]=\"fontSizes\"\n [(ngModel)]=\"fontSize\"\n (change)=\"setFontSize(fontSize)\"\n [disabled]=\"htmlMode\"\n [hidden]=\"isButtonHidden('fontSize')\"\n tabindex=\"-1\">\n </ae-select>\n </div>\n <div aeToolbarSet>\n <input\n style=\"display: none\"\n type=\"color\" (change)=\"insertColor(fgInput.value, 'textColor')\"\n #fgInput>\n <button [id]=\"'foregroundColorPicker-'+id\" aeButton iconName=\"textColor\"\n (click)=\"focus(); fgInput.click()\"\n title=\"Text Color\"\n [disabled]=\"htmlMode\" [hidden]=\"isButtonHidden('textColor')\">\n </button>\n <input\n style=\"display: none\"\n type=\"color\" (change)=\"insertColor(bgInput.value, 'backgroundColor')\"\n #bgInput>\n <button [id]=\"'backgroundColorPicker-'+id\" aeButton iconName=\"backgroundColor\"\n (click)=\"focus(); bgInput.click()\"\n title=\"Background Color\"\n [disabled]=\"htmlMode\" [hidden]=\"isButtonHidden('backgroundColor')\">\n </button>\n </div>\n @if (_customClasses) {\n <div aeToolbarSet>\n <ae-select class=\"select-custom-style\" [options]=\"customClassList\"\n [(ngModel)]=\"customClassId\"\n (change)=\"setCustomClass(customClassId)\"\n [disabled]=\"htmlMode\"\n [hidden]=\"isButtonHidden('customClasses')\"\n tabindex=\"-1\"></ae-select>\n </div>\n }\n <div aeToolbarSet>\n <button [id]=\"'link-'+id\" aeButton iconName=\"link\" (click)=\"insertUrl()\"\n title=\"Insert Link\" [disabled]=\"isLinkButtonDisabled\" [hidden]=\"isButtonHidden('link')\">\n </button>\n <button [id]=\"'unlink-'+id\" aeButton iconName=\"unlink\" (click)=\"triggerCommand('unlink')\"\n title=\"Unlink\" [disabled]=\"htmlMode || !linkSelected\" [hidden]=\"isButtonHidden('unlink')\">\n </button>\n <input\n style=\"display: none\"\n accept=\"image/*\"\n type=\"file\" (change)=\"onFileChanged($event)\"\n #fileInput>\n <button [id]=\"'insertImage-'+id\" aeButton iconName=\"image\" (click)=\"focus(); fileInput.click()\"\n title=\"Insert Image\"\n [disabled]=\"htmlMode\" [hidden]=\"isButtonHidden('insertImage')\">\n </button>\n <button [id]=\"'insertVideo-'+id\" aeButton iconName=\"video\"\n (click)=\"insertVideo()\" title=\"Insert Video\" [disabled]=\"htmlMode\"\n [hidden]=\"isButtonHidden('insertVideo')\">\n </button>\n <button [id]=\"'insertHorizontalRule-'+id\" aeButton iconName=\"horizontalLine\" title=\"Horizontal Line\"\n (click)=\"triggerCommand('insertHorizontalRule')\" [disabled]=\"htmlMode\"\n [hidden]=\"isButtonHidden('insertHorizontalRule')\">\n </button>\n </div>\n <div aeToolbarSet>\n <button [id]=\"'clearFormatting-'+id\" aeButton iconName=\"removeFormat\" title=\"Clear Formatting\"\n class=\"angular-editor-button\"\n (click)=\"triggerCommand('removeFormat')\" [disabled]=\"htmlMode\" [hidden]=\"isButtonHidden('removeFormat')\">\n </button>\n </div>\n <div aeToolbarSet>\n <button [id]=\"'toggleEditorMode-'+id\" aeButton iconName=\"htmlCode\" title=\"HTML Code\"\n (click)=\"triggerCommand('toggleEditorMode')\" [hidden]=\"isButtonHidden('toggleEditorMode')\">\n </button>\n </div>\n <ng-content></ng-content>\n </div>\n}\n", styles: ["a{cursor:pointer}.angular-editor-toolbar{font:100 14px/15px Roboto,Arial,sans-serif;background-color:var(--ae-toolbar-bg-color, #f5f5f5);font-size:.8rem;padding:var(--ae-toolbar-padding, .2rem);border:var(--ae-toolbar-border-radius, 1px solid #ddd);display:flex;flex-wrap:wrap;gap:4px}.select-heading{display:inline-block;width:90px}@supports not (-moz-appearance: none){.select-heading optgroup{font-size:12px;background-color:#f4f4f4;padding:5px}.select-heading option{border:1px solid;background-color:#fff}}.select-heading:disabled{background-color:#f5f5f5;pointer-events:none;cursor:not-allowed}.select-heading:hover{cursor:pointer;background-color:#f1f1f1;transition:.2s ease}.select-font{display:inline-block;width:90px}@supports not (-moz-appearance: none){.select-font optgroup{font-size:12px;background-color:#f4f4f4;padding:5px}.select-font option{border:1px solid;background-color:#fff}}.select-font:disabled{background-color:#f5f5f5;pointer-events:none;cursor:not-allowed}.select-font:hover{cursor:pointer;background-color:#f1f1f1;transition:.2s ease}.select-font-size{display:inline-block;width:50px}@supports not (-moz-appearance: none){.select-font-size optgroup{font-size:12px;background-color:#f4f4f4;padding:5px}.select-font-size option{border:1px solid;background-color:#fff}.select-font-size .size1{font-size:10px}.select-font-size .size2{font-size:12px}.select-font-size .size3{font-size:14px}.select-font-size .size4{font-size:16px}.select-font-size .size5{font-size:18px}.select-font-size .size6{font-size:20px}.select-font-size .size7{font-size:22px}}.select-font-size:disabled{background-color:#f5f5f5;pointer-events:none;cursor:not-allowed}.select-font-size:hover{cursor:pointer;background-color:#f1f1f1;transition:.2s ease}.select-custom-style{display:inline-block;width:90px}@supports not (-moz-appearance: none){.select-custom-style optgroup{font-size:12px;background-color:#f4f4f4;padding:5px}.select-custom-style option{border:1px solid;background-color:#fff}}.select-custom-style:disabled{background-color:#f5f5f5;pointer-events:none;cursor:not-allowed}.select-custom-style:hover{cursor:pointer;background-color:#f1f1f1;transition:.2s ease}.color-label{position:relative;cursor:pointer}.background{font-size:smaller;background:#1b1b1b;color:#fff;padding:3px}.foreground :after{position:absolute;content:\"\";inset:auto auto -3px -1px;width:15px;height:2px;z-index:0;background:#1b1b1b}.default{font-size:16px}h1{font-size:24px}h2{font-size:20px}h3{font-size:16px}h4{font-size:15px}h5{font-size:14px}h6{font-size:13px}div,pre{font-size:12px}\n"] }]
1082
+ }], propDecorators: { id: [{
901
1083
  type: Input
902
1084
  }], uploadUrl: [{
903
1085
  type: Input
@@ -923,11 +1105,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.13", ngImpo
923
1105
  }] } });
924
1106
 
925
1107
  class AngularEditorComponent {
926
- r;
927
- editorService;
928
- doc;
929
- sanitizer;
930
- cdRef;
931
1108
  autoFocus;
932
1109
  onChange;
933
1110
  onTouched;
@@ -937,16 +1114,20 @@ class AngularEditorComponent {
937
1114
  focused = false;
938
1115
  touched = false;
939
1116
  changed = false;
1117
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
940
1118
  focusInstance;
1119
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
941
1120
  blurInstance;
942
1121
  id = '';
943
1122
  config = angularEditorConfig;
944
1123
  placeholder = '';
945
- tabIndex;
946
- html;
1124
+ tabIndex = null;
1125
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1126
+ html = new EventEmitter();
947
1127
  textArea;
948
1128
  editorWrapper;
949
1129
  editorToolbar;
1130
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
950
1131
  customButtonsTemplateRef;
951
1132
  executeCommandFn = this.executeCommand.bind(this);
952
1133
  viewMode = new EventEmitter();
@@ -960,12 +1141,15 @@ class AngularEditorComponent {
960
1141
  onFocus() {
961
1142
  this.focus();
962
1143
  }
963
- constructor(r, editorService, doc, sanitizer, cdRef, defaultTabIndex, autoFocus) {
964
- this.r = r;
965
- this.editorService = editorService;
966
- this.doc = doc;
967
- this.sanitizer = sanitizer;
968
- this.cdRef = cdRef;
1144
+ r = inject(Renderer2);
1145
+ editorService = inject(AngularEditorService);
1146
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1147
+ doc = inject(DOCUMENT);
1148
+ sanitizer = inject(DomSanitizer);
1149
+ cdRef = inject(ChangeDetectorRef);
1150
+ constructor(defaultTabIndex,
1151
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1152
+ autoFocus) {
969
1153
  this.autoFocus = autoFocus;
970
1154
  const parsedTabIndex = Number(defaultTabIndex);
971
1155
  this.tabIndex = (parsedTabIndex || parsedTabIndex === 0) ? parsedTabIndex : null;
@@ -981,10 +1165,11 @@ class AngularEditorComponent {
981
1165
  onPaste(event) {
982
1166
  if (this.config.rawPaste) {
983
1167
  event.preventDefault();
984
- const text = event.clipboardData.getData('text/plain');
1168
+ const text = event.clipboardData?.getData('text/plain') ?? '';
985
1169
  document.execCommand('insertHTML', false, text);
986
1170
  return text;
987
1171
  }
1172
+ return undefined;
988
1173
  }
989
1174
  /**
990
1175
  * Executed command from editor header buttons
@@ -1046,11 +1231,11 @@ class AngularEditorComponent {
1046
1231
  */
1047
1232
  this.editorService.executeInNextQueueIteration(this.editorService.saveSelection);
1048
1233
  if (typeof this.onTouched === 'function') {
1049
- this.onTouched();
1234
+ (this.onTouched)();
1050
1235
  }
1051
1236
  if (event.relatedTarget !== null) {
1052
1237
  const parent = event.relatedTarget.parentElement;
1053
- if (!parent.classList.contains('angular-editor-toolbar-set') && !parent.classList.contains('ae-picker')) {
1238
+ if (!parent?.classList.contains('angular-editor-toolbar-set') && !parent?.classList.contains('ae-picker')) {
1054
1239
  this.blurEvent.emit(event);
1055
1240
  this.focused = false;
1056
1241
  }
@@ -1074,19 +1259,15 @@ class AngularEditorComponent {
1074
1259
  * @param element html element from contenteditable
1075
1260
  */
1076
1261
  onContentChange(element) {
1077
- let html = '';
1078
- if (this.modeVisual) {
1079
- html = element.innerHTML;
1080
- }
1081
- else {
1082
- html = element.innerText;
1083
- }
1262
+ let html = this.modeVisual ? element.innerHTML : element.innerText;
1084
1263
  if ((!html || html === '<br>')) {
1085
1264
  html = '';
1086
1265
  }
1087
1266
  if (typeof this.onChange === 'function') {
1088
- this.onChange(this.config.sanitize || this.config.sanitize === undefined ?
1089
- this.sanitizer.sanitize(SecurityContext.HTML, html) : html);
1267
+ const sanitized = (this.config.sanitize || this.config.sanitize === undefined)
1268
+ ? (this.sanitizer.sanitize(SecurityContext.HTML, html) ?? '')
1269
+ : html;
1270
+ (this.onChange)(sanitized);
1090
1271
  if ((!html) !== this.showPlaceholder) {
1091
1272
  this.togglePlaceholder(this.showPlaceholder);
1092
1273
  }
@@ -1099,8 +1280,9 @@ class AngularEditorComponent {
1099
1280
  *
1100
1281
  * @param fn a function
1101
1282
  */
1283
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1102
1284
  registerOnChange(fn) {
1103
- this.onChange = e => (e === '<br>' ? fn('') : fn(e));
1285
+ this.onChange = (e) => (e === '<br>' ? fn('') : fn(e));
1104
1286
  }
1105
1287
  /**
1106
1288
  * Set the function to be called
@@ -1108,6 +1290,7 @@ class AngularEditorComponent {
1108
1290
  *
1109
1291
  * @param fn a function
1110
1292
  */
1293
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1111
1294
  registerOnTouched(fn) {
1112
1295
  this.onTouched = fn;
1113
1296
  }
@@ -1116,6 +1299,7 @@ class AngularEditorComponent {
1116
1299
  *
1117
1300
  * @param value value to be executed when there is a change in contenteditable
1118
1301
  */
1302
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1119
1303
  writeValue(value) {
1120
1304
  if ((!value || value === '<br>' || value === '') !== this.showPlaceholder) {
1121
1305
  this.togglePlaceholder(this.showPlaceholder);
@@ -1247,8 +1431,8 @@ class AngularEditorComponent {
1247
1431
  this.editorToolbar.triggerBlocks(els);
1248
1432
  }
1249
1433
  configure() {
1250
- this.editorService.uploadUrl = this.config.uploadUrl;
1251
- this.editorService.uploadWithCredentials = this.config.uploadWithCredentials;
1434
+ this.editorService.uploadUrl = this.config.uploadUrl ?? '';
1435
+ this.editorService.uploadWithCredentials = this.config.uploadWithCredentials ?? false;
1252
1436
  if (this.config.defaultParagraphSeparator) {
1253
1437
  this.editorService.setDefaultParagraphSeparator(this.config.defaultParagraphSeparator);
1254
1438
  }
@@ -1260,14 +1444,14 @@ class AngularEditorComponent {
1260
1444
  }
1261
1445
  }
1262
1446
  getFonts() {
1263
- const fonts = this.config.fonts ? this.config.fonts : angularEditorConfig.fonts;
1447
+ const fonts = this.config.fonts ? this.config.fonts : (angularEditorConfig.fonts ?? []);
1264
1448
  return fonts.map(x => {
1265
1449
  return { label: x.name, value: x.name };
1266
1450
  });
1267
1451
  }
1268
1452
  getCustomTags() {
1269
1453
  const tags = ['span'];
1270
- this.config.customClasses.forEach(x => {
1454
+ (this.config.customClasses ?? []).forEach(x => {
1271
1455
  if (x.tag !== undefined) {
1272
1456
  if (!tags.includes(x.tag)) {
1273
1457
  tags.push(x.tag);
@@ -1288,17 +1472,17 @@ class AngularEditorComponent {
1288
1472
  html = html.replace('position: fixed;', '');
1289
1473
  return html;
1290
1474
  }
1291
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: AngularEditorComponent, deps: [{ token: i0.Renderer2 }, { token: AngularEditorService }, { token: DOCUMENT }, { token: i2.DomSanitizer }, { token: i0.ChangeDetectorRef }, { token: 'tabindex', attribute: true }, { token: 'autofocus', attribute: true }], target: i0.ɵɵFactoryTarget.Component });
1292
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.13", type: AngularEditorComponent, isStandalone: false, selector: "angular-editor", inputs: { id: "id", config: "config", placeholder: "placeholder", tabIndex: "tabIndex" }, outputs: { html: "html", viewMode: "viewMode", blurEvent: "blur", focusEvent: "focus" }, host: { listeners: { "focus": "onFocus()" }, properties: { "attr.tabindex": "this.tabindex" } }, providers: [
1475
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: AngularEditorComponent, deps: [{ token: 'tabindex', attribute: true }, { token: 'autofocus', attribute: true }], target: i0.ɵɵFactoryTarget.Component });
1476
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.7", type: AngularEditorComponent, isStandalone: false, selector: "angular-editor", inputs: { id: "id", config: "config", placeholder: "placeholder", tabIndex: "tabIndex" }, outputs: { html: "html", viewMode: "viewMode", blurEvent: "blur", focusEvent: "focus" }, host: { listeners: { "focus": "onFocus()" }, properties: { "attr.tabindex": "this.tabindex" } }, providers: [
1293
1477
  {
1294
1478
  provide: NG_VALUE_ACCESSOR,
1295
1479
  useExisting: forwardRef(() => AngularEditorComponent),
1296
1480
  multi: true
1297
1481
  },
1298
1482
  AngularEditorService
1299
- ], queries: [{ propertyName: "customButtonsTemplateRef", first: true, predicate: ["customButtons"], descendants: true }], viewQueries: [{ propertyName: "textArea", first: true, predicate: ["editor"], descendants: true, static: true }, { propertyName: "editorWrapper", first: true, predicate: ["editorWrapper"], descendants: true, static: true }, { propertyName: "editorToolbar", first: true, predicate: ["editorToolbar"], descendants: true }], ngImport: i0, template: "<div\n class=\"angular-editor\"\n #angularEditor\n [style.width]=\"config.width\"\n [style.minWidth]=\"config.minWidth\"\n [ngClass]=\"{\n 'bottom': config.toolbarPosition === 'bottom'\n }\"\n>\n <angular-editor-toolbar\n #editorToolbar\n [id]=\"id\"\n [uploadUrl]=\"config.uploadUrl\"\n [upload]=\"config.upload\"\n [showToolbar]=\"config.showToolbar !== undefined ? config.showToolbar : true\"\n [fonts]=\"getFonts()\"\n [customClasses]=\"config.customClasses\"\n [defaultFontName]=\"config.defaultFontName\"\n [defaultFontSize]=\"config.defaultFontSize\"\n [hiddenButtons]=\"config.toolbarHiddenButtons\"\n (execute)=\"executeCommand($event)\"\n >\n <ng-container\n [ngTemplateOutlet]=\"customButtonsTemplateRef\"\n [ngTemplateOutletContext]=\"{ executeCommandFn: this.executeCommandFn}\"\n >\n </ng-container>\n </angular-editor-toolbar>\n\n <div\n class=\"angular-editor-wrapper\"\n #editorWrapper\n >\n <div\n #editor\n class=\"angular-editor-textarea\"\n [attr.contenteditable]=\"config.editable\"\n [attr.tabindex]=\"disabled ? -1 : tabIndex\"\n [attr.translate]=\"config.translate\"\n [attr.spellcheck]=\"config.spellcheck\"\n [style.height]=\"config.height\"\n [style.minHeight]=\"config.minHeight\"\n [style.maxHeight]=\"config.maxHeight\"\n [style.outline]=\"config.outline === false ? 'none': undefined\"\n (input)=\"onContentChange($any($event.target))\"\n (focus)=\"onTextAreaFocus($event)\"\n (blur)=\"onTextAreaBlur($event)\"\n (click)=\"exec()\"\n (keyup)=\"exec()\"\n (mouseout)=\"onTextAreaMouseOut($event)\"\n (paste)=\"onPaste($event)\"\n >\n </div>\n <span class=\"angular-editor-placeholder\">{{ placeholder || config['placeholder'] }}</span>\n </div>\n</div>\n", styles: ["a{cursor:pointer}.angular-editor{display:flex;flex-direction:column;gap:var(--ae-gap, 5px)}.angular-editor.bottom{flex-direction:column-reverse}.angular-editor ::ng-deep [contenteditable=true]:empty:before{content:attr(placeholder);color:#868e96;opacity:1}.angular-editor .angular-editor-wrapper{position:relative}.angular-editor .angular-editor-wrapper .angular-editor-textarea{min-height:150px;overflow:auto;resize:vertical}.angular-editor .angular-editor-wrapper .angular-editor-textarea:after{content:\"\";position:absolute;bottom:0;right:0;display:block;width:8px;height:8px;cursor:nwse-resize;background-color:#ffffff80}.angular-editor .angular-editor-wrapper .angular-editor-textarea{min-height:5rem;padding:.5rem .8rem 1rem;border-radius:var(--ae-text-area-border-radius, .3rem);border:var(--ae-text-area-border, 1px solid #ddd);background-color:transparent;overflow-x:hidden;overflow-y:auto;position:relative}.angular-editor .angular-editor-wrapper .angular-editor-textarea:focus,.angular-editor .angular-editor-wrapper .angular-editor-textarea.focus{outline:var(--ae-focus-outline-color, -webkit-focus-ring-color auto 1px)}.angular-editor .angular-editor-wrapper .angular-editor-textarea ::ng-deep blockquote{margin-left:1rem;border-left:.2em solid #dfe2e5;padding-left:.5rem}.angular-editor .angular-editor-wrapper ::ng-deep p{margin-bottom:0}.angular-editor .angular-editor-wrapper .angular-editor-placeholder{display:none;position:absolute;top:0;padding:.6rem .8rem 1rem .9rem;color:#6c757d;opacity:.75}.angular-editor .angular-editor-wrapper.show-placeholder .angular-editor-placeholder{display:block}.angular-editor .angular-editor-wrapper.disabled{cursor:not-allowed;opacity:.5;pointer-events:none}\n"], dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: AeToolbarComponent, selector: "angular-editor-toolbar, ae-toolbar, div[aeToolbar]", inputs: ["id", "uploadUrl", "upload", "showToolbar", "fonts", "customClasses", "defaultFontName", "defaultFontSize", "hiddenButtons"], outputs: ["execute"] }], encapsulation: i0.ViewEncapsulation.None });
1483
+ ], queries: [{ propertyName: "customButtonsTemplateRef", first: true, predicate: ["customButtons"], descendants: true }], viewQueries: [{ propertyName: "textArea", first: true, predicate: ["editor"], descendants: true, static: true }, { propertyName: "editorWrapper", first: true, predicate: ["editorWrapper"], descendants: true, static: true }, { propertyName: "editorToolbar", first: true, predicate: ["editorToolbar"], descendants: true }], ngImport: i0, template: "<div\n class=\"angular-editor\"\n #angularEditor\n [style.width]=\"config.width\"\n [style.minWidth]=\"config.minWidth\"\n [ngClass]=\"{\n 'bottom': config.toolbarPosition === 'bottom'\n }\"\n>\n <angular-editor-toolbar\n #editorToolbar\n [id]=\"id\"\n [uploadUrl]=\"config.uploadUrl || ''\"\n [upload]=\"$any(config.upload)\"\n [showToolbar]=\"config.showToolbar !== undefined ? config.showToolbar : true\"\n [fonts]=\"getFonts()\"\n [customClasses]=\"config.customClasses || []\"\n [defaultFontName]=\"config.defaultFontName || ''\"\n [defaultFontSize]=\"config.defaultFontSize || ''\"\n [hiddenButtons]=\"config.toolbarHiddenButtons || []\"\n (execute)=\"executeCommand($event)\"\n >\n <ng-container\n [ngTemplateOutlet]=\"customButtonsTemplateRef\"\n [ngTemplateOutletContext]=\"{ executeCommandFn: this.executeCommandFn}\"\n >\n </ng-container>\n </angular-editor-toolbar>\n\n <div\n class=\"angular-editor-wrapper\"\n #editorWrapper\n >\n <div\n #editor\n class=\"angular-editor-textarea\"\n [attr.contenteditable]=\"config.editable\"\n [attr.tabindex]=\"disabled ? -1 : tabIndex\"\n [attr.translate]=\"config.translate\"\n [attr.spellcheck]=\"config.spellcheck\"\n [attr.dir]=\"config.textDirection\"\n [style.height]=\"config.height\"\n [style.minHeight]=\"config.minHeight\"\n [style.maxHeight]=\"config.maxHeight\"\n [style.outline]=\"config.outline === false ? 'none': undefined\"\n (input)=\"onContentChange($any($event.target))\"\n (focus)=\"onTextAreaFocus($event)\"\n (blur)=\"onTextAreaBlur($event)\"\n (click)=\"exec()\"\n (keyup)=\"exec()\"\n (mouseout)=\"onTextAreaMouseOut($event)\"\n (paste)=\"onPaste($event)\"\n >\n </div>\n <span class=\"angular-editor-placeholder\">{{ placeholder || config['placeholder'] }}</span>\n </div>\n</div>\n", styles: ["a{cursor:pointer}.angular-editor{display:flex;flex-direction:column;gap:var(--ae-gap, 5px)}.angular-editor.bottom{flex-direction:column-reverse}.angular-editor ::ng-deep [contenteditable=true]:empty:before{content:attr(placeholder);color:#868e96;opacity:1}.angular-editor .angular-editor-wrapper{position:relative}.angular-editor .angular-editor-wrapper .angular-editor-textarea{min-height:150px;overflow:auto;resize:vertical}.angular-editor .angular-editor-wrapper .angular-editor-textarea:after{content:\"\";position:absolute;bottom:0;right:0;display:block;width:8px;height:8px;cursor:nwse-resize;background-color:#ffffff80}.angular-editor .angular-editor-wrapper .angular-editor-textarea{min-height:5rem;padding:.5rem .8rem 1rem;border-radius:var(--ae-text-area-border-radius, .3rem);border:var(--ae-text-area-border, 1px solid #ddd);background-color:transparent;overflow-x:hidden;overflow-y:auto;position:relative}.angular-editor .angular-editor-wrapper .angular-editor-textarea:focus,.angular-editor .angular-editor-wrapper .angular-editor-textarea.focus{outline:var(--ae-focus-outline-color, -webkit-focus-ring-color auto 1px)}.angular-editor .angular-editor-wrapper .angular-editor-textarea ::ng-deep blockquote{margin-left:1rem;border-left:.2em solid #dfe2e5;padding-left:.5rem}.angular-editor .angular-editor-wrapper ::ng-deep p{margin-bottom:0}.angular-editor .angular-editor-wrapper .angular-editor-placeholder{display:none;position:absolute;top:0;padding:.6rem .8rem 1rem .9rem;color:#6c757d;opacity:.75}.angular-editor .angular-editor-wrapper.show-placeholder .angular-editor-placeholder{display:block}.angular-editor .angular-editor-wrapper.disabled{cursor:not-allowed;opacity:.5;pointer-events:none}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: AeToolbarComponent, selector: "angular-editor-toolbar, ae-toolbar, div[aeToolbar]", inputs: ["id", "uploadUrl", "upload", "showToolbar", "fonts", "customClasses", "defaultFontName", "defaultFontSize", "hiddenButtons"], outputs: ["execute"] }], encapsulation: i0.ViewEncapsulation.None });
1300
1484
  }
1301
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: AngularEditorComponent, decorators: [{
1485
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: AngularEditorComponent, decorators: [{
1302
1486
  type: Component,
1303
1487
  args: [{ selector: 'angular-editor', encapsulation: ViewEncapsulation.None, providers: [
1304
1488
  {
@@ -1307,11 +1491,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.13", ngImpo
1307
1491
  multi: true
1308
1492
  },
1309
1493
  AngularEditorService
1310
- ], standalone: false, template: "<div\n class=\"angular-editor\"\n #angularEditor\n [style.width]=\"config.width\"\n [style.minWidth]=\"config.minWidth\"\n [ngClass]=\"{\n 'bottom': config.toolbarPosition === 'bottom'\n }\"\n>\n <angular-editor-toolbar\n #editorToolbar\n [id]=\"id\"\n [uploadUrl]=\"config.uploadUrl\"\n [upload]=\"config.upload\"\n [showToolbar]=\"config.showToolbar !== undefined ? config.showToolbar : true\"\n [fonts]=\"getFonts()\"\n [customClasses]=\"config.customClasses\"\n [defaultFontName]=\"config.defaultFontName\"\n [defaultFontSize]=\"config.defaultFontSize\"\n [hiddenButtons]=\"config.toolbarHiddenButtons\"\n (execute)=\"executeCommand($event)\"\n >\n <ng-container\n [ngTemplateOutlet]=\"customButtonsTemplateRef\"\n [ngTemplateOutletContext]=\"{ executeCommandFn: this.executeCommandFn}\"\n >\n </ng-container>\n </angular-editor-toolbar>\n\n <div\n class=\"angular-editor-wrapper\"\n #editorWrapper\n >\n <div\n #editor\n class=\"angular-editor-textarea\"\n [attr.contenteditable]=\"config.editable\"\n [attr.tabindex]=\"disabled ? -1 : tabIndex\"\n [attr.translate]=\"config.translate\"\n [attr.spellcheck]=\"config.spellcheck\"\n [style.height]=\"config.height\"\n [style.minHeight]=\"config.minHeight\"\n [style.maxHeight]=\"config.maxHeight\"\n [style.outline]=\"config.outline === false ? 'none': undefined\"\n (input)=\"onContentChange($any($event.target))\"\n (focus)=\"onTextAreaFocus($event)\"\n (blur)=\"onTextAreaBlur($event)\"\n (click)=\"exec()\"\n (keyup)=\"exec()\"\n (mouseout)=\"onTextAreaMouseOut($event)\"\n (paste)=\"onPaste($event)\"\n >\n </div>\n <span class=\"angular-editor-placeholder\">{{ placeholder || config['placeholder'] }}</span>\n </div>\n</div>\n", styles: ["a{cursor:pointer}.angular-editor{display:flex;flex-direction:column;gap:var(--ae-gap, 5px)}.angular-editor.bottom{flex-direction:column-reverse}.angular-editor ::ng-deep [contenteditable=true]:empty:before{content:attr(placeholder);color:#868e96;opacity:1}.angular-editor .angular-editor-wrapper{position:relative}.angular-editor .angular-editor-wrapper .angular-editor-textarea{min-height:150px;overflow:auto;resize:vertical}.angular-editor .angular-editor-wrapper .angular-editor-textarea:after{content:\"\";position:absolute;bottom:0;right:0;display:block;width:8px;height:8px;cursor:nwse-resize;background-color:#ffffff80}.angular-editor .angular-editor-wrapper .angular-editor-textarea{min-height:5rem;padding:.5rem .8rem 1rem;border-radius:var(--ae-text-area-border-radius, .3rem);border:var(--ae-text-area-border, 1px solid #ddd);background-color:transparent;overflow-x:hidden;overflow-y:auto;position:relative}.angular-editor .angular-editor-wrapper .angular-editor-textarea:focus,.angular-editor .angular-editor-wrapper .angular-editor-textarea.focus{outline:var(--ae-focus-outline-color, -webkit-focus-ring-color auto 1px)}.angular-editor .angular-editor-wrapper .angular-editor-textarea ::ng-deep blockquote{margin-left:1rem;border-left:.2em solid #dfe2e5;padding-left:.5rem}.angular-editor .angular-editor-wrapper ::ng-deep p{margin-bottom:0}.angular-editor .angular-editor-wrapper .angular-editor-placeholder{display:none;position:absolute;top:0;padding:.6rem .8rem 1rem .9rem;color:#6c757d;opacity:.75}.angular-editor .angular-editor-wrapper.show-placeholder .angular-editor-placeholder{display:block}.angular-editor .angular-editor-wrapper.disabled{cursor:not-allowed;opacity:.5;pointer-events:none}\n"] }]
1311
- }], ctorParameters: () => [{ type: i0.Renderer2 }, { type: AngularEditorService }, { type: undefined, decorators: [{
1312
- type: Inject,
1313
- args: [DOCUMENT]
1314
- }] }, { type: i2.DomSanitizer }, { type: i0.ChangeDetectorRef }, { type: undefined, decorators: [{
1494
+ ], standalone: false, template: "<div\n class=\"angular-editor\"\n #angularEditor\n [style.width]=\"config.width\"\n [style.minWidth]=\"config.minWidth\"\n [ngClass]=\"{\n 'bottom': config.toolbarPosition === 'bottom'\n }\"\n>\n <angular-editor-toolbar\n #editorToolbar\n [id]=\"id\"\n [uploadUrl]=\"config.uploadUrl || ''\"\n [upload]=\"$any(config.upload)\"\n [showToolbar]=\"config.showToolbar !== undefined ? config.showToolbar : true\"\n [fonts]=\"getFonts()\"\n [customClasses]=\"config.customClasses || []\"\n [defaultFontName]=\"config.defaultFontName || ''\"\n [defaultFontSize]=\"config.defaultFontSize || ''\"\n [hiddenButtons]=\"config.toolbarHiddenButtons || []\"\n (execute)=\"executeCommand($event)\"\n >\n <ng-container\n [ngTemplateOutlet]=\"customButtonsTemplateRef\"\n [ngTemplateOutletContext]=\"{ executeCommandFn: this.executeCommandFn}\"\n >\n </ng-container>\n </angular-editor-toolbar>\n\n <div\n class=\"angular-editor-wrapper\"\n #editorWrapper\n >\n <div\n #editor\n class=\"angular-editor-textarea\"\n [attr.contenteditable]=\"config.editable\"\n [attr.tabindex]=\"disabled ? -1 : tabIndex\"\n [attr.translate]=\"config.translate\"\n [attr.spellcheck]=\"config.spellcheck\"\n [attr.dir]=\"config.textDirection\"\n [style.height]=\"config.height\"\n [style.minHeight]=\"config.minHeight\"\n [style.maxHeight]=\"config.maxHeight\"\n [style.outline]=\"config.outline === false ? 'none': undefined\"\n (input)=\"onContentChange($any($event.target))\"\n (focus)=\"onTextAreaFocus($event)\"\n (blur)=\"onTextAreaBlur($event)\"\n (click)=\"exec()\"\n (keyup)=\"exec()\"\n (mouseout)=\"onTextAreaMouseOut($event)\"\n (paste)=\"onPaste($event)\"\n >\n </div>\n <span class=\"angular-editor-placeholder\">{{ placeholder || config['placeholder'] }}</span>\n </div>\n</div>\n", styles: ["a{cursor:pointer}.angular-editor{display:flex;flex-direction:column;gap:var(--ae-gap, 5px)}.angular-editor.bottom{flex-direction:column-reverse}.angular-editor ::ng-deep [contenteditable=true]:empty:before{content:attr(placeholder);color:#868e96;opacity:1}.angular-editor .angular-editor-wrapper{position:relative}.angular-editor .angular-editor-wrapper .angular-editor-textarea{min-height:150px;overflow:auto;resize:vertical}.angular-editor .angular-editor-wrapper .angular-editor-textarea:after{content:\"\";position:absolute;bottom:0;right:0;display:block;width:8px;height:8px;cursor:nwse-resize;background-color:#ffffff80}.angular-editor .angular-editor-wrapper .angular-editor-textarea{min-height:5rem;padding:.5rem .8rem 1rem;border-radius:var(--ae-text-area-border-radius, .3rem);border:var(--ae-text-area-border, 1px solid #ddd);background-color:transparent;overflow-x:hidden;overflow-y:auto;position:relative}.angular-editor .angular-editor-wrapper .angular-editor-textarea:focus,.angular-editor .angular-editor-wrapper .angular-editor-textarea.focus{outline:var(--ae-focus-outline-color, -webkit-focus-ring-color auto 1px)}.angular-editor .angular-editor-wrapper .angular-editor-textarea ::ng-deep blockquote{margin-left:1rem;border-left:.2em solid #dfe2e5;padding-left:.5rem}.angular-editor .angular-editor-wrapper ::ng-deep p{margin-bottom:0}.angular-editor .angular-editor-wrapper .angular-editor-placeholder{display:none;position:absolute;top:0;padding:.6rem .8rem 1rem .9rem;color:#6c757d;opacity:.75}.angular-editor .angular-editor-wrapper.show-placeholder .angular-editor-placeholder{display:block}.angular-editor .angular-editor-wrapper.disabled{cursor:not-allowed;opacity:.5;pointer-events:none}\n"] }]
1495
+ }], ctorParameters: () => [{ type: undefined, decorators: [{
1315
1496
  type: Attribute,
1316
1497
  args: ['tabindex']
1317
1498
  }] }, { type: undefined, decorators: [{
@@ -1356,11 +1537,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.13", ngImpo
1356
1537
  }] } });
1357
1538
 
1358
1539
  class AngularEditorModule {
1359
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: AngularEditorModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1360
- static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.13", ngImport: i0, type: AngularEditorModule, declarations: [AngularEditorComponent, AeToolbarComponent, AeSelectComponent, AeButtonComponent, AeToolbarSetComponent], imports: [CommonModule, FormsModule, ReactiveFormsModule], exports: [AngularEditorComponent, AeToolbarComponent, AeButtonComponent, AeToolbarSetComponent] });
1361
- static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: AngularEditorModule, imports: [CommonModule, FormsModule, ReactiveFormsModule] });
1540
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: AngularEditorModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1541
+ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.0.7", ngImport: i0, type: AngularEditorModule, declarations: [AngularEditorComponent, AeToolbarComponent, AeSelectComponent, AeButtonComponent, AeToolbarSetComponent], imports: [CommonModule, FormsModule, ReactiveFormsModule], exports: [AngularEditorComponent, AeToolbarComponent, AeButtonComponent, AeToolbarSetComponent] });
1542
+ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: AngularEditorModule, imports: [CommonModule, FormsModule, ReactiveFormsModule] });
1362
1543
  }
1363
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: AngularEditorModule, decorators: [{
1544
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: AngularEditorModule, decorators: [{
1364
1545
  type: NgModule,
1365
1546
  args: [{
1366
1547
  imports: [