@firestitch/html-editor 12.7.4 → 12.7.5

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.
Files changed (51) hide show
  1. package/app/modules/html-editor/classes/plugin.d.ts +7 -7
  2. package/app/modules/html-editor/components/html-editor/html-editor.component.d.ts +58 -58
  3. package/app/modules/html-editor/consts/paragraph-buttons.const.d.ts +1 -1
  4. package/app/modules/html-editor/consts/rich-buttons.const.d.ts +1 -1
  5. package/app/modules/html-editor/consts/text-buttons.const.d.ts +1 -1
  6. package/app/modules/html-editor/enums/default-plugin.enum.d.ts +16 -16
  7. package/app/modules/html-editor/fs-html-editor.module.d.ts +43 -43
  8. package/app/modules/html-editor/injects/config.inject.d.ts +3 -3
  9. package/app/modules/html-editor/interfaces/html-editor-config.d.ts +40 -40
  10. package/app/modules/html-editor/interfaces/plugin-button.d.ts +12 -12
  11. package/app/modules/html-editor/interfaces/plugin-config.d.ts +5 -5
  12. package/app/modules/html-editor/plugins/checklist.plugin.d.ts +7 -7
  13. package/app/modules/html-editor/plugins/code.plugin.d.ts +9 -9
  14. package/app/modules/html-editor/plugins/configs/mention-plugin.config.d.ts +13 -13
  15. package/app/modules/html-editor/plugins/configs/screen-record-plugin.config.d.ts +7 -7
  16. package/app/modules/html-editor/plugins/mention.plugin.d.ts +15 -15
  17. package/app/modules/html-editor/plugins/realtime.plugin.d.ts +7 -7
  18. package/app/modules/html-editor/plugins/screen-record.plugin.d.ts +11 -11
  19. package/app/modules/html-editor/services/froala-loader.service.d.ts +21 -21
  20. package/app/modules/html-renderer/components/html-renderer/html-renderer.component.d.ts +12 -12
  21. package/app/modules/html-renderer/fs-html-renderer.module.d.ts +8 -8
  22. package/bundles/firestitch-html-editor.umd.js +1354 -1341
  23. package/bundles/firestitch-html-editor.umd.js.map +1 -1
  24. package/esm2015/app/modules/html-editor/classes/plugin.js +4 -4
  25. package/esm2015/app/modules/html-editor/components/html-editor/html-editor.component.js +480 -467
  26. package/esm2015/app/modules/html-editor/consts/paragraph-buttons.const.js +9 -9
  27. package/esm2015/app/modules/html-editor/consts/rich-buttons.const.js +6 -6
  28. package/esm2015/app/modules/html-editor/consts/text-buttons.const.js +18 -18
  29. package/esm2015/app/modules/html-editor/enums/default-plugin.enum.js +1 -1
  30. package/esm2015/app/modules/html-editor/fs-html-editor.module.js +69 -69
  31. package/esm2015/app/modules/html-editor/injects/config.inject.js +3 -3
  32. package/esm2015/app/modules/html-editor/interfaces/html-editor-config.js +1 -1
  33. package/esm2015/app/modules/html-editor/interfaces/plugin-button.js +1 -1
  34. package/esm2015/app/modules/html-editor/interfaces/plugin-config.js +1 -1
  35. package/esm2015/app/modules/html-editor/plugins/checklist.plugin.js +34 -34
  36. package/esm2015/app/modules/html-editor/plugins/code.plugin.js +62 -62
  37. package/esm2015/app/modules/html-editor/plugins/configs/mention-plugin.config.js +1 -1
  38. package/esm2015/app/modules/html-editor/plugins/configs/screen-record-plugin.config.js +1 -1
  39. package/esm2015/app/modules/html-editor/plugins/mention.plugin.js +86 -86
  40. package/esm2015/app/modules/html-editor/plugins/realtime.plugin.js +12 -12
  41. package/esm2015/app/modules/html-editor/plugins/screen-record.plugin.js +88 -88
  42. package/esm2015/app/modules/html-editor/services/froala-loader.service.js +89 -89
  43. package/esm2015/app/modules/html-renderer/components/html-renderer/html-renderer.component.js +28 -28
  44. package/esm2015/app/modules/html-renderer/fs-html-renderer.module.js +25 -25
  45. package/esm2015/firestitch-html-editor.js +4 -4
  46. package/esm2015/public_api.js +13 -13
  47. package/fesm2015/firestitch-html-editor.js +957 -944
  48. package/fesm2015/firestitch-html-editor.js.map +1 -1
  49. package/firestitch-html-editor.d.ts +5 -5
  50. package/package.json +1 -1
  51. package/public_api.d.ts +18 -18
@@ -1,988 +1,1001 @@
1
- import * as i0 from '@angular/core';
2
- import { InjectionToken, Injectable, Optional, Inject, forwardRef, Component, ChangeDetectionStrategy, HostBinding, ViewChild, Input, NgModule } from '@angular/core';
3
1
  import * as i3 from '@angular/common';
4
- import { DOCUMENT, CommonModule } from '@angular/common';
2
+ import { CommonModule, DOCUMENT } from '@angular/common';
3
+ import * as i0 from '@angular/core';
4
+ import { Component, ChangeDetectionStrategy, Input, NgModule, InjectionToken, Injectable, Optional, Inject, forwardRef, HostBinding, ViewChild } from '@angular/core';
5
5
  import * as i2 from '@firestitch/label';
6
6
  import { FsLabelModule } from '@firestitch/label';
7
7
  import * as i4 from '@firestitch/skeleton';
8
8
  import { FsSkeletonModule } from '@firestitch/skeleton';
9
- import { NG_VALUE_ACCESSOR, NG_VALIDATORS } from '@angular/forms';
9
+ import * as i1 from '@angular/platform-browser';
10
+ import { NG_VALUE_ACCESSOR, NG_VALIDATORS, ControlContainer, NgForm } from '@angular/forms';
10
11
  import { fsSourceLoader, guid } from '@firestitch/common';
11
12
  import { FileProcessor, FsFile } from '@firestitch/file';
12
13
  import { BehaviorSubject, combineLatest, ReplaySubject, Subject, fromEventPattern } from 'rxjs';
13
14
  import { map, shareReplay, tap, concatMap, switchMap, filter, startWith, distinctUntilChanged, skip, takeUntil } from 'rxjs/operators';
14
15
  import { merge, debounce } from 'lodash-es';
15
- import * as i1 from '@angular/platform-browser';
16
16
  import Tribute from 'tributejs';
17
17
  import { __awaiter } from 'tslib';
18
18
 
19
- const RichButtons = [
20
- 'insertTable',
21
- 'insertImage',
22
- 'insertLink',
23
- 'insertVideo',
19
+ class FsHtmlRendererComponent {
20
+ constructor(sanitized, _cdRef) {
21
+ this.sanitized = sanitized;
22
+ this._cdRef = _cdRef;
23
+ }
24
+ set setHtml(html) {
25
+ this.trustedHtml = this.sanitized.bypassSecurityTrustHtml(html || '');
26
+ this._cdRef.markForCheck();
27
+ }
28
+ }
29
+ FsHtmlRendererComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsHtmlRendererComponent, deps: [{ token: i1.DomSanitizer }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
30
+ FsHtmlRendererComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.16", type: FsHtmlRendererComponent, selector: "fs-html-renderer", inputs: { setHtml: ["html", "setHtml"] }, ngImport: i0, template: "<span class=\"fr-view fs-html-editor-default\" [innerHtml]=\"trustedHtml\"></span>\n", styles: [""], changeDetection: i0.ChangeDetectionStrategy.OnPush });
31
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsHtmlRendererComponent, decorators: [{
32
+ type: Component,
33
+ args: [{
34
+ selector: 'fs-html-renderer',
35
+ templateUrl: 'html-renderer.component.html',
36
+ styleUrls: ['html-renderer.component.scss'],
37
+ changeDetection: ChangeDetectionStrategy.OnPush,
38
+ }]
39
+ }], ctorParameters: function () { return [{ type: i1.DomSanitizer }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { setHtml: [{
40
+ type: Input,
41
+ args: ['html']
42
+ }] } });
43
+
44
+ class FsHtmlRendererModule {
45
+ }
46
+ FsHtmlRendererModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsHtmlRendererModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
47
+ FsHtmlRendererModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsHtmlRendererModule, declarations: [FsHtmlRendererComponent], imports: [CommonModule], exports: [FsHtmlRendererComponent] });
48
+ FsHtmlRendererModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsHtmlRendererModule, imports: [[
49
+ CommonModule,
50
+ ]] });
51
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsHtmlRendererModule, decorators: [{
52
+ type: NgModule,
53
+ args: [{
54
+ imports: [
55
+ CommonModule,
56
+ ],
57
+ exports: [
58
+ FsHtmlRendererComponent,
59
+ ],
60
+ declarations: [
61
+ FsHtmlRendererComponent,
62
+ ],
63
+ }]
64
+ }] });
65
+
66
+ const ParagraphButtons = [
67
+ 'align',
68
+ 'formatOL',
69
+ 'formatUL',
70
+ 'checklist',
71
+ 'indent',
72
+ 'outdent',
73
+ 'lineHeight'
24
74
  ];
25
75
 
26
- const TextButtons = [
27
- 'paragraphFormat',
28
- 'code',
29
- 'bold',
30
- 'italic',
31
- 'underline',
32
- 'strikeThrough',
33
- 'subscript',
34
- 'superscript',
35
- 'fontFamily',
36
- 'fontSize',
37
- 'textColor',
38
- 'backgroundColor',
39
- 'inlineClass',
40
- 'inlineStyle',
41
- 'clearFormatting',
42
- 'quote',
76
+ const RichButtons = [
77
+ 'insertTable',
78
+ 'insertImage',
79
+ 'insertLink',
80
+ 'insertVideo',
43
81
  ];
44
82
 
45
- const ParagraphButtons = [
46
- 'align',
47
- 'formatOL',
48
- 'formatUL',
49
- 'checklist',
50
- 'indent',
51
- 'outdent',
52
- 'lineHeight'
83
+ const TextButtons = [
84
+ 'paragraphFormat',
85
+ 'code',
86
+ 'bold',
87
+ 'italic',
88
+ 'underline',
89
+ 'strikeThrough',
90
+ 'subscript',
91
+ 'superscript',
92
+ 'fontFamily',
93
+ 'fontSize',
94
+ 'textColor',
95
+ 'backgroundColor',
96
+ 'inlineClass',
97
+ 'inlineStyle',
98
+ 'clearFormatting',
99
+ 'quote',
53
100
  ];
54
101
 
55
- const FS_HTML_EDITOR_DEFAULT_CONFIG = new InjectionToken('fs-html-editor.default-config');
102
+ const FS_HTML_EDITOR_DEFAULT_CONFIG = new InjectionToken('fs-html-editor.default-config');
56
103
  const FS_HTML_EDITOR_CONFIG = new InjectionToken('fs-html-editor.config');
57
104
 
58
- class FsFroalaLoaderService {
59
- constructor(_defaultConfig, _document) {
60
- this._defaultConfig = _defaultConfig;
61
- this._document = _document;
62
- this._froalaLoaded = new BehaviorSubject(false);
63
- this._froalaPluginsLoaded = new BehaviorSubject(false);
64
- this._sourceLoader = fsSourceLoader;
65
- this._loaded$ = combineLatest([this._froalaLoaded, this._froalaPluginsLoaded])
66
- .pipe(map(([FroalaReady, pluginsRead]) => {
67
- return pluginsRead && FroalaReady;
68
- }), shareReplay(1));
69
- this._sourceLoader.setDocument(this._document);
70
- this._load();
71
- }
72
- get loaded$() {
73
- return this._loaded$;
74
- }
75
- get FroalaEditor() {
76
- return this._FroalaEditor;
77
- }
78
- _load() {
79
- const baseDir = '/assets/froala/';
80
- this._sourceLoader.registerResources({
81
- froala: [
82
- `${baseDir}js/froala_editor.min.js`,
83
- `${baseDir}css/froala_editor.pkgd.min.css`,
84
- ],
85
- froala_align: `${baseDir}js/plugins/align.min.js`,
86
- froala_colors: `${baseDir}js/plugins/colors.min.js`,
87
- froala_image: `${baseDir}js/plugins/image.min.js`,
88
- froala_link: `${baseDir}js/plugins/link.min.js`,
89
- froala_lists: `${baseDir}js/plugins/lists.min.js`,
90
- froala_paragraph_format: `${baseDir}js/plugins/paragraph_format.min.js`,
91
- froala_table: `${baseDir}js/plugins/table.min.js`,
92
- froala_url: `${baseDir}js/plugins/url.min.js`,
93
- froala_video: `${baseDir}js/plugins/video.min.js`,
94
- froala_quote: `${baseDir}js/plugins/quote.min.js`,
95
- froala_draggable: `${baseDir}js/plugins/draggable.min.js`,
96
- froala_font_size: `${baseDir}js/plugins/font_size.min.js`,
97
- froala_quick_insert: `${baseDir}js/plugins/quick_insert.min.js`,
98
- froala_line_height: `${baseDir}js/plugins/line_height.min.js`
99
- });
100
- this._sourceLoader.loadResource('froala')
101
- .pipe(tap(() => {
102
- this._FroalaEditor = window.FroalaEditor;
103
- this._froalaDone();
104
- }), concatMap(() => {
105
- return this._loadPlugins();
106
- }), tap(() => {
107
- this._froalaPluginsDone();
108
- }))
109
- .subscribe();
110
- }
111
- _loadPlugins() {
112
- const resources = this._defaultConfig
113
- .froalaPlugins
114
- .map((pluginName) => `froala_${pluginName}`);
115
- return this._sourceLoader.loadResources(resources);
116
- }
117
- _froalaDone() {
118
- this._froalaLoaded.next(true);
119
- }
120
- _froalaPluginsDone() {
121
- this._froalaPluginsLoaded.next(true);
122
- }
123
- }
124
- FsFroalaLoaderService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsFroalaLoaderService, deps: [{ token: FS_HTML_EDITOR_CONFIG, optional: true }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Injectable });
125
- FsFroalaLoaderService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsFroalaLoaderService, providedIn: 'root' });
126
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsFroalaLoaderService, decorators: [{
127
- type: Injectable,
128
- args: [{
129
- providedIn: 'root',
130
- }]
131
- }], ctorParameters: function () { return [{ type: undefined, decorators: [{
132
- type: Optional
133
- }, {
134
- type: Inject,
135
- args: [FS_HTML_EDITOR_CONFIG]
136
- }] }, { type: Document, decorators: [{
137
- type: Inject,
138
- args: [DOCUMENT]
105
+ class FsFroalaLoaderService {
106
+ constructor(_defaultConfig, _document) {
107
+ this._defaultConfig = _defaultConfig;
108
+ this._document = _document;
109
+ this._froalaLoaded = new BehaviorSubject(false);
110
+ this._froalaPluginsLoaded = new BehaviorSubject(false);
111
+ this._sourceLoader = fsSourceLoader;
112
+ this._loaded$ = combineLatest([this._froalaLoaded, this._froalaPluginsLoaded])
113
+ .pipe(map(([FroalaReady, pluginsRead]) => {
114
+ return pluginsRead && FroalaReady;
115
+ }), shareReplay(1));
116
+ this._sourceLoader.setDocument(this._document);
117
+ this._load();
118
+ }
119
+ get loaded$() {
120
+ return this._loaded$;
121
+ }
122
+ get FroalaEditor() {
123
+ return this._FroalaEditor;
124
+ }
125
+ _load() {
126
+ const baseDir = '/assets/froala/';
127
+ this._sourceLoader.registerResources({
128
+ froala: [
129
+ `${baseDir}js/froala_editor.min.js`,
130
+ `${baseDir}css/froala_editor.pkgd.min.css`,
131
+ ],
132
+ froala_align: `${baseDir}js/plugins/align.min.js`,
133
+ froala_colors: `${baseDir}js/plugins/colors.min.js`,
134
+ froala_image: `${baseDir}js/plugins/image.min.js`,
135
+ froala_link: `${baseDir}js/plugins/link.min.js`,
136
+ froala_lists: `${baseDir}js/plugins/lists.min.js`,
137
+ froala_paragraph_format: `${baseDir}js/plugins/paragraph_format.min.js`,
138
+ froala_table: `${baseDir}js/plugins/table.min.js`,
139
+ froala_url: `${baseDir}js/plugins/url.min.js`,
140
+ froala_video: `${baseDir}js/plugins/video.min.js`,
141
+ froala_quote: `${baseDir}js/plugins/quote.min.js`,
142
+ froala_draggable: `${baseDir}js/plugins/draggable.min.js`,
143
+ froala_font_size: `${baseDir}js/plugins/font_size.min.js`,
144
+ froala_quick_insert: `${baseDir}js/plugins/quick_insert.min.js`,
145
+ froala_line_height: `${baseDir}js/plugins/line_height.min.js`
146
+ });
147
+ this._sourceLoader.loadResource('froala')
148
+ .pipe(tap(() => {
149
+ this._FroalaEditor = window.FroalaEditor;
150
+ this._froalaDone();
151
+ }), concatMap(() => {
152
+ return this._loadPlugins();
153
+ }), tap(() => {
154
+ this._froalaPluginsDone();
155
+ }))
156
+ .subscribe();
157
+ }
158
+ _loadPlugins() {
159
+ const resources = this._defaultConfig
160
+ .froalaPlugins
161
+ .map((pluginName) => `froala_${pluginName}`);
162
+ return this._sourceLoader.loadResources(resources);
163
+ }
164
+ _froalaDone() {
165
+ this._froalaLoaded.next(true);
166
+ }
167
+ _froalaPluginsDone() {
168
+ this._froalaPluginsLoaded.next(true);
169
+ }
170
+ }
171
+ FsFroalaLoaderService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsFroalaLoaderService, deps: [{ token: FS_HTML_EDITOR_CONFIG, optional: true }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Injectable });
172
+ FsFroalaLoaderService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsFroalaLoaderService, providedIn: 'root' });
173
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsFroalaLoaderService, decorators: [{
174
+ type: Injectable,
175
+ args: [{
176
+ providedIn: 'root',
177
+ }]
178
+ }], ctorParameters: function () { return [{ type: undefined, decorators: [{
179
+ type: Optional
180
+ }, {
181
+ type: Inject,
182
+ args: [FS_HTML_EDITOR_CONFIG]
183
+ }] }, { type: Document, decorators: [{
184
+ type: Inject,
185
+ args: [DOCUMENT]
139
186
  }] }]; } });
140
187
 
141
- class FsHtmlEditorComponent {
142
- constructor(_defaultConfig, _cdRef, _fr) {
143
- this._defaultConfig = _defaultConfig;
144
- this._cdRef = _cdRef;
145
- this._fr = _fr;
146
- this.classFocused = false;
147
- this.config = {};
148
- this.disabled = false;
149
- this.initialized = false;
150
- this.containerID = `fs-html-editor-${guid('xxx')}`;
151
- this._initialize$ = new ReplaySubject();
152
- this._froalaReady$ = new BehaviorSubject(null);
153
- this._destroy$ = new Subject();
154
- this.onChange = (data) => { };
155
- this.onTouched = () => { };
156
- }
157
- get el() {
158
- return this.elRef.nativeElement;
159
- }
160
- get html() {
161
- return this._html;
162
- }
163
- get editor() {
164
- return this._editor;
165
- }
166
- get froalaLoaded$() {
167
- return this._fr.loaded$;
168
- }
169
- ngOnInit() {
170
- this.config = this.config || {};
171
- this.config.autofocus = this.config.autofocus !== false && (!this.config.disabled || !this.disabled);
172
- this._listenLazyInit();
173
- }
174
- ngAfterViewInit() {
175
- this._initialize$.next();
176
- }
177
- hasContent() {
178
- const el = document.createElement('div');
179
- if (el.querySelector('img')) {
180
- return true;
181
- }
182
- el.innerHTML = this._html;
183
- return !!el.innerText.length;
184
- }
185
- initialize(options = {}) {
186
- const config = this._createConfig();
187
- this._initPlugins(config);
188
- this._initButtons(config);
189
- this._editor = new this._fr.FroalaEditor(this.el, this._createOptions(), () => {
190
- this._froalaReady$.next({ config, options });
191
- });
192
- }
193
- _processImageUpload(blob) {
194
- const processor = new FileProcessor();
195
- const file = new FsFile(blob);
196
- const config = {
197
- orientate: true,
198
- quality: this.config.image.quality,
199
- format: this.config.image.format,
200
- maxWidth: this.config.image.width,
201
- maxHeight: this.config.image.height,
202
- minWidth: this.config.image.minWidth,
203
- minHeight: this.config.image.minHeight,
204
- };
205
- return processor.processFile(file, config)
206
- .pipe(switchMap((fsFile) => {
207
- return this.config.image.upload(fsFile.file);
208
- }));
209
- }
210
- updateSize() {
211
- // Hack: To trigger the toolbar button size modes
212
- window.dispatchEvent(new Event('resize'));
213
- }
214
- validate(control) {
215
- const err = {};
216
- if (this.config.maxLength && this._html) {
217
- const maxLength = this.config.maxLength;
218
- const length = this._html.length;
219
- if (length > maxLength) {
220
- err.maxLengthError = `Must be ${maxLength} characters or fewer. You entered ${length} characters.`;
221
- }
222
- }
223
- return Object.keys(err).length ? err : null;
224
- }
225
- focus(options) {
226
- options = options ? options : {};
227
- if (options.cursorPosition === 'end') {
228
- this.editor.selection.setAtEnd(this.editor.$el.get(0));
229
- }
230
- else {
231
- this.editor.selection.setAtStart(this.editor.$el.get(0));
232
- }
233
- this.editor.selection.restore();
234
- const elSelection = this.editor.selection.element();
235
- if (elSelection) {
236
- elSelection.scrollIntoView({ block: 'center' });
237
- }
238
- }
239
- clear() {
240
- this.writeValue('');
241
- }
242
- disable() {
243
- this.disabled = true;
244
- }
245
- setHtml(html) {
246
- this.writeValue(html);
247
- }
248
- writeValue(html) {
249
- this._html = html || '';
250
- if (Array.isArray(this._html)) {
251
- this._html = this._html.pop();
252
- }
253
- this._html = this._html
254
- .replace(/<(li)>\s?<(div)>/g, '<li>')
255
- .replace(/<\/(div)><\/(li)>/g, '</li>');
256
- if (this.editor && this.editor.html) {
257
- try {
258
- this.editor.html.set(this._html);
259
- }
260
- catch (e) {
261
- }
262
- }
263
- this._cdRef.markForCheck();
264
- }
265
- registerOnChange(fn) {
266
- this.onChange = fn;
267
- }
268
- registerOnTouched(fn) {
269
- this.onTouched = fn;
270
- }
271
- ngOnDestroy() {
272
- this._initialize$.complete();
273
- this._destroy$.next();
274
- this._destroy$.complete();
275
- this.destroy();
276
- }
277
- destroy() {
278
- if (this.editor) {
279
- this.editor.destroy();
280
- }
281
- this.initialized = false;
282
- this._cdRef.markForCheck();
283
- this.el.innerHTML = '';
284
- }
285
- _createConfig() {
286
- return merge({ froalaConfig: {} }, this._defaultConfig, this.config);
287
- }
288
- _change(html) {
289
- this._html = html;
290
- this.onChange(html);
291
- }
292
- _initButtons(config) {
293
- (config.buttons || [])
294
- .forEach((button) => {
295
- /*
296
- Svg Keys:
297
- ["add", "advancedImageEditor", "alignCenter", "alignJustify", "alignLeft", "alignRight",
298
- "anchors", "back", "backgroundColor", "blockquote", "bold", "cellBackground",
299
- "cellBorderColor", "cellOptions", "cellStyle", "clearFormatting", "close", "codeView",
300
- "cogs", "columns", "editLink", "exitFullscreen", "fontAwesome", "fontFamily",
301
- "fontSize", "fullscreen", "help", "horizontalLine", "imageAltText", "imageCaption",
302
- "imageClass", "imageDisplay", "imageManager", "imageSize", "indent", "inlineClass",
303
- "inlineStyle", "insertEmbed", "insertFile", "insertImage", "insertLink", "insertMore",
304
- "insertTable", "insertVideo", "upload", "italic", "search", "lineHeight", "linkStyles",
305
- "mention", "more", "openLink", "orderedList", "outdent", "pageBreaker",
306
- "paragraphFormat", "paragraphMore", "paragraphStyle", "pdfExport", "print",
307
- "redo", "removeTable", "remove", "replaceImage", "row", "selectAll", "smile",
308
- "spellcheck", "star", "strikeThrough", "subscript", "superscript", "symbols", "tags",
309
- "tableHeader", "tableStyle", "textColor", "textMore", "underline", "undo", "unlink",
310
- "unorderedList", "verticalAlignBottom", "verticalAlignMiddle", "verticalAlignTop"]
311
- */
312
- var _a, _b, _c;
313
- if (button.svgKey) {
314
- this._fr.FroalaEditor.DefineIcon(button.name, { SVG_KEY: button.svgKey });
315
- }
316
- this._fr.FroalaEditor.RegisterCommand(button.name, {
317
- title: button.title,
318
- focus: (_a = button.focus) !== null && _a !== void 0 ? _a : true,
319
- undo: (_b = button.undo) !== null && _b !== void 0 ? _b : true,
320
- refreshAfterCallback: (_c = button.refreshAfterCallback) !== null && _c !== void 0 ? _c : true,
321
- callback: function () {
322
- button.click(this);
323
- }
324
- });
325
- });
326
- }
327
- _initPlugins(config) {
328
- (config.plugins || []).forEach((plugin) => {
329
- this._fr.FroalaEditor.PLUGINS[plugin.config.name] = function (editor) {
330
- plugin.editor = editor;
331
- plugin.initialize();
332
- return plugin;
333
- };
334
- (plugin.config.buttons || []).forEach((button) => {
335
- this._fr.FroalaEditor.DefineIcon(button.name, {
336
- NAME: button.name,
337
- PATH: button.svgPath,
338
- });
339
- this._fr.FroalaEditor.RegisterCommand(button.name, {
340
- icon: button.name,
341
- title: button.tooltip,
342
- undo: button.undo,
343
- focus: button.focus,
344
- showOnMobile: button.showOnMobile,
345
- refreshAfterCallback: button.refreshAfterCallback,
346
- callback: function () {
347
- if (button.click) {
348
- button.click(this);
349
- }
350
- },
351
- refresh: function (button) {
352
- if (button.refresh) {
353
- button.refresh(this, button);
354
- }
355
- }
356
- });
357
- });
358
- });
359
- }
360
- _createOptions() {
361
- var _a, _b;
362
- const config = this._createConfig();
363
- return merge(
364
- // For some reason editor store somewhere pointer on default config object and dublicate options each time on init
365
- // Extra merge level fixed this problem and allow to init config properly without legacy data
366
- {}, {
367
- shortcutsEnabled: ['show', 'bold', 'italic', 'underline', 'indent', 'outdent', 'undo', 'redo', 'insertImage', 'createLink'],
368
- key: config.activationKey,
369
- placeholderText: config.placeholder,
370
- linkAlwaysBlank: true,
371
- tabSpaces: 2,
372
- typingTimer: 250,
373
- tooltips: false,
374
- wordPasteModal: false,
375
- imageDefaultWidth: 0,
376
- imageDefaultAlign: 'left',
377
- quickInsertEnabled: false,
378
- scrollableContainer: `#${this.containerID}`,
379
- paragraphDefaultSelection: 'Format',
380
- videoUpload: false,
381
- imagePaste: !!((_a = config.image) === null || _a === void 0 ? void 0 : _a.upload),
382
- imageUpload: !!((_b = config.image) === null || _b === void 0 ? void 0 : _b.upload),
383
- paragraphFormat: {
384
- N: 'Normal',
385
- H1: 'Heading 1',
386
- H2: 'Heading 2',
387
- H3: 'Heading 3',
388
- H4: 'Heading 4',
389
- BLOCKQUOTE: 'Quote',
390
- },
391
- lineHeights: {
392
- Default: '',
393
- '0.5': '0.5',
394
- 'Single': '1',
395
- '1.15': '1.15',
396
- '1.5': '1.5',
397
- 'Double': '2'
398
- },
399
- paragraphFormatSelection: true,
400
- toolbarButtonsXS: {
401
- moreText: {
402
- buttons: TextButtons,
403
- buttonsVisible: 1,
404
- },
405
- moreParagraph: {
406
- buttons: ParagraphButtons,
407
- buttonsVisible: 2,
408
- },
409
- moreRich: {
410
- buttons: RichButtons,
411
- buttonsVisible: 0,
412
- },
413
- },
414
- toolbarButtons: {
415
- moreText: {
416
- buttons: TextButtons,
417
- buttonsVisible: 3,
418
- },
419
- moreParagraph: {
420
- buttons: ParagraphButtons,
421
- buttonsVisible: 5,
422
- },
423
- moreRich: {
424
- buttons: RichButtons,
425
- buttonsVisible: 3,
426
- },
427
- },
428
- }, config.froalaConfig);
429
- }
430
- _listenLazyInit() {
431
- this.froalaLoaded$
432
- .pipe(filter((ready) => ready), switchMap(() => this._initialize$), tap(() => {
433
- const selection = window.getSelection();
434
- const options = {};
435
- if (selection.baseNode) {
436
- options.selection = {
437
- node: selection.baseNode.nodeValue,
438
- offset: selection.baseOffset,
439
- };
440
- }
441
- this.initialize(options);
442
- }), switchMap(() => this._froalaReady$), filter((data) => !!data), tap(({ config, options }) => {
443
- this._setupFroala(config, options);
444
- }))
445
- .subscribe();
446
- }
447
- _contentChanged() {
448
- const editorHTML = this._editor.html.get();
449
- if (this.html !== editorHTML) {
450
- this._change(editorHTML);
451
- }
452
- }
453
- _setupFroala(config, options) {
454
- this._cdRef.markForCheck();
455
- this.setHtml(this._html);
456
- if (config.disabled) {
457
- this.disable();
458
- }
459
- if (config.froalaConfig.events) {
460
- if (config.froalaConfig.events.initialized) {
461
- config.froalaConfig.events.initialized();
462
- }
463
- }
464
- this._editor.events.on('focus', () => {
465
- this.classFocused = true;
466
- this._cdRef.markForCheck();
467
- });
468
- this._editor.events.on('blur', () => {
469
- this.classFocused = false;
470
- this._cdRef.markForCheck();
471
- });
472
- this._editor.events.on('click', () => {
473
- if (this.config.initOnClick && !this.initialized) {
474
- this.initialized = true;
475
- this._cdRef.markForCheck();
476
- }
477
- });
478
- fromEventPattern((handler) => {
479
- this._editor.events.on('contentChanged', handler);
480
- }, () => { })
481
- .pipe(startWith(this._html), map(() => this.editor.html.get()), distinctUntilChanged(), skip(1))
482
- .subscribe(() => {
483
- this._contentChanged();
484
- });
485
- this._editor.events.on('paste.afterCleanup', (html) => {
486
- var div = document.createElement('div');
487
- div.innerHTML = html;
488
- div.querySelectorAll('*')
489
- .forEach((el) => {
490
- for (var i = 0; i < el.attributes.length; i++) {
491
- const name = el.attributes[0].name;
492
- if (name !== 'href') {
493
- el.removeAttribute(name);
494
- }
495
- }
496
- });
497
- return div.innerHTML;
498
- });
499
- this._editor.events.on('keydown', () => {
500
- this.onTouched();
501
- });
502
- if (this.config.image && this.config.image.upload) {
503
- this._editor.events.on('image.beforePasteUpload', (image) => {
504
- fetch(image.getAttribute('src'))
505
- .then((res) => {
506
- res.blob()
507
- .then((blob) => {
508
- this._processImageUpload(blob)
509
- .pipe(takeUntil(this._destroy$))
510
- .subscribe((url) => {
511
- image.setAttribute('src', url);
512
- image.removeAttribute('data-fr-image-pasted');
513
- this._contentChanged();
514
- });
515
- });
516
- });
517
- return false;
518
- });
519
- this._editor.events.on('image.beforeUpload', (blobs) => {
520
- this._processImageUpload(blobs[0])
521
- .pipe(takeUntil(this._destroy$))
522
- .subscribe((url) => {
523
- this.editor.image.insert(url, null, null, this.editor.image.get());
524
- });
525
- return false;
526
- });
527
- }
528
- if (this.el.querySelector('.fr-second-toolbar')) {
529
- this.el.querySelector('.fr-second-toolbar').remove();
530
- }
531
- if (this.config.autofocus && !this.config.initOnClick) {
532
- this.focus();
533
- }
534
- }
535
- }
536
- FsHtmlEditorComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsHtmlEditorComponent, deps: [{ token: FS_HTML_EDITOR_CONFIG, optional: true }, { token: i0.ChangeDetectorRef }, { token: FsFroalaLoaderService }], target: i0.ɵɵFactoryTarget.Component });
537
- FsHtmlEditorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.16", type: FsHtmlEditorComponent, selector: "fs-html-editor", inputs: { config: "config", hint: "hint", disabled: "disabled" }, host: { properties: { "class.focused": "this.classFocused", "class.disabled": "this.disabled" } }, providers: [
538
- {
539
- provide: NG_VALUE_ACCESSOR,
540
- useExisting: forwardRef(() => FsHtmlEditorComponent),
541
- multi: true
542
- },
543
- {
544
- provide: NG_VALIDATORS,
545
- useExisting: forwardRef(() => FsHtmlEditorComponent),
546
- multi: true
547
- },
548
- ], viewQueries: [{ propertyName: "elRef", first: true, predicate: ["elRef"], descendants: true }], ngImport: i0, template: "<fs-label-field>\n <fs-label *ngIf=\"config.label\">{{config.label}}</fs-label>\n <div\n class=\"html-editor-container fs-html-editor-default\"\n [id]=\"containerID\"\n [ngClass]=\"{\n initialized: initialized,\n 'init-on-click': config.initOnClick\n }\">\n <ng-container *fsSkeleton=\"(froalaLoaded$ | async) !== false\"></ng-container>\n <div #elRef></div>\n\n <div class=\"bottom-line\"></div>\n <div class=\"disabled-line\"></div>\n </div>\n\n <fs-label-message>\n <div class=\"fs-form-message\">\n <div class=\"fs-form-hint\">{{hint}}</div>\n </div>\n </fs-label-message>\n</fs-label-field>\n", styles: [":host ::ng-deep .fr-box.fr-basic .fr-wrapper{border:0;border-bottom:1px solid #949494;margin-bottom:1px;background-color:transparent}:host ::ng-deep .fr-box.fr-basic .fr-element{padding:0;font-family:inherit;color:inherit;font-size:inherit;line-height:inherit;min-height:auto}:host ::ng-deep .fr-more-toolbar,:host ::ng-deep .fr-toolbar,:host ::ng-deep .fr-dropdown:after,:host ::ng-deep .fr-dropdown-menu .fr-dropdown-wrapper{transition:none!important}:host ::ng-deep .fr-toolbar-open .fr-more-toolbar{display:block}:host ::ng-deep .fr-more-toolbar{display:none}:host ::ng-deep .fr-toolbar.fr-top{position:sticky;z-index:2;border-radius:0;background-color:#fff}:host ::ng-deep .fr-toolbar.fr-top .fr-btn-grp{margin:0 20px 0 0}:host ::ng-deep .fr-toolbar.fr-top .fr-btn-grp:nth-child(1):after,:host ::ng-deep .fr-toolbar.fr-top .fr-btn-grp:nth-child(2):after{content:\"\";position:absolute;top:9px;height:30px;border-left:1px solid #e5e5e5;margin-left:10px}:host ::ng-deep .fr-toolbar.fr-top div:first-of-type:before{border:none}:host ::ng-deep .fr-toolbar.fr-top.fr-toolbar-open .fr-newline{height:auto}:host ::ng-deep .fr-toolbar.fr-top .fr-btn-grp:first-child{margin-left:0}:host ::ng-deep .fr-toolbar.fr-top.fr-top{border:0}:host ::ng-deep .fr-toolbar.fr-top .fr-newline{margin:0}:host ::ng-deep .fr-toolbar.fr-top .fr-more-toolbar{z-index:auto;display:flex;justify-content:center;padding-left:0!important}:host ::ng-deep .fr-toolbar.fr-top .fr-command.fr-btn{z-index:auto}:host ::ng-deep .fr-toolbar.fr-top .fr-command.fr-btn.fr-dropdown:after{right:3px}:host ::ng-deep .fr-toolbar.fr-top .fr-command.fr-btn.fr-dropdown.fr-selection span{margin-right:24px}:host ::ng-deep .fr-toolbar.fr-top .fr-command.fr-btn.fr-open{border-radius:4px;margin:4px 2px}:host ::ng-deep .fr-view ol,:host ::ng-deep .fr-view ul{list-style-position:unset}:host ::ng-deep .html-editor-container.init-on-click:not(.initialized) .fr-toolbar{display:none}:host.disabled ::ng-deep .fr-box.fr-basic{opacity:.5;pointer-events:none}:host.disabled ::ng-deep .fr-box.fr-basic .fr-wrapper{border:none}:host.disabled ::ng-deep .disabled-line{display:block}::ng-deep .fr-popup{z-index:1001!important}::ng-deep .fr-video-by-url-layer .fr-checkbox-line{display:none}.disabled-line{display:none;position:absolute;bottom:-1px;z-index:1;background-image:linear-gradient(90deg,rgba(0,0,0,.42) 0,rgba(0,0,0,.42) 33%,transparent 0);background-size:4px 100%;background-repeat:repeat-x;height:1px;width:100%}.bottom-line{opacity:0;transform-origin:50%;transform:scaleX(.5);transition:background-color .3s cubic-bezier(.55,0,.55,.2);width:100%;border-bottom:2px solid #949494;position:absolute;bottom:-1px;z-index:1}:host{position:relative;display:block}:host.focused .bottom-line{opacity:1;display:block;transform:scaleX(1);transition:transform .3s cubic-bezier(.25,.8,.25,1),opacity .1s cubic-bezier(.25,.8,.25,1),background-color .3s cubic-bezier(.25,.8,.25,1)}::ng-deep .fs-html-editor-mention-container{position:absolute;top:0;left:0;height:auto;max-height:300px;max-width:500px;overflow:auto;display:block;z-index:999999;box-shadow:0 2px 4px -1px #0003,0 4px 5px #00000024,0 1px 10px #0000001f;border-bottom-left-radius:4px;border-bottom-right-radius:4px;background:#fff}::ng-deep .fs-html-editor-mention-container ul{margin:0;padding:0;list-style:none}::ng-deep .fs-html-editor-mention-container li{padding:0 16px;cursor:pointer;line-height:48px}::ng-deep .fs-html-editor-mention-container li.highlight,::ng-deep .fs-html-editor-mention-container li:hover{background:#F5F5F5}::ng-deep .fs-html-editor-mention-container li.no-match{cursor:default}\n"], components: [{ type: i2.FsLabelFieldComponent, selector: "fs-label-field", inputs: ["bottomMargin", "topMargin", "labelMargin"] }, { type: i2.FsLabelComponent, selector: "fs-label" }, { type: i2.FsLabelMessageComponent, selector: "fs-label-message" }], directives: [{ type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i4.FsSkeletonContentDirective, selector: "[fsSkeleton]", inputs: ["fsSkeleton", "fsSkeletonPattern"] }], pipes: { "async": i3.AsyncPipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush });
549
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsHtmlEditorComponent, decorators: [{
550
- type: Component,
551
- args: [{
552
- selector: 'fs-html-editor',
553
- templateUrl: 'html-editor.component.html',
554
- styleUrls: ['html-editor.component.scss'],
555
- providers: [
556
- {
557
- provide: NG_VALUE_ACCESSOR,
558
- useExisting: forwardRef(() => FsHtmlEditorComponent),
559
- multi: true
560
- },
561
- {
562
- provide: NG_VALIDATORS,
563
- useExisting: forwardRef(() => FsHtmlEditorComponent),
564
- multi: true
565
- },
566
- ],
567
- changeDetection: ChangeDetectionStrategy.OnPush,
568
- }]
569
- }], ctorParameters: function () { return [{ type: undefined, decorators: [{
570
- type: Optional
571
- }, {
572
- type: Inject,
573
- args: [FS_HTML_EDITOR_CONFIG]
574
- }] }, { type: i0.ChangeDetectorRef }, { type: FsFroalaLoaderService }]; }, propDecorators: { classFocused: [{
575
- type: HostBinding,
576
- args: ['class.focused']
577
- }], elRef: [{
578
- type: ViewChild,
579
- args: ['elRef']
580
- }], config: [{
581
- type: Input
582
- }], hint: [{
583
- type: Input
584
- }], disabled: [{
585
- type: Input
586
- }, {
587
- type: HostBinding,
588
- args: ['class.disabled']
188
+ class FsHtmlEditorComponent {
189
+ constructor(_defaultConfig, _cdRef, _fr) {
190
+ this._defaultConfig = _defaultConfig;
191
+ this._cdRef = _cdRef;
192
+ this._fr = _fr;
193
+ this.classFocused = false;
194
+ this.config = {};
195
+ this.disabled = false;
196
+ this.initialized = false;
197
+ this.containerID = `fs-html-editor-${guid('xxx')}`;
198
+ this._initialize$ = new ReplaySubject();
199
+ this._froalaReady$ = new BehaviorSubject(null);
200
+ this._destroy$ = new Subject();
201
+ this.onChange = (data) => { };
202
+ this.onTouched = () => { };
203
+ }
204
+ get el() {
205
+ return this.elRef.nativeElement;
206
+ }
207
+ get html() {
208
+ return this._html;
209
+ }
210
+ get editor() {
211
+ return this._editor;
212
+ }
213
+ get froalaLoaded$() {
214
+ return this._fr.loaded$;
215
+ }
216
+ ngOnInit() {
217
+ this.config = this.config || {};
218
+ this.config.autofocus = this.config.autofocus !== false && (!this.config.disabled || !this.disabled);
219
+ this._listenLazyInit();
220
+ }
221
+ ngAfterViewInit() {
222
+ this._initialize$.next();
223
+ }
224
+ hasContent() {
225
+ const el = document.createElement('div');
226
+ if (el.querySelector('img')) {
227
+ return true;
228
+ }
229
+ el.innerHTML = this._html;
230
+ return !!el.innerText.length;
231
+ }
232
+ initialize(options = {}) {
233
+ const config = this._createConfig();
234
+ this._initPlugins(config);
235
+ this._initButtons(config);
236
+ this._editor = new this._fr.FroalaEditor(this.el, this._createOptions(), () => {
237
+ this._froalaReady$.next({ config, options });
238
+ });
239
+ }
240
+ _processImageUpload(blob) {
241
+ const processor = new FileProcessor();
242
+ const file = new FsFile(blob);
243
+ const config = {
244
+ orientate: true,
245
+ quality: this.config.image.quality,
246
+ format: this.config.image.format,
247
+ maxWidth: this.config.image.width,
248
+ maxHeight: this.config.image.height,
249
+ minWidth: this.config.image.minWidth,
250
+ minHeight: this.config.image.minHeight,
251
+ };
252
+ return processor.processFile(file, config)
253
+ .pipe(switchMap((fsFile) => {
254
+ return this.config.image.upload(fsFile.file);
255
+ }));
256
+ }
257
+ updateSize() {
258
+ // Hack: To trigger the toolbar button size modes
259
+ window.dispatchEvent(new Event('resize'));
260
+ }
261
+ validate(control) {
262
+ const err = {};
263
+ if (this.config.maxLength && this._html) {
264
+ const maxLength = this.config.maxLength;
265
+ const length = this._html.length;
266
+ if (length > maxLength) {
267
+ err.maxLengthError = `Must be ${maxLength} characters or fewer. You entered ${length} characters.`;
268
+ }
269
+ }
270
+ return Object.keys(err).length ? err : null;
271
+ }
272
+ focus(options) {
273
+ options = options ? options : {};
274
+ if (options.cursorPosition === 'end') {
275
+ this.editor.selection.setAtEnd(this.editor.$el.get(0));
276
+ }
277
+ else {
278
+ this.editor.selection.setAtStart(this.editor.$el.get(0));
279
+ }
280
+ this.editor.selection.restore();
281
+ const elSelection = this.editor.selection.element();
282
+ if (elSelection) {
283
+ elSelection.scrollIntoView({ block: 'center' });
284
+ }
285
+ }
286
+ clear() {
287
+ this.writeValue('');
288
+ }
289
+ disable() {
290
+ this.disabled = true;
291
+ }
292
+ setHtml(html) {
293
+ this.writeValue(html);
294
+ }
295
+ writeValue(html) {
296
+ this._html = html || '';
297
+ if (Array.isArray(this._html)) {
298
+ this._html = this._html.pop();
299
+ }
300
+ this._html = this._html
301
+ .replace(/<(li)>\s?<(div)>/g, '<li>')
302
+ .replace(/<\/(div)><\/(li)>/g, '</li>');
303
+ if (this.editor && this.editor.html) {
304
+ try {
305
+ this.editor.html.set(this._html);
306
+ }
307
+ catch (e) {
308
+ }
309
+ }
310
+ this._cdRef.markForCheck();
311
+ }
312
+ registerOnChange(fn) {
313
+ this.onChange = fn;
314
+ }
315
+ registerOnTouched(fn) {
316
+ this.onTouched = fn;
317
+ }
318
+ ngOnDestroy() {
319
+ this._initialize$.complete();
320
+ this._destroy$.next();
321
+ this._destroy$.complete();
322
+ this.destroy();
323
+ }
324
+ destroy() {
325
+ if (this.editor) {
326
+ this.editor.destroy();
327
+ }
328
+ this.initialized = false;
329
+ this._cdRef.markForCheck();
330
+ this.el.innerHTML = '';
331
+ }
332
+ _createConfig() {
333
+ return merge({ froalaConfig: {} }, this._defaultConfig, this.config);
334
+ }
335
+ _change(html) {
336
+ this._html = html;
337
+ this.onChange(html);
338
+ }
339
+ _initButtons(config) {
340
+ (config.buttons || [])
341
+ .forEach((button) => {
342
+ /*
343
+ Svg Keys:
344
+ ["add", "advancedImageEditor", "alignCenter", "alignJustify", "alignLeft", "alignRight",
345
+ "anchors", "back", "backgroundColor", "blockquote", "bold", "cellBackground",
346
+ "cellBorderColor", "cellOptions", "cellStyle", "clearFormatting", "close", "codeView",
347
+ "cogs", "columns", "editLink", "exitFullscreen", "fontAwesome", "fontFamily",
348
+ "fontSize", "fullscreen", "help", "horizontalLine", "imageAltText", "imageCaption",
349
+ "imageClass", "imageDisplay", "imageManager", "imageSize", "indent", "inlineClass",
350
+ "inlineStyle", "insertEmbed", "insertFile", "insertImage", "insertLink", "insertMore",
351
+ "insertTable", "insertVideo", "upload", "italic", "search", "lineHeight", "linkStyles",
352
+ "mention", "more", "openLink", "orderedList", "outdent", "pageBreaker",
353
+ "paragraphFormat", "paragraphMore", "paragraphStyle", "pdfExport", "print",
354
+ "redo", "removeTable", "remove", "replaceImage", "row", "selectAll", "smile",
355
+ "spellcheck", "star", "strikeThrough", "subscript", "superscript", "symbols", "tags",
356
+ "tableHeader", "tableStyle", "textColor", "textMore", "underline", "undo", "unlink",
357
+ "unorderedList", "verticalAlignBottom", "verticalAlignMiddle", "verticalAlignTop"]
358
+ */
359
+ var _a, _b, _c;
360
+ if (button.svgKey) {
361
+ this._fr.FroalaEditor.DefineIcon(button.name, { SVG_KEY: button.svgKey });
362
+ }
363
+ this._fr.FroalaEditor.RegisterCommand(button.name, {
364
+ title: button.title,
365
+ focus: (_a = button.focus) !== null && _a !== void 0 ? _a : true,
366
+ undo: (_b = button.undo) !== null && _b !== void 0 ? _b : true,
367
+ refreshAfterCallback: (_c = button.refreshAfterCallback) !== null && _c !== void 0 ? _c : true,
368
+ callback: function () {
369
+ button.click(this);
370
+ }
371
+ });
372
+ });
373
+ }
374
+ _initPlugins(config) {
375
+ (config.plugins || []).forEach((plugin) => {
376
+ this._fr.FroalaEditor.PLUGINS[plugin.config.name] = function (editor) {
377
+ plugin.editor = editor;
378
+ plugin.initialize();
379
+ return plugin;
380
+ };
381
+ (plugin.config.buttons || []).forEach((button) => {
382
+ this._fr.FroalaEditor.DefineIcon(button.name, {
383
+ NAME: button.name,
384
+ PATH: button.svgPath,
385
+ });
386
+ this._fr.FroalaEditor.RegisterCommand(button.name, {
387
+ icon: button.name,
388
+ title: button.tooltip,
389
+ undo: button.undo,
390
+ focus: button.focus,
391
+ showOnMobile: button.showOnMobile,
392
+ refreshAfterCallback: button.refreshAfterCallback,
393
+ callback: function () {
394
+ if (button.click) {
395
+ button.click(this);
396
+ }
397
+ },
398
+ refresh: function (button) {
399
+ if (button.refresh) {
400
+ button.refresh(this, button);
401
+ }
402
+ }
403
+ });
404
+ });
405
+ });
406
+ }
407
+ _createOptions() {
408
+ var _a, _b;
409
+ const config = this._createConfig();
410
+ return merge(
411
+ // For some reason editor store somewhere pointer on default config object and dublicate options each time on init
412
+ // Extra merge level fixed this problem and allow to init config properly without legacy data
413
+ {}, {
414
+ shortcutsEnabled: ['show', 'bold', 'italic', 'underline', 'indent', 'outdent', 'undo', 'redo', 'insertImage', 'createLink'],
415
+ key: config.activationKey,
416
+ placeholderText: config.placeholder,
417
+ linkAlwaysBlank: true,
418
+ tabSpaces: 2,
419
+ typingTimer: 250,
420
+ tooltips: false,
421
+ wordPasteModal: false,
422
+ imageDefaultWidth: 0,
423
+ imageDefaultAlign: 'left',
424
+ quickInsertEnabled: false,
425
+ scrollableContainer: `#${this.containerID}`,
426
+ paragraphDefaultSelection: 'Format',
427
+ videoUpload: false,
428
+ imagePaste: !!((_a = config.image) === null || _a === void 0 ? void 0 : _a.upload),
429
+ imageUpload: !!((_b = config.image) === null || _b === void 0 ? void 0 : _b.upload),
430
+ paragraphFormat: {
431
+ N: 'Normal',
432
+ H1: 'Heading 1',
433
+ H2: 'Heading 2',
434
+ H3: 'Heading 3',
435
+ H4: 'Heading 4',
436
+ BLOCKQUOTE: 'Quote',
437
+ },
438
+ lineHeights: {
439
+ Default: '',
440
+ '0.5': '0.5',
441
+ 'Single': '1',
442
+ '1.15': '1.15',
443
+ '1.5': '1.5',
444
+ 'Double': '2'
445
+ },
446
+ paragraphFormatSelection: true,
447
+ toolbarButtonsXS: {
448
+ moreText: {
449
+ buttons: TextButtons,
450
+ buttonsVisible: 1,
451
+ },
452
+ moreParagraph: {
453
+ buttons: ParagraphButtons,
454
+ buttonsVisible: 2,
455
+ },
456
+ moreRich: {
457
+ buttons: RichButtons,
458
+ buttonsVisible: 0,
459
+ },
460
+ },
461
+ toolbarButtons: {
462
+ moreText: {
463
+ buttons: TextButtons,
464
+ buttonsVisible: 3,
465
+ },
466
+ moreParagraph: {
467
+ buttons: ParagraphButtons,
468
+ buttonsVisible: 5,
469
+ },
470
+ moreRich: {
471
+ buttons: RichButtons,
472
+ buttonsVisible: 3,
473
+ },
474
+ },
475
+ }, config.froalaConfig);
476
+ }
477
+ _listenLazyInit() {
478
+ this.froalaLoaded$
479
+ .pipe(filter((ready) => ready), switchMap(() => this._initialize$), tap(() => {
480
+ const selection = window.getSelection();
481
+ const options = {};
482
+ if (selection.baseNode) {
483
+ options.selection = {
484
+ node: selection.baseNode.nodeValue,
485
+ offset: selection.baseOffset,
486
+ };
487
+ }
488
+ this.initialize(options);
489
+ }), switchMap(() => this._froalaReady$), filter((data) => !!data), tap(({ config, options }) => {
490
+ this._setupFroala(config, options);
491
+ }))
492
+ .subscribe();
493
+ }
494
+ _contentChanged() {
495
+ const editorHTML = this._editor.html.get();
496
+ if (this.html !== editorHTML) {
497
+ this._change(editorHTML);
498
+ }
499
+ }
500
+ _setupFroala(config, options) {
501
+ this._cdRef.markForCheck();
502
+ this.setHtml(this._html);
503
+ if (config.disabled) {
504
+ this.disable();
505
+ }
506
+ if (config.froalaConfig.events) {
507
+ if (config.froalaConfig.events.initialized) {
508
+ config.froalaConfig.events.initialized();
509
+ }
510
+ }
511
+ this._editor.events.on('focus', () => {
512
+ this.classFocused = true;
513
+ this._cdRef.markForCheck();
514
+ });
515
+ this._editor.events.on('blur', () => {
516
+ this.classFocused = false;
517
+ this._cdRef.markForCheck();
518
+ });
519
+ this._editor.events.on('click', () => {
520
+ if (this.config.initOnClick && !this.initialized) {
521
+ this.initialized = true;
522
+ this._cdRef.markForCheck();
523
+ }
524
+ });
525
+ fromEventPattern((handler) => {
526
+ this._editor.events.on('contentChanged', handler);
527
+ }, () => { })
528
+ .pipe(startWith(this._html), map(() => this.editor.html.get()), distinctUntilChanged(), skip(1))
529
+ .subscribe(() => {
530
+ this._contentChanged();
531
+ });
532
+ this._editor.events.on('paste.afterCleanup', (html) => {
533
+ var div = document.createElement('div');
534
+ div.innerHTML = html;
535
+ div.querySelectorAll('*')
536
+ .forEach((el) => {
537
+ for (var i = 0; i < el.attributes.length; i++) {
538
+ const name = el.attributes[0].name;
539
+ if (name !== 'href') {
540
+ el.removeAttribute(name);
541
+ }
542
+ }
543
+ });
544
+ return div.innerHTML;
545
+ });
546
+ this._editor.events.on('keydown', () => {
547
+ this.onTouched();
548
+ });
549
+ if (this.config.image && this.config.image.upload) {
550
+ this._editor.events.on('image.beforePasteUpload', (image) => {
551
+ fetch(image.getAttribute('src'))
552
+ .then((res) => {
553
+ res.blob()
554
+ .then((blob) => {
555
+ this._processImageUpload(blob)
556
+ .pipe(takeUntil(this._destroy$))
557
+ .subscribe((url) => {
558
+ image.setAttribute('src', url);
559
+ image.removeAttribute('data-fr-image-pasted');
560
+ this._contentChanged();
561
+ });
562
+ });
563
+ });
564
+ return false;
565
+ });
566
+ this._editor.events.on('image.beforeUpload', (blobs) => {
567
+ this._processImageUpload(blobs[0])
568
+ .pipe(takeUntil(this._destroy$))
569
+ .subscribe((url) => {
570
+ this.editor.image.insert(url, null, null, this.editor.image.get());
571
+ });
572
+ return false;
573
+ });
574
+ }
575
+ if (this.el.querySelector('.fr-second-toolbar')) {
576
+ this.el.querySelector('.fr-second-toolbar').remove();
577
+ }
578
+ if (this.config.autofocus && !this.config.initOnClick) {
579
+ this.focus();
580
+ }
581
+ }
582
+ }
583
+ FsHtmlEditorComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsHtmlEditorComponent, deps: [{ token: FS_HTML_EDITOR_CONFIG, optional: true }, { token: i0.ChangeDetectorRef }, { token: FsFroalaLoaderService }], target: i0.ɵɵFactoryTarget.Component });
584
+ FsHtmlEditorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.16", type: FsHtmlEditorComponent, selector: "fs-html-editor", inputs: { config: "config", hint: "hint", disabled: "disabled" }, host: { properties: { "class.focused": "this.classFocused", "class.disabled": "this.disabled" } }, providers: [
585
+ {
586
+ provide: NG_VALUE_ACCESSOR,
587
+ useExisting: forwardRef(() => FsHtmlEditorComponent),
588
+ multi: true
589
+ },
590
+ {
591
+ provide: NG_VALIDATORS,
592
+ useExisting: forwardRef(() => FsHtmlEditorComponent),
593
+ multi: true
594
+ },
595
+ ], viewQueries: [{ propertyName: "elRef", first: true, predicate: ["elRef"], descendants: true }], ngImport: i0, template: "<fs-label-field>\n <fs-label *ngIf=\"config.label\">{{config.label}}</fs-label>\n <div\n class=\"html-editor-container fs-html-editor-default\"\n [id]=\"containerID\"\n [ngClass]=\"{\n initialized: initialized,\n 'init-on-click': config.initOnClick\n }\">\n <ng-container *fsSkeleton=\"(froalaLoaded$ | async) !== false\"></ng-container>\n <div #elRef></div>\n\n <div class=\"bottom-line\"></div>\n <div class=\"disabled-line\"></div>\n </div>\n\n <fs-label-message>\n <div class=\"fs-form-message\">\n <div class=\"fs-form-hint\">{{hint}}</div>\n </div>\n </fs-label-message>\n</fs-label-field>\n", styles: [":host ::ng-deep .fr-box.fr-basic .fr-wrapper{border:0;border-bottom:1px solid #949494;margin-bottom:1px;background-color:transparent}:host ::ng-deep .fr-box.fr-basic .fr-element{padding:0;font-family:inherit;color:inherit;font-size:inherit;line-height:inherit;min-height:auto}:host ::ng-deep .fr-more-toolbar,:host ::ng-deep .fr-toolbar,:host ::ng-deep .fr-dropdown:after,:host ::ng-deep .fr-dropdown-menu .fr-dropdown-wrapper{transition:none!important}:host ::ng-deep .fr-toolbar-open .fr-more-toolbar{display:block}:host ::ng-deep .fr-more-toolbar{display:none}:host ::ng-deep .fr-toolbar.fr-top{position:sticky;z-index:2;border-radius:0;background-color:#fff}:host ::ng-deep .fr-toolbar.fr-top .fr-btn-grp{margin:0 20px 0 0}:host ::ng-deep .fr-toolbar.fr-top .fr-btn-grp:nth-child(1):after,:host ::ng-deep .fr-toolbar.fr-top .fr-btn-grp:nth-child(2):after{content:\"\";position:absolute;top:9px;height:30px;border-left:1px solid #e5e5e5;margin-left:10px}:host ::ng-deep .fr-toolbar.fr-top div:first-of-type:before{border:none}:host ::ng-deep .fr-toolbar.fr-top.fr-toolbar-open .fr-newline{height:auto}:host ::ng-deep .fr-toolbar.fr-top .fr-btn-grp:first-child{margin-left:0}:host ::ng-deep .fr-toolbar.fr-top.fr-top{border:0}:host ::ng-deep .fr-toolbar.fr-top .fr-newline{margin:0}:host ::ng-deep .fr-toolbar.fr-top .fr-more-toolbar{z-index:auto;display:flex;justify-content:center;padding-left:0!important}:host ::ng-deep .fr-toolbar.fr-top .fr-command.fr-btn{z-index:auto}:host ::ng-deep .fr-toolbar.fr-top .fr-command.fr-btn.fr-dropdown:after{right:3px}:host ::ng-deep .fr-toolbar.fr-top .fr-command.fr-btn.fr-dropdown.fr-selection span{margin-right:24px}:host ::ng-deep .fr-toolbar.fr-top .fr-command.fr-btn.fr-open{border-radius:4px;margin:4px 2px}:host ::ng-deep .fr-view ol,:host ::ng-deep .fr-view ul{list-style-position:unset}:host ::ng-deep .html-editor-container.init-on-click:not(.initialized) .fr-toolbar{display:none}:host.disabled ::ng-deep .fr-box.fr-basic{opacity:.5;pointer-events:none}:host.disabled ::ng-deep .fr-box.fr-basic .fr-wrapper{border:none}:host.disabled ::ng-deep .disabled-line{display:block}::ng-deep .fr-popup{z-index:1001!important}::ng-deep .fr-video-by-url-layer .fr-checkbox-line{display:none}.disabled-line{display:none;position:absolute;bottom:-1px;z-index:1;background-image:linear-gradient(90deg,rgba(0,0,0,.42) 0,rgba(0,0,0,.42) 33%,transparent 0);background-size:4px 100%;background-repeat:repeat-x;height:1px;width:100%}.bottom-line{opacity:0;transform-origin:50%;transform:scaleX(.5);transition:background-color .3s cubic-bezier(.55,0,.55,.2);width:100%;border-bottom:2px solid #949494;position:absolute;bottom:-1px;z-index:1}:host{position:relative;display:block}:host.focused .bottom-line{opacity:1;display:block;transform:scaleX(1);transition:transform .3s cubic-bezier(.25,.8,.25,1),opacity .1s cubic-bezier(.25,.8,.25,1),background-color .3s cubic-bezier(.25,.8,.25,1)}::ng-deep .fs-html-editor-mention-container{position:absolute;top:0;left:0;height:auto;max-height:300px;max-width:500px;overflow:auto;display:block;z-index:999999;box-shadow:0 2px 4px -1px #0003,0 4px 5px #00000024,0 1px 10px #0000001f;border-bottom-left-radius:4px;border-bottom-right-radius:4px;background:#fff}::ng-deep .fs-html-editor-mention-container ul{margin:0;padding:0;list-style:none}::ng-deep .fs-html-editor-mention-container li{padding:0 16px;cursor:pointer;line-height:48px}::ng-deep .fs-html-editor-mention-container li.highlight,::ng-deep .fs-html-editor-mention-container li:hover{background:#F5F5F5}::ng-deep .fs-html-editor-mention-container li.no-match{cursor:default}\n"], components: [{ type: i2.FsLabelFieldComponent, selector: "fs-label-field", inputs: ["bottomMargin", "topMargin", "labelMargin"] }, { type: i2.FsLabelComponent, selector: "fs-label" }, { type: i2.FsLabelMessageComponent, selector: "fs-label-message" }], directives: [{ type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i4.FsSkeletonContentDirective, selector: "[fsSkeleton]", inputs: ["fsSkeleton", "fsSkeletonPattern"] }], pipes: { "async": i3.AsyncPipe }, viewProviders: [
596
+ {
597
+ provide: ControlContainer,
598
+ deps: [[Optional, NgForm]],
599
+ useFactory: (ngForm) => ngForm,
600
+ },
601
+ ], changeDetection: i0.ChangeDetectionStrategy.OnPush });
602
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsHtmlEditorComponent, decorators: [{
603
+ type: Component,
604
+ args: [{
605
+ selector: 'fs-html-editor',
606
+ templateUrl: 'html-editor.component.html',
607
+ styleUrls: ['html-editor.component.scss'],
608
+ providers: [
609
+ {
610
+ provide: NG_VALUE_ACCESSOR,
611
+ useExisting: forwardRef(() => FsHtmlEditorComponent),
612
+ multi: true
613
+ },
614
+ {
615
+ provide: NG_VALIDATORS,
616
+ useExisting: forwardRef(() => FsHtmlEditorComponent),
617
+ multi: true
618
+ },
619
+ ],
620
+ changeDetection: ChangeDetectionStrategy.OnPush,
621
+ viewProviders: [
622
+ {
623
+ provide: ControlContainer,
624
+ deps: [[Optional, NgForm]],
625
+ useFactory: (ngForm) => ngForm,
626
+ },
627
+ ],
628
+ }]
629
+ }], ctorParameters: function () { return [{ type: undefined, decorators: [{
630
+ type: Optional
631
+ }, {
632
+ type: Inject,
633
+ args: [FS_HTML_EDITOR_CONFIG]
634
+ }] }, { type: i0.ChangeDetectorRef }, { type: FsFroalaLoaderService }]; }, propDecorators: { classFocused: [{
635
+ type: HostBinding,
636
+ args: ['class.focused']
637
+ }], elRef: [{
638
+ type: ViewChild,
639
+ args: ['elRef']
640
+ }], config: [{
641
+ type: Input
642
+ }], hint: [{
643
+ type: Input
644
+ }], disabled: [{
645
+ type: Input
646
+ }, {
647
+ type: HostBinding,
648
+ args: ['class.disabled']
589
649
  }] } });
590
650
 
591
- class FsHtmlRendererComponent {
592
- constructor(sanitized, _cdRef) {
593
- this.sanitized = sanitized;
594
- this._cdRef = _cdRef;
595
- }
596
- set setHtml(html) {
597
- this.trustedHtml = this.sanitized.bypassSecurityTrustHtml(html || '');
598
- this._cdRef.markForCheck();
599
- }
651
+ class FsHtmlEditorModule {
652
+ static forRoot(config = {}) {
653
+ return {
654
+ ngModule: FsHtmlEditorModule,
655
+ providers: [
656
+ { provide: FS_HTML_EDITOR_DEFAULT_CONFIG, useValue: config },
657
+ {
658
+ provide: FS_HTML_EDITOR_CONFIG,
659
+ useFactory: FsHtmlEditorConfigFactory,
660
+ deps: [FS_HTML_EDITOR_DEFAULT_CONFIG]
661
+ }
662
+ ]
663
+ };
664
+ }
665
+ }
666
+ FsHtmlEditorModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsHtmlEditorModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
667
+ FsHtmlEditorModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsHtmlEditorModule, declarations: [FsHtmlEditorComponent], imports: [CommonModule,
668
+ FsSkeletonModule,
669
+ FsLabelModule,
670
+ FsHtmlRendererModule], exports: [FsHtmlEditorComponent] });
671
+ FsHtmlEditorModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsHtmlEditorModule, imports: [[
672
+ CommonModule,
673
+ FsSkeletonModule,
674
+ FsLabelModule,
675
+ FsHtmlRendererModule,
676
+ ]] });
677
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsHtmlEditorModule, decorators: [{
678
+ type: NgModule,
679
+ args: [{
680
+ imports: [
681
+ CommonModule,
682
+ FsSkeletonModule,
683
+ FsLabelModule,
684
+ FsHtmlRendererModule,
685
+ ],
686
+ exports: [
687
+ FsHtmlEditorComponent,
688
+ ],
689
+ declarations: [
690
+ FsHtmlEditorComponent,
691
+ ],
692
+ }]
693
+ }] });
694
+ function FsHtmlEditorConfigFactory(config) {
695
+ return Object.assign({ froalaPlugins: [
696
+ "align" /* Align */,
697
+ "colors" /* Colors */,
698
+ "image" /* Image */,
699
+ "link" /* Link */,
700
+ "lists" /* Lists */,
701
+ "paragraph_format" /* ParagraphFormat */,
702
+ "quote" /* Quote */,
703
+ "table" /* Table */,
704
+ "url" /* Url */,
705
+ "video" /* Video */,
706
+ "draggable" /* Draggable */,
707
+ "font_size" /* FontSize */,
708
+ "line_height" /* LineHeight */,
709
+ ] }, config);
600
710
  }
601
- FsHtmlRendererComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsHtmlRendererComponent, deps: [{ token: i1.DomSanitizer }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
602
- FsHtmlRendererComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.16", type: FsHtmlRendererComponent, selector: "fs-html-renderer", inputs: { setHtml: ["html", "setHtml"] }, ngImport: i0, template: "<span class=\"fr-view fs-html-editor-default\" [innerHtml]=\"trustedHtml\"></span>\n", styles: [""], changeDetection: i0.ChangeDetectionStrategy.OnPush });
603
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsHtmlRendererComponent, decorators: [{
604
- type: Component,
605
- args: [{
606
- selector: 'fs-html-renderer',
607
- templateUrl: 'html-renderer.component.html',
608
- styleUrls: ['html-renderer.component.scss'],
609
- changeDetection: ChangeDetectionStrategy.OnPush,
610
- }]
611
- }], ctorParameters: function () { return [{ type: i1.DomSanitizer }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { setHtml: [{
612
- type: Input,
613
- args: ['html']
614
- }] } });
615
711
 
616
- class FsHtmlRendererModule {
712
+ class Plugin {
713
+ initialize() { }
714
+ destroy() { }
617
715
  }
618
- FsHtmlRendererModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsHtmlRendererModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
619
- FsHtmlRendererModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsHtmlRendererModule, declarations: [FsHtmlRendererComponent], imports: [CommonModule], exports: [FsHtmlRendererComponent] });
620
- FsHtmlRendererModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsHtmlRendererModule, imports: [[
621
- CommonModule,
622
- ]] });
623
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsHtmlRendererModule, decorators: [{
624
- type: NgModule,
625
- args: [{
626
- imports: [
627
- CommonModule,
628
- ],
629
- exports: [
630
- FsHtmlRendererComponent,
631
- ],
632
- declarations: [
633
- FsHtmlRendererComponent,
634
- ],
635
- }]
636
- }] });
637
716
 
638
- class FsHtmlEditorModule {
639
- static forRoot(config = {}) {
640
- return {
641
- ngModule: FsHtmlEditorModule,
642
- providers: [
643
- { provide: FS_HTML_EDITOR_DEFAULT_CONFIG, useValue: config },
644
- {
645
- provide: FS_HTML_EDITOR_CONFIG,
646
- useFactory: FsHtmlEditorConfigFactory,
647
- deps: [FS_HTML_EDITOR_DEFAULT_CONFIG]
648
- }
649
- ]
650
- };
651
- }
652
- }
653
- FsHtmlEditorModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsHtmlEditorModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
654
- FsHtmlEditorModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsHtmlEditorModule, declarations: [FsHtmlEditorComponent], imports: [CommonModule,
655
- FsSkeletonModule,
656
- FsLabelModule,
657
- FsHtmlRendererModule], exports: [FsHtmlEditorComponent] });
658
- FsHtmlEditorModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsHtmlEditorModule, imports: [[
659
- CommonModule,
660
- FsSkeletonModule,
661
- FsLabelModule,
662
- FsHtmlRendererModule,
663
- ]] });
664
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FsHtmlEditorModule, decorators: [{
665
- type: NgModule,
666
- args: [{
667
- imports: [
668
- CommonModule,
669
- FsSkeletonModule,
670
- FsLabelModule,
671
- FsHtmlRendererModule,
672
- ],
673
- exports: [
674
- FsHtmlEditorComponent,
675
- ],
676
- declarations: [
677
- FsHtmlEditorComponent,
678
- ],
679
- }]
680
- }] });
681
- function FsHtmlEditorConfigFactory(config) {
682
- return Object.assign({ froalaPlugins: [
683
- "align" /* Align */,
684
- "colors" /* Colors */,
685
- "image" /* Image */,
686
- "link" /* Link */,
687
- "lists" /* Lists */,
688
- "paragraph_format" /* ParagraphFormat */,
689
- "quote" /* Quote */,
690
- "table" /* Table */,
691
- "url" /* Url */,
692
- "video" /* Video */,
693
- "draggable" /* Draggable */,
694
- "font_size" /* FontSize */,
695
- "line_height" /* LineHeight */,
696
- ] }, config);
697
- }
698
-
699
- class Plugin {
700
- initialize() { }
701
- destroy() { }
702
- }
703
-
704
- class MentionPlugin extends Plugin {
705
- constructor(config) {
706
- super();
707
- this.config = config;
708
- this._guid = guid();
709
- this.selected = (event) => {
710
- if (this.config.selected) {
711
- if (MentionPlugin._currentGuid === this._guid) {
712
- this.config.selected(event.detail.item.original);
713
- }
714
- }
715
- };
716
- this.config = Object.assign(Object.assign({}, config), { buttons: [
717
- {
718
- name: config.name,
719
- tooltip: config.tooltip,
720
- svgPath: config.iconPath,
721
- click: (editor) => {
722
- this._closeAll();
723
- this._tribute.showMenuForCollection(editor.el);
724
- }
725
- }
726
- ] });
727
- this._tribute = new Tribute({
728
- values: debounce(this._loadValues.bind(this), 200),
729
- searchOpts: {
730
- pre: '',
731
- post: '',
732
- skip: true
733
- },
734
- containerClass: `fs-html-editor-mention-container ${this.config.containerClass || ''}`,
735
- itemClass: `fs-html-editor-mention-menu-item ${this.config.menuItemClass || ''}`,
736
- trigger: this.config.trigger,
737
- allowSpaces: true,
738
- menuItemTemplate: (item) => {
739
- return this.config.menuItemTemplate(item.original);
740
- },
741
- selectTemplate: (item) => {
742
- const template = this.config.selectedTemplate(item.original);
743
- let p = document.createElement('p');
744
- p.innerHTML = template;
745
- let node = p.firstElementChild;
746
- if (!node) {
747
- node = document.createElement('span');
748
- node.innerHTML = template;
749
- }
750
- node.setAttribute('contenteditable', 'false');
751
- node.classList.add('fr-deletable');
752
- return node.outerHTML;
753
- },
754
- });
755
- MentionPlugin._tributes.push(this._tribute);
756
- }
757
- initialize() {
758
- this._tribute.attach(this.editor.el);
759
- this.editor.events.on('keydown', (e) => {
760
- if (e.key === 'Enter' && this._tribute.isActive) {
761
- return false;
762
- }
763
- }, true);
764
- this.editor.el.addEventListener("tribute-replaced", this.selected);
765
- }
766
- destroy() {
767
- this.editor.el.removeEventListener("tribute-replaced", this.selected);
768
- }
769
- _closeAll() {
770
- MentionPlugin._tributes.forEach((tribute) => {
771
- if (tribute.menu) {
772
- tribute.hideMenu();
773
- }
774
- });
775
- }
776
- _loadValues(keyword, cb) {
777
- MentionPlugin._currentGuid = this._guid;
778
- return this.config.fetch(keyword)
779
- .subscribe((data) => {
780
- cb(data);
781
- });
782
- }
783
- }
784
- MentionPlugin._currentGuid = null;
717
+ class MentionPlugin extends Plugin {
718
+ constructor(config) {
719
+ super();
720
+ this.config = config;
721
+ this._guid = guid();
722
+ this.selected = (event) => {
723
+ if (this.config.selected) {
724
+ if (MentionPlugin._currentGuid === this._guid) {
725
+ this.config.selected(event.detail.item.original);
726
+ }
727
+ }
728
+ };
729
+ this.config = Object.assign(Object.assign({}, config), { buttons: [
730
+ {
731
+ name: config.name,
732
+ tooltip: config.tooltip,
733
+ svgPath: config.iconPath,
734
+ click: (editor) => {
735
+ this._closeAll();
736
+ this._tribute.showMenuForCollection(editor.el);
737
+ }
738
+ }
739
+ ] });
740
+ this._tribute = new Tribute({
741
+ values: debounce(this._loadValues.bind(this), 200),
742
+ searchOpts: {
743
+ pre: '',
744
+ post: '',
745
+ skip: true
746
+ },
747
+ containerClass: `fs-html-editor-mention-container ${this.config.containerClass || ''}`,
748
+ itemClass: `fs-html-editor-mention-menu-item ${this.config.menuItemClass || ''}`,
749
+ trigger: this.config.trigger,
750
+ allowSpaces: true,
751
+ menuItemTemplate: (item) => {
752
+ return this.config.menuItemTemplate(item.original);
753
+ },
754
+ selectTemplate: (item) => {
755
+ const template = this.config.selectedTemplate(item.original);
756
+ let p = document.createElement('p');
757
+ p.innerHTML = template;
758
+ let node = p.firstElementChild;
759
+ if (!node) {
760
+ node = document.createElement('span');
761
+ node.innerHTML = template;
762
+ }
763
+ node.setAttribute('contenteditable', 'false');
764
+ node.classList.add('fr-deletable');
765
+ return node.outerHTML;
766
+ },
767
+ });
768
+ MentionPlugin._tributes.push(this._tribute);
769
+ }
770
+ initialize() {
771
+ this._tribute.attach(this.editor.el);
772
+ this.editor.events.on('keydown', (e) => {
773
+ if (e.key === 'Enter' && this._tribute.isActive) {
774
+ return false;
775
+ }
776
+ }, true);
777
+ this.editor.el.addEventListener("tribute-replaced", this.selected);
778
+ }
779
+ destroy() {
780
+ this.editor.el.removeEventListener("tribute-replaced", this.selected);
781
+ }
782
+ _closeAll() {
783
+ MentionPlugin._tributes.forEach((tribute) => {
784
+ if (tribute.menu) {
785
+ tribute.hideMenu();
786
+ }
787
+ });
788
+ }
789
+ _loadValues(keyword, cb) {
790
+ MentionPlugin._currentGuid = this._guid;
791
+ return this.config.fetch(keyword)
792
+ .subscribe((data) => {
793
+ cb(data);
794
+ });
795
+ }
796
+ }
797
+ MentionPlugin._currentGuid = null;
785
798
  MentionPlugin._tributes = [];
786
799
 
787
- class ChecklistPlugin extends Plugin {
788
- constructor(config = { name: 'checklist' }) {
789
- super();
790
- this.config = config;
791
- this.config = Object.assign(Object.assign({}, config), { name: 'checklist', buttons: [
792
- {
793
- name: 'checklist',
794
- svgPath: 'M8.4,10.3l-1.2,1.2l4,4L20,6.7l-1.2-1.2l-7.6,7.6L8.4,10.3z M18.2,18.2H5.8V5.8h8.9V4H5.8C4.8,4,4,4.8,4,5.8v12.4c0,1,0.8,1.8,1.8,1.8h12.4c1,0,1.8-0.8,1.8-1.8v-7.1h-1.8V18.2z',
795
- click: (editor) => {
796
- editor.html.insert('<ul class="checklist"><li></li></ul>');
797
- }
798
- }
799
- ] });
800
- }
801
- initialize() {
802
- this.editor.events.on('click', (e) => {
803
- const li = e.target;
804
- if (li.nodeName === 'LI' && e.offsetX < 0) {
805
- const items = [li, ...li.querySelectorAll('li')];
806
- if (li.classList.contains('checked')) {
807
- items.forEach((item) => {
808
- item.classList.remove('checked');
809
- });
810
- }
811
- else {
812
- items.forEach((item) => {
813
- item.classList.add('checked');
814
- });
815
- }
816
- }
817
- }, false);
818
- }
800
+ class ChecklistPlugin extends Plugin {
801
+ constructor(config = { name: 'checklist' }) {
802
+ super();
803
+ this.config = config;
804
+ this.config = Object.assign(Object.assign({}, config), { name: 'checklist', buttons: [
805
+ {
806
+ name: 'checklist',
807
+ svgPath: 'M8.4,10.3l-1.2,1.2l4,4L20,6.7l-1.2-1.2l-7.6,7.6L8.4,10.3z M18.2,18.2H5.8V5.8h8.9V4H5.8C4.8,4,4,4.8,4,5.8v12.4c0,1,0.8,1.8,1.8,1.8h12.4c1,0,1.8-0.8,1.8-1.8v-7.1h-1.8V18.2z',
808
+ click: (editor) => {
809
+ editor.html.insert('<ul class="checklist"><li></li></ul>');
810
+ }
811
+ }
812
+ ] });
813
+ }
814
+ initialize() {
815
+ this.editor.events.on('click', (e) => {
816
+ const li = e.target;
817
+ if (li.nodeName === 'LI' && e.offsetX < 0) {
818
+ const items = [li, ...li.querySelectorAll('li')];
819
+ if (li.classList.contains('checked')) {
820
+ items.forEach((item) => {
821
+ item.classList.remove('checked');
822
+ });
823
+ }
824
+ else {
825
+ items.forEach((item) => {
826
+ item.classList.add('checked');
827
+ });
828
+ }
829
+ }
830
+ }, false);
831
+ }
819
832
  }
820
833
 
821
- class CodePlugin extends Plugin {
822
- constructor(config = { name: 'code' }) {
823
- super();
824
- this.config = config;
825
- this.config = Object.assign(Object.assign({}, config), { name: 'code', buttons: [
826
- {
827
- name: 'code',
828
- svgPath: 'M8.9,7.3L4.2,12l4.7,4.7l1.1-1.1L6.4,12L10,8.4L8.9,7.3z M15.1,7.3L14,8.4l3.6,3.6L14,15.6l1.1,1.1l4.7-4.7L15.1,7.3z',
829
- click: (editor) => {
830
- const node = editor.selection.get();
831
- const codeEl = this._getCodeEl(node.baseNode);
832
- if (codeEl) {
833
- codeEl.classList.remove('code');
834
- }
835
- else {
836
- editor.html.insert('<p class="code">' + editor.selection.get().toString().replace(/\n{1,}/g, '<br>') + '</p>');
837
- }
838
- }
839
- }
840
- ] });
841
- }
842
- initialize() {
843
- this.editor.events.on('keydown', (e) => {
844
- if (e.keyCode === 13) {
845
- const selection = this.editor.selection.get();
846
- if (selection && this._getCodeEl(selection.baseNode)) {
847
- e.preventDefault();
848
- e.stopPropagation();
849
- e.stopImmediatePropagation();
850
- let br = '<br>';
851
- const base = selection.baseNode;
852
- if (base.nodeName === '#text' && selection.baseOffset === base.length) {
853
- if (!(base.nextSibling && base.nextSibling.nodeName === 'BR')) {
854
- br += '<br>';
855
- }
856
- }
857
- else {
858
- const el = Array.from(base.childNodes).splice(selection.baseOffset - 1, 1).pop();
859
- if (el && el.nodeName !== 'BR') {
860
- br += '<br>';
861
- }
862
- }
863
- this.editor.html.insert(br);
864
- return false;
865
- }
866
- }
867
- }, true);
868
- }
869
- destroy() { }
870
- _getCodeEl(el) {
871
- if (el) {
872
- if (el.classList && el.classList.contains('code')) {
873
- return el;
874
- }
875
- if (el.parentElement) {
876
- return this._getCodeEl(el.parentElement);
877
- }
878
- }
879
- return null;
880
- }
834
+ class CodePlugin extends Plugin {
835
+ constructor(config = { name: 'code' }) {
836
+ super();
837
+ this.config = config;
838
+ this.config = Object.assign(Object.assign({}, config), { name: 'code', buttons: [
839
+ {
840
+ name: 'code',
841
+ svgPath: 'M8.9,7.3L4.2,12l4.7,4.7l1.1-1.1L6.4,12L10,8.4L8.9,7.3z M15.1,7.3L14,8.4l3.6,3.6L14,15.6l1.1,1.1l4.7-4.7L15.1,7.3z',
842
+ click: (editor) => {
843
+ const node = editor.selection.get();
844
+ const codeEl = this._getCodeEl(node.baseNode);
845
+ if (codeEl) {
846
+ codeEl.classList.remove('code');
847
+ }
848
+ else {
849
+ editor.html.insert('<p class="code">' + editor.selection.get().toString().replace(/\n{1,}/g, '<br>') + '</p>');
850
+ }
851
+ }
852
+ }
853
+ ] });
854
+ }
855
+ initialize() {
856
+ this.editor.events.on('keydown', (e) => {
857
+ if (e.keyCode === 13) {
858
+ const selection = this.editor.selection.get();
859
+ if (selection && this._getCodeEl(selection.baseNode)) {
860
+ e.preventDefault();
861
+ e.stopPropagation();
862
+ e.stopImmediatePropagation();
863
+ let br = '<br>';
864
+ const base = selection.baseNode;
865
+ if (base.nodeName === '#text' && selection.baseOffset === base.length) {
866
+ if (!(base.nextSibling && base.nextSibling.nodeName === 'BR')) {
867
+ br += '<br>';
868
+ }
869
+ }
870
+ else {
871
+ const el = Array.from(base.childNodes).splice(selection.baseOffset - 1, 1).pop();
872
+ if (el && el.nodeName !== 'BR') {
873
+ br += '<br>';
874
+ }
875
+ }
876
+ this.editor.html.insert(br);
877
+ return false;
878
+ }
879
+ }
880
+ }, true);
881
+ }
882
+ destroy() { }
883
+ _getCodeEl(el) {
884
+ if (el) {
885
+ if (el.classList && el.classList.contains('code')) {
886
+ return el;
887
+ }
888
+ if (el.parentElement) {
889
+ return this._getCodeEl(el.parentElement);
890
+ }
891
+ }
892
+ return null;
893
+ }
881
894
  }
882
895
 
883
- class ScreenRecordPlugin extends Plugin {
884
- constructor(config = {}) {
885
- super();
886
- this.config = config;
887
- this.config = Object.assign(Object.assign({}, config), { name: config.name || 'screenRecord', buttons: [
888
- {
889
- name: 'screenRecord',
896
+ class ScreenRecordPlugin extends Plugin {
897
+ constructor(config = {}) {
898
+ super();
899
+ this.config = config;
900
+ this.config = Object.assign(Object.assign({}, config), { name: config.name || 'screenRecord', buttons: [
901
+ {
902
+ name: 'screenRecord',
890
903
  svgPath: `M14.7,7.7v6.1H7.1V7.7H14.7 M16.3,9.6V6.9c0-0.4-0.3-0.8-0.8-0.8H6.4c-0.4,0-0.8,0.3-0.8,0.8v7.6c0,0.4,0.3,0.8,0.8,0.8h9.1c0.4,0,0.8-0.3,0.8-0.8v-2.7l1.7,1.7c0.3,0.3,0.8,0.3,1.1,0c0.1-0.1,0.2-0.3,0.2-0.5V8.4c0-0.4-0.3-0.8-0.8-0.8
891
904
  c-0.2,0-0.4,0.1-0.5,0.2L16.3,9.6z M21.5,1.6H2.9c-0.7,0-1.3,0.7-1.3,1.6v14.6c0,0.9,0.6,1.6,1.3,1.6h7.6v1.1l-5,1c-0.2,0-0.4,0.3-0.4,0.6c0,0.3,0.2,0.4,0.4,0.4c0,0,0,0,0.1,0l5.3-1h2.6l5.3,1c0,0,0,0,0.1,0c0.2,0,0.4-0.2,0.4-0.4
892
- c0-0.3-0.1-0.6-0.4-0.6l-5-1v-1.1h7.6c0.7,0,1.3-0.7,1.3-1.6V3.2C22.9,2.3,22.3,1.6,21.5,1.6z M21.1,17.3H3.3V3.7h17.8L21.1,17.3L21.1,17.3z`,
893
- tooltip: 'Screen Record',
894
- click: (editor) => {
895
- navigator.mediaDevices.getDisplayMedia({ video: true })
896
- .then((stream) => {
897
- const chunks = [];
898
- const options = { mimeType: 'video/webm; codecs=vp9' };
899
- let mediaRecorder = new MediaRecorder(stream, options);
900
- stream.addEventListener('inactive', (e) => {
901
- mediaRecorder.stop();
902
- mediaRecorder = null;
903
- stream.getTracks().forEach((track) => track.stop());
904
- stream = null;
905
- const blob = new Blob(chunks, { type: 'video/webm' });
906
- config.upload(blob)
907
- .subscribe((url) => {
908
- editor.html.insert(`<span class="fr-screen-record fr-deletable fr-draggable"><video controls style="max-width:${config.maxWidth}"><source src="${url}" type="video/webm"></video></span>`);
909
- });
910
- });
911
- mediaRecorder.addEventListener('dataavailable', (event) => {
912
- if (event.data && event.data.size > 0) {
913
- chunks.push(event.data);
914
- }
915
- });
916
- mediaRecorder.start(10);
917
- })
918
- .catch((e) => { });
919
- }
920
- }
921
- ] });
922
- }
923
- initialize() {
924
- return __awaiter(this, void 0, void 0, function* () {
925
- const FroalaEditor = window.FroalaEditor;
926
- this.editor.events.on('mouseup', (e) => {
927
- const el = this._getEl(e.target);
928
- if (el) {
929
- this.editor.popups.hideAll();
930
- this._activeEl = el;
931
- this._showPopup(el);
932
- }
933
- });
934
- FroalaEditor.POPUP_TEMPLATES["screenRecordPlugin.popup"] = '[_BUTTONS_]';
935
- FroalaEditor.DefineIcon('popupClose', { NAME: 'trash', SVG_KEY: 'remove' });
936
- FroalaEditor.RegisterCommand('popupClose', {
937
- title: 'Remove',
938
- undo: false,
939
- focus: false,
940
- callback: () => {
941
- if (this._activeEl) {
942
- this._activeEl.remove();
943
- }
944
- }
945
- });
946
- });
947
- }
948
- _createPopup() {
949
- const template = {
950
- buttons: `<div class="fr-buttons">${this.editor.button.buildList(['popupClose'])}</div>`,
951
- };
952
- return this.editor.popups.create('screenRecordPlugin.popup', template);
953
- }
954
- _showPopup(el) {
955
- var $popup = this.editor.popups.get('screenRecordPlugin.popup');
956
- if (!$popup) {
957
- $popup = this._createPopup();
958
- }
959
- this.editor.popups.setContainer('screenRecordPlugin.popup', this.editor.$(el));
960
- const left = el.offsetLeft + el.offsetWidth / 2;
961
- this.editor.popups.show('screenRecordPlugin.popup', left, null);
962
- }
963
- _getEl(el) {
964
- if (el && el.classList) {
965
- if (el.classList.contains('fr-screen-record'))
966
- return el;
967
- return this._getEl(el.parentNode);
968
- }
969
- }
905
+ c0-0.3-0.1-0.6-0.4-0.6l-5-1v-1.1h7.6c0.7,0,1.3-0.7,1.3-1.6V3.2C22.9,2.3,22.3,1.6,21.5,1.6z M21.1,17.3H3.3V3.7h17.8L21.1,17.3L21.1,17.3z`,
906
+ tooltip: 'Screen Record',
907
+ click: (editor) => {
908
+ navigator.mediaDevices.getDisplayMedia({ video: true })
909
+ .then((stream) => {
910
+ const chunks = [];
911
+ const options = { mimeType: 'video/webm; codecs=vp9' };
912
+ let mediaRecorder = new MediaRecorder(stream, options);
913
+ stream.addEventListener('inactive', (e) => {
914
+ mediaRecorder.stop();
915
+ mediaRecorder = null;
916
+ stream.getTracks().forEach((track) => track.stop());
917
+ stream = null;
918
+ const blob = new Blob(chunks, { type: 'video/webm' });
919
+ config.upload(blob)
920
+ .subscribe((url) => {
921
+ editor.html.insert(`<span class="fr-screen-record fr-deletable fr-draggable"><video controls style="max-width:${config.maxWidth}"><source src="${url}" type="video/webm"></video></span>`);
922
+ });
923
+ });
924
+ mediaRecorder.addEventListener('dataavailable', (event) => {
925
+ if (event.data && event.data.size > 0) {
926
+ chunks.push(event.data);
927
+ }
928
+ });
929
+ mediaRecorder.start(10);
930
+ })
931
+ .catch((e) => { });
932
+ }
933
+ }
934
+ ] });
935
+ }
936
+ initialize() {
937
+ return __awaiter(this, void 0, void 0, function* () {
938
+ const FroalaEditor = window.FroalaEditor;
939
+ this.editor.events.on('mouseup', (e) => {
940
+ const el = this._getEl(e.target);
941
+ if (el) {
942
+ this.editor.popups.hideAll();
943
+ this._activeEl = el;
944
+ this._showPopup(el);
945
+ }
946
+ });
947
+ FroalaEditor.POPUP_TEMPLATES["screenRecordPlugin.popup"] = '[_BUTTONS_]';
948
+ FroalaEditor.DefineIcon('popupClose', { NAME: 'trash', SVG_KEY: 'remove' });
949
+ FroalaEditor.RegisterCommand('popupClose', {
950
+ title: 'Remove',
951
+ undo: false,
952
+ focus: false,
953
+ callback: () => {
954
+ if (this._activeEl) {
955
+ this._activeEl.remove();
956
+ }
957
+ }
958
+ });
959
+ });
960
+ }
961
+ _createPopup() {
962
+ const template = {
963
+ buttons: `<div class="fr-buttons">${this.editor.button.buildList(['popupClose'])}</div>`,
964
+ };
965
+ return this.editor.popups.create('screenRecordPlugin.popup', template);
966
+ }
967
+ _showPopup(el) {
968
+ var $popup = this.editor.popups.get('screenRecordPlugin.popup');
969
+ if (!$popup) {
970
+ $popup = this._createPopup();
971
+ }
972
+ this.editor.popups.setContainer('screenRecordPlugin.popup', this.editor.$(el));
973
+ const left = el.offsetLeft + el.offsetWidth / 2;
974
+ this.editor.popups.show('screenRecordPlugin.popup', left, null);
975
+ }
976
+ _getEl(el) {
977
+ if (el && el.classList) {
978
+ if (el.classList.contains('fr-screen-record'))
979
+ return el;
980
+ return this._getEl(el.parentNode);
981
+ }
982
+ }
970
983
  }
971
984
 
972
- class RealtimePlugin extends Plugin {
973
- constructor(config = { name: 'realtime' }) {
974
- super();
975
- this.config = config;
976
- this.config = Object.assign(Object.assign({}, config), { name: 'realtime' });
977
- }
978
- initialize() {
979
- this.editor.events.on('click', (e) => {
980
- }, false);
981
- }
985
+ class RealtimePlugin extends Plugin {
986
+ constructor(config = { name: 'realtime' }) {
987
+ super();
988
+ this.config = config;
989
+ this.config = Object.assign(Object.assign({}, config), { name: 'realtime' });
990
+ }
991
+ initialize() {
992
+ this.editor.events.on('click', (e) => {
993
+ }, false);
994
+ }
982
995
  }
983
996
 
984
- /**
985
- * Generated bundle index. Do not edit.
997
+ /**
998
+ * Generated bundle index. Do not edit.
986
999
  */
987
1000
 
988
1001
  export { ChecklistPlugin, CodePlugin, FS_HTML_EDITOR_CONFIG, FsHtmlEditorComponent, FsHtmlEditorModule, FsHtmlRendererComponent, FsHtmlRendererModule, MentionPlugin, ParagraphButtons, RealtimePlugin, RichButtons, ScreenRecordPlugin, TextButtons };