@firestitch/html-editor 9.5.1 → 9.5.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.
@@ -5,7 +5,7 @@ import { FsSkeletonModule } from '@firestitch/skeleton';
5
5
  import { NG_VALUE_ACCESSOR, NG_VALIDATORS } from '@angular/forms';
6
6
  import { FileProcessor, FsFile } from '@firestitch/file';
7
7
  import { Observable, BehaviorSubject, combineLatest, ReplaySubject, Subject } from 'rxjs';
8
- import { shareReplay, map, tap, concatMap, takeUntil, switchMap, filter } from 'rxjs/operators';
8
+ import { shareReplay, map, tap, concatMap, switchMap, filter, takeUntil } from 'rxjs/operators';
9
9
  import { merge, debounce } from 'lodash-es';
10
10
  import { DomSanitizer } from '@angular/platform-browser';
11
11
  import Tribute from 'tributejs';
@@ -134,7 +134,7 @@ var FsFroalaLoaderService = /** @class */ (function () {
134
134
  this._defaultConfig = _defaultConfig;
135
135
  this._froalaLoaded = new BehaviorSubject(false);
136
136
  this._defaultPluginsLoaded = new BehaviorSubject(false);
137
- this._ready$ = combineLatest([this._froalaLoaded, this._defaultPluginsLoaded])
137
+ this._loaded$ = combineLatest([this._froalaLoaded, this._defaultPluginsLoaded])
138
138
  .pipe(map(function (_a) {
139
139
  var _b = __read(_a, 2), FroalaReady = _b[0], pluginsRead = _b[1];
140
140
  return pluginsRead && FroalaReady;
@@ -149,9 +149,9 @@ var FsFroalaLoaderService = /** @class */ (function () {
149
149
  }
150
150
  this._load();
151
151
  }
152
- Object.defineProperty(FsFroalaLoaderService.prototype, "ready$", {
152
+ Object.defineProperty(FsFroalaLoaderService.prototype, "loaded$", {
153
153
  get: function () {
154
- return this._ready$;
154
+ return this._loaded$;
155
155
  },
156
156
  enumerable: true,
157
157
  configurable: true
@@ -226,6 +226,7 @@ var FsHtmlEditorComponent = /** @class */ (function () {
226
226
  this.config = {};
227
227
  this.initialized = false;
228
228
  this._initialize$ = new ReplaySubject();
229
+ this._froalaReady$ = new BehaviorSubject(null);
229
230
  this._destroy$ = new Subject();
230
231
  this.onChange = function (data) { };
231
232
  this.onTouched = function () { };
@@ -252,9 +253,9 @@ var FsHtmlEditorComponent = /** @class */ (function () {
252
253
  enumerable: true,
253
254
  configurable: true
254
255
  });
255
- Object.defineProperty(FsHtmlEditorComponent.prototype, "froalaReady$", {
256
+ Object.defineProperty(FsHtmlEditorComponent.prototype, "froalaLoaded$", {
256
257
  get: function () {
257
- return this._fr.ready$;
258
+ return this._fr.loaded$;
258
259
  },
259
260
  enumerable: true,
260
261
  configurable: true
@@ -284,96 +285,9 @@ var FsHtmlEditorComponent = /** @class */ (function () {
284
285
  if (options === void 0) { options = {}; }
285
286
  var config = this._createConfig();
286
287
  this._initPlugins(config);
287
- this.el.innerHTML = this._html;
288
+ // this.el.innerHTML = this._html || '';
288
289
  this._editor = new this._fr.FroalaEditor(this.el, this._createOptions(), function () {
289
- _this._cdRef.markForCheck();
290
- if (config.disabled) {
291
- _this.disable();
292
- }
293
- if (config.froalaConfig.events) {
294
- if (config.froalaConfig.events.initialized) {
295
- config.froalaConfig.events.initialized();
296
- }
297
- }
298
- _this._editor.events.on('focus', function () {
299
- _this.classFocused = true;
300
- _this._cdRef.markForCheck();
301
- });
302
- _this._editor.events.on('blur', function () {
303
- _this.classFocused = false;
304
- _this._cdRef.markForCheck();
305
- });
306
- _this._editor.events.on('contentChanged', function () {
307
- var editorHTML = _this._editor.html.get();
308
- if (_this.html !== editorHTML) {
309
- _this._change(editorHTML);
310
- }
311
- });
312
- _this._editor.events.on('paste.afterCleanup', function (html) {
313
- var div = document.createElement('div');
314
- div.innerHTML = html;
315
- div.querySelectorAll('*')
316
- .forEach(function (el) {
317
- for (var i = 0; i < el.attributes.length; i++) {
318
- var name_1 = el.attributes[0].name;
319
- if (name_1 !== 'href') {
320
- el.removeAttribute(name_1);
321
- }
322
- }
323
- });
324
- return div.innerHTML;
325
- });
326
- _this._editor.events.on('keydown', function () {
327
- _this.onTouched();
328
- });
329
- if (_this.config.image && _this.config.image.upload) {
330
- _this._editor.events.on('image.beforePasteUpload', function (image) {
331
- fetch(image.getAttribute('src'))
332
- .then(function (res) {
333
- res.blob()
334
- .then(function (blob) {
335
- _this._processImageUpload(blob)
336
- .pipe(takeUntil(_this._destroy$))
337
- .subscribe(function (url) {
338
- image.setAttribute('src', url);
339
- image.removeAttribute('data-fr-image-pasted');
340
- });
341
- });
342
- });
343
- return false;
344
- });
345
- _this._editor.events.on('image.beforeUpload', function (blobs) {
346
- _this._processImageUpload(blobs[0])
347
- .pipe(takeUntil(_this._destroy$))
348
- .subscribe(function (url) {
349
- _this.editor.image.insert(url, null, null, _this.editor.image.get());
350
- });
351
- return false;
352
- });
353
- }
354
- if (_this.el.querySelector('.fr-second-toolbar')) {
355
- _this.el.querySelector('.fr-second-toolbar').remove();
356
- }
357
- var selection = options.selection;
358
- if (selection) {
359
- var node = Array.from(_this.el.querySelectorAll('.fr-element *')).find(function (node) {
360
- return selection.node === node.textContent;
361
- });
362
- if (node) {
363
- var range = document.createRange();
364
- var sel = window.getSelection();
365
- range.setStart(_this._getTextNode(node), selection.offset);
366
- range.collapse(true);
367
- sel.removeAllRanges();
368
- sel.addRange(range);
369
- }
370
- else if (_this.config.autofocus) {
371
- _this.focus();
372
- }
373
- }
374
- else if (_this.config.autofocus) {
375
- _this.focus();
376
- }
290
+ _this._froalaReady$.next({ config: config, options: options });
377
291
  });
378
292
  };
379
293
  FsHtmlEditorComponent.prototype._processImageUpload = function (blob) {
@@ -381,8 +295,9 @@ var FsHtmlEditorComponent = /** @class */ (function () {
381
295
  var processor = new FileProcessor();
382
296
  var file = new FsFile(blob);
383
297
  return processor.process([file], this.config.image)
384
- .pipe(switchMap(function (img) {
385
- return _this.config.image.upload(img.file);
298
+ .pipe(switchMap(function (_a) {
299
+ var _b = __read(_a, 1), f = _b[0];
300
+ return _this.config.image.upload(f.file);
386
301
  }));
387
302
  };
388
303
  FsHtmlEditorComponent.prototype._getTextNode = function (node) {
@@ -458,23 +373,15 @@ var FsHtmlEditorComponent = /** @class */ (function () {
458
373
  this.writeValue(html);
459
374
  };
460
375
  FsHtmlEditorComponent.prototype.writeValue = function (html) {
461
- var _this = this;
462
376
  this._html = html || '';
463
- this._cdRef.markForCheck();
464
- // SP-T2298 timeout needed for the case, when froala was already initated and
465
- // second instance opened in dialog/drawer. In this case init step pass much faster, writeValue trigger
466
- // after init and froala ignore new html. At the same time froala was initied but editor not yet, and next
467
- // code doesn't work without timeout. We've got time range when too late for initiate value, and to early
468
- // for change event.
469
- setTimeout(function () {
470
- if (_this.editor && _this.editor.html) {
471
- try {
472
- _this.editor.html.set(_this._html);
473
- }
474
- catch (e) {
475
- }
377
+ if (this.editor && this.editor.html) {
378
+ try {
379
+ this.editor.html.set(this._html);
476
380
  }
477
- });
381
+ catch (e) {
382
+ }
383
+ }
384
+ this._cdRef.markForCheck();
478
385
  };
479
386
  FsHtmlEditorComponent.prototype.registerOnChange = function (fn) {
480
387
  this.onChange = fn;
@@ -500,7 +407,7 @@ var FsHtmlEditorComponent = /** @class */ (function () {
500
407
  return merge({ froalaConfig: {} }, this._defaultConfig, this.config);
501
408
  };
502
409
  FsHtmlEditorComponent.prototype._change = function (html) {
503
- this._html = html;
410
+ // this._html = html;
504
411
  this.onChange(html);
505
412
  };
506
413
  FsHtmlEditorComponent.prototype._initPlugins = function (config) {
@@ -596,9 +503,8 @@ var FsHtmlEditorComponent = /** @class */ (function () {
596
503
  };
597
504
  FsHtmlEditorComponent.prototype._listenLazyInit = function () {
598
505
  var _this = this;
599
- this.froalaReady$
600
- .pipe(filter(function (ready) { return ready; }), switchMap(function () { return _this._initialize$; }))
601
- .subscribe(function () {
506
+ this.froalaLoaded$
507
+ .pipe(filter(function (ready) { return ready; }), switchMap(function () { return _this._initialize$; }), tap(function () {
602
508
  var selection = window.getSelection();
603
509
  var options = {};
604
510
  if (selection.baseNode) {
@@ -608,7 +514,107 @@ var FsHtmlEditorComponent = /** @class */ (function () {
608
514
  };
609
515
  }
610
516
  _this.initialize(options);
517
+ }), switchMap(function () { return _this._froalaReady$; }), filter(function (data) { return !!data; }), tap(function (_a) {
518
+ var config = _a.config, options = _a.options;
519
+ _this._setupFroala(config, options);
520
+ }))
521
+ .subscribe();
522
+ };
523
+ FsHtmlEditorComponent.prototype._contentChanged = function () {
524
+ var editorHTML = this._editor.html.get();
525
+ if (this.html !== editorHTML) {
526
+ this._change(editorHTML);
527
+ }
528
+ };
529
+ FsHtmlEditorComponent.prototype._setupFroala = function (config, options) {
530
+ var _this = this;
531
+ this._cdRef.markForCheck();
532
+ this.setHtml(this._html);
533
+ if (config.disabled) {
534
+ this.disable();
535
+ }
536
+ if (config.froalaConfig.events) {
537
+ if (config.froalaConfig.events.initialized) {
538
+ config.froalaConfig.events.initialized();
539
+ }
540
+ }
541
+ this._editor.events.on('focus', function () {
542
+ _this.classFocused = true;
543
+ _this._cdRef.markForCheck();
544
+ });
545
+ this._editor.events.on('blur', function () {
546
+ _this.classFocused = false;
547
+ _this._cdRef.markForCheck();
611
548
  });
549
+ this._editor.events.on('contentChanged', function () {
550
+ _this._contentChanged();
551
+ });
552
+ this._editor.events.on('paste.afterCleanup', function (html) {
553
+ var div = document.createElement('div');
554
+ div.innerHTML = html;
555
+ div.querySelectorAll('*')
556
+ .forEach(function (el) {
557
+ for (var i = 0; i < el.attributes.length; i++) {
558
+ var name_1 = el.attributes[0].name;
559
+ if (name_1 !== 'href') {
560
+ el.removeAttribute(name_1);
561
+ }
562
+ }
563
+ });
564
+ return div.innerHTML;
565
+ });
566
+ this._editor.events.on('keydown', function () {
567
+ _this.onTouched();
568
+ });
569
+ if (this.config.image && this.config.image.upload) {
570
+ this._editor.events.on('image.beforePasteUpload', function (image) {
571
+ fetch(image.getAttribute('src'))
572
+ .then(function (res) {
573
+ res.blob()
574
+ .then(function (blob) {
575
+ _this._processImageUpload(blob)
576
+ .pipe(takeUntil(_this._destroy$))
577
+ .subscribe(function (url) {
578
+ image.setAttribute('src', url);
579
+ image.removeAttribute('data-fr-image-pasted');
580
+ _this._contentChanged();
581
+ });
582
+ });
583
+ });
584
+ return false;
585
+ });
586
+ this._editor.events.on('image.beforeUpload', function (blobs) {
587
+ _this._processImageUpload(blobs[0])
588
+ .pipe(takeUntil(_this._destroy$))
589
+ .subscribe(function (url) {
590
+ _this.editor.image.insert(url, null, null, _this.editor.image.get());
591
+ });
592
+ return false;
593
+ });
594
+ }
595
+ if (this.el.querySelector('.fr-second-toolbar')) {
596
+ this.el.querySelector('.fr-second-toolbar').remove();
597
+ }
598
+ var selection = options.selection;
599
+ if (selection) {
600
+ var node = Array.from(this.el.querySelectorAll('.fr-element *')).find(function (node) {
601
+ return selection.node === node.textContent;
602
+ });
603
+ if (node) {
604
+ var range = document.createRange();
605
+ var sel = window.getSelection();
606
+ range.setStart(this._getTextNode(node), selection.offset);
607
+ range.collapse(true);
608
+ sel.removeAllRanges();
609
+ sel.addRange(range);
610
+ }
611
+ else if (this.config.autofocus) {
612
+ this.focus();
613
+ }
614
+ }
615
+ else if (this.config.autofocus) {
616
+ this.focus();
617
+ }
612
618
  };
613
619
  var FsHtmlEditorComponent_1;
614
620
  FsHtmlEditorComponent.ctorParameters = function () { return [
@@ -635,7 +641,7 @@ var FsHtmlEditorComponent = /** @class */ (function () {
635
641
  FsHtmlEditorComponent = FsHtmlEditorComponent_1 = __decorate([
636
642
  Component({
637
643
  selector: 'fs-html-editor',
638
- template: "<div class=\"fs-html-editor-default\">\n <ng-container *ngIf=\"initialized\">\n <ng-container *fsSkeleton=\"(froalaReady$ | 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",
644
+ 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",
639
645
  providers: [
640
646
  {
641
647
  provide: NG_VALUE_ACCESSOR,
@@ -649,7 +655,7 @@ var FsHtmlEditorComponent = /** @class */ (function () {
649
655
  },
650
656
  ],
651
657
  changeDetection: ChangeDetectionStrategy.OnPush,
652
- 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-dropdown-menu .fr-dropdown-wrapper,:host ::ng-deep .fr-dropdown:after,:host ::ng-deep .fr-more-toolbar,:host ::ng-deep .fr-toolbar{transition:none!important}:host ::ng-deep .fr-toolbar{position:-webkit-sticky;position:sticky;z-index:2;border-radius:0;background-color:transparent}:host ::ng-deep .fr-toolbar .fr-btn-grp{margin:0 20px 0 0;position:relative}:host ::ng-deep .fr-toolbar .fr-btn-grp:nth-child(1):after,:host ::ng-deep .fr-toolbar .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 div:first-of-type:before{border:none}:host ::ng-deep .fr-toolbar.fr-toolbar-open .fr-newline{height:auto}:host ::ng-deep .fr-toolbar .fr-btn-grp:first-child{margin-left:0}:host ::ng-deep .fr-toolbar.fr-top{border:0}:host ::ng-deep .fr-toolbar .fr-newline{margin:0}:host ::ng-deep .fr-toolbar .fr-more-toolbar{z-index:auto}:host ::ng-deep .fr-toolbar .fr-command.fr-btn{z-index:auto}:host ::ng-deep .fr-toolbar .fr-command.fr-btn.fr-dropdown:after{right:3px}:host ::ng-deep .fr-toolbar .fr-command.fr-btn.fr-dropdown.fr-selection span{margin-right:24px}:host ::ng-deep .fr-toolbar .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 rgba(0,0,0,.2),0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12);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}"]
658
+ 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-dropdown-menu .fr-dropdown-wrapper,:host ::ng-deep .fr-dropdown:after,:host ::ng-deep .fr-more-toolbar,:host ::ng-deep .fr-toolbar{transition:none!important}:host ::ng-deep .fr-toolbar{position:-webkit-sticky;position:sticky;z-index:2;border-radius:0;background-color:transparent}:host ::ng-deep .fr-toolbar .fr-btn-grp{margin:0 20px 0 0}:host ::ng-deep .fr-toolbar .fr-btn-grp:nth-child(1):after,:host ::ng-deep .fr-toolbar .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 div:first-of-type:before{border:none}:host ::ng-deep .fr-toolbar.fr-toolbar-open .fr-newline{height:auto}:host ::ng-deep .fr-toolbar .fr-btn-grp:first-child{margin-left:0}:host ::ng-deep .fr-toolbar.fr-top{border:0}:host ::ng-deep .fr-toolbar .fr-newline{margin:0}:host ::ng-deep .fr-toolbar .fr-more-toolbar{z-index:auto}:host ::ng-deep .fr-toolbar .fr-command.fr-btn{z-index:auto}:host ::ng-deep .fr-toolbar .fr-command.fr-btn.fr-dropdown:after{right:3px}:host ::ng-deep .fr-toolbar .fr-command.fr-btn.fr-dropdown.fr-selection span{margin-right:24px}:host ::ng-deep .fr-toolbar .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 rgba(0,0,0,.2),0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12);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}"]
653
659
  }),
654
660
  __param(0, Optional()), __param(0, Inject(FS_HTML_EDITOR_CONFIG)),
655
661
  __metadata("design:paramtypes", [Object, ChangeDetectorRef,