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