@firestitch/html-editor 9.5.4 → 9.5.7

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.
@@ -4,8 +4,8 @@ import { CommonModule } from '@angular/common';
4
4
  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
- import { Observable, BehaviorSubject, combineLatest, ReplaySubject, Subject } from 'rxjs';
8
- import { shareReplay, map, tap, concatMap, takeUntil, switchMap, filter } from 'rxjs/operators';
7
+ import { Observable, BehaviorSubject, combineLatest, ReplaySubject, Subject, fromEventPattern } from 'rxjs';
8
+ import { shareReplay, map, tap, concatMap, switchMap, filter, startWith, distinctUntilChanged, skip, 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,94 +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
- _this._contentChanged();
308
- });
309
- _this._editor.events.on('paste.afterCleanup', function (html) {
310
- var div = document.createElement('div');
311
- div.innerHTML = html;
312
- div.querySelectorAll('*')
313
- .forEach(function (el) {
314
- for (var i = 0; i < el.attributes.length; i++) {
315
- var name_1 = el.attributes[0].name;
316
- if (name_1 !== 'href') {
317
- el.removeAttribute(name_1);
318
- }
319
- }
320
- });
321
- return div.innerHTML;
322
- });
323
- _this._editor.events.on('keydown', function () {
324
- _this.onTouched();
325
- });
326
- if (_this.config.image && _this.config.image.upload) {
327
- _this._editor.events.on('image.beforePasteUpload', function (image) {
328
- fetch(image.getAttribute('src'))
329
- .then(function (res) {
330
- res.blob()
331
- .then(function (blob) {
332
- _this._processImageUpload(blob)
333
- .pipe(takeUntil(_this._destroy$))
334
- .subscribe(function (url) {
335
- image.setAttribute('src', url);
336
- image.removeAttribute('data-fr-image-pasted');
337
- _this._contentChanged();
338
- });
339
- });
340
- });
341
- return false;
342
- });
343
- _this._editor.events.on('image.beforeUpload', function (blobs) {
344
- _this._processImageUpload(blobs[0])
345
- .pipe(takeUntil(_this._destroy$))
346
- .subscribe(function (url) {
347
- _this.editor.image.insert(url, null, null, _this.editor.image.get());
348
- });
349
- return false;
350
- });
351
- }
352
- if (_this.el.querySelector('.fr-second-toolbar')) {
353
- _this.el.querySelector('.fr-second-toolbar').remove();
354
- }
355
- var selection = options.selection;
356
- if (selection) {
357
- var node = Array.from(_this.el.querySelectorAll('.fr-element *')).find(function (node) {
358
- return selection.node === node.textContent;
359
- });
360
- if (node) {
361
- var range = document.createRange();
362
- var sel = window.getSelection();
363
- range.setStart(_this._getTextNode(node), selection.offset);
364
- range.collapse(true);
365
- sel.removeAllRanges();
366
- sel.addRange(range);
367
- }
368
- else if (_this.config.autofocus) {
369
- _this.focus();
370
- }
371
- }
372
- else if (_this.config.autofocus) {
373
- _this.focus();
374
- }
290
+ _this._froalaReady$.next({ config: config, options: options });
375
291
  });
376
292
  };
377
293
  FsHtmlEditorComponent.prototype._processImageUpload = function (blob) {
@@ -457,23 +373,15 @@ var FsHtmlEditorComponent = /** @class */ (function () {
457
373
  this.writeValue(html);
458
374
  };
459
375
  FsHtmlEditorComponent.prototype.writeValue = function (html) {
460
- var _this = this;
461
376
  this._html = html || '';
462
- this._cdRef.markForCheck();
463
- // SP-T2298 timeout needed for the case, when froala was already initated and
464
- // second instance opened in dialog/drawer. In this case init step pass much faster, writeValue trigger
465
- // after init and froala ignore new html. At the same time froala was initied but editor not yet, and next
466
- // code doesn't work without timeout. We've got time range when too late for initiate value, and to early
467
- // for change event.
468
- setTimeout(function () {
469
- if (_this.editor && _this.editor.html) {
470
- try {
471
- _this.editor.html.set(_this._html);
472
- }
473
- catch (e) {
474
- }
377
+ if (this.editor && this.editor.html) {
378
+ try {
379
+ this.editor.html.set(this._html);
475
380
  }
476
- });
381
+ catch (e) {
382
+ }
383
+ }
384
+ this._cdRef.markForCheck();
477
385
  };
478
386
  FsHtmlEditorComponent.prototype.registerOnChange = function (fn) {
479
387
  this.onChange = fn;
@@ -499,7 +407,7 @@ var FsHtmlEditorComponent = /** @class */ (function () {
499
407
  return merge({ froalaConfig: {} }, this._defaultConfig, this.config);
500
408
  };
501
409
  FsHtmlEditorComponent.prototype._change = function (html) {
502
- this._html = html;
410
+ // this._html = html;
503
411
  this.onChange(html);
504
412
  };
505
413
  FsHtmlEditorComponent.prototype._initPlugins = function (config) {
@@ -595,9 +503,8 @@ var FsHtmlEditorComponent = /** @class */ (function () {
595
503
  };
596
504
  FsHtmlEditorComponent.prototype._listenLazyInit = function () {
597
505
  var _this = this;
598
- this.froalaReady$
599
- .pipe(filter(function (ready) { return ready; }), switchMap(function () { return _this._initialize$; }))
600
- .subscribe(function () {
506
+ this.froalaLoaded$
507
+ .pipe(filter(function (ready) { return ready; }), switchMap(function () { return _this._initialize$; }), tap(function () {
601
508
  var selection = window.getSelection();
602
509
  var options = {};
603
510
  if (selection.baseNode) {
@@ -607,7 +514,11 @@ var FsHtmlEditorComponent = /** @class */ (function () {
607
514
  };
608
515
  }
609
516
  _this.initialize(options);
610
- });
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();
611
522
  };
612
523
  FsHtmlEditorComponent.prototype._contentChanged = function () {
613
524
  var editorHTML = this._editor.html.get();
@@ -615,6 +526,106 @@ var FsHtmlEditorComponent = /** @class */ (function () {
615
526
  this._change(editorHTML);
616
527
  }
617
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();
548
+ });
549
+ fromEventPattern(function (handler) {
550
+ _this._editor.events.on('contentChanged', handler);
551
+ }, function () { })
552
+ .pipe(startWith(this._html), map(function () { return _this.editor.html.get(); }), distinctUntilChanged(), skip(1))
553
+ .subscribe(function () {
554
+ _this._contentChanged();
555
+ });
556
+ // this._editor.events.on('contentChanged', () => {
557
+ // console.log('test');
558
+ // if (!this._firstChange) {
559
+ // this._contentChanged();
560
+ // }
561
+ // });
562
+ this._editor.events.on('paste.afterCleanup', function (html) {
563
+ var div = document.createElement('div');
564
+ div.innerHTML = html;
565
+ div.querySelectorAll('*')
566
+ .forEach(function (el) {
567
+ for (var i = 0; i < el.attributes.length; i++) {
568
+ var name_1 = el.attributes[0].name;
569
+ if (name_1 !== 'href') {
570
+ el.removeAttribute(name_1);
571
+ }
572
+ }
573
+ });
574
+ return div.innerHTML;
575
+ });
576
+ this._editor.events.on('keydown', function () {
577
+ _this.onTouched();
578
+ });
579
+ if (this.config.image && this.config.image.upload) {
580
+ this._editor.events.on('image.beforePasteUpload', function (image) {
581
+ fetch(image.getAttribute('src'))
582
+ .then(function (res) {
583
+ res.blob()
584
+ .then(function (blob) {
585
+ _this._processImageUpload(blob)
586
+ .pipe(takeUntil(_this._destroy$))
587
+ .subscribe(function (url) {
588
+ image.setAttribute('src', url);
589
+ image.removeAttribute('data-fr-image-pasted');
590
+ _this._contentChanged();
591
+ });
592
+ });
593
+ });
594
+ return false;
595
+ });
596
+ this._editor.events.on('image.beforeUpload', function (blobs) {
597
+ _this._processImageUpload(blobs[0])
598
+ .pipe(takeUntil(_this._destroy$))
599
+ .subscribe(function (url) {
600
+ _this.editor.image.insert(url, null, null, _this.editor.image.get());
601
+ });
602
+ return false;
603
+ });
604
+ }
605
+ if (this.el.querySelector('.fr-second-toolbar')) {
606
+ this.el.querySelector('.fr-second-toolbar').remove();
607
+ }
608
+ var selection = options.selection;
609
+ if (selection) {
610
+ var node = Array.from(this.el.querySelectorAll('.fr-element *')).find(function (node) {
611
+ return selection.node === node.textContent;
612
+ });
613
+ if (node) {
614
+ var range = document.createRange();
615
+ var sel = window.getSelection();
616
+ range.setStart(this._getTextNode(node), selection.offset);
617
+ range.collapse(true);
618
+ sel.removeAllRanges();
619
+ sel.addRange(range);
620
+ }
621
+ else if (this.config.autofocus) {
622
+ this.focus();
623
+ }
624
+ }
625
+ else if (this.config.autofocus) {
626
+ this.focus();
627
+ }
628
+ };
618
629
  var FsHtmlEditorComponent_1;
619
630
  FsHtmlEditorComponent.ctorParameters = function () { return [
620
631
  { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [FS_HTML_EDITOR_CONFIG,] }] },
@@ -640,7 +651,7 @@ var FsHtmlEditorComponent = /** @class */ (function () {
640
651
  FsHtmlEditorComponent = FsHtmlEditorComponent_1 = __decorate([
641
652
  Component({
642
653
  selector: 'fs-html-editor',
643
- 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",
654
+ 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",
644
655
  providers: [
645
656
  {
646
657
  provide: NG_VALUE_ACCESSOR,
@@ -654,7 +665,7 @@ var FsHtmlEditorComponent = /** @class */ (function () {
654
665
  },
655
666
  ],
656
667
  changeDetection: ChangeDetectionStrategy.OnPush,
657
- 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}"]
668
+ 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:#fff}: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}"]
658
669
  }),
659
670
  __param(0, Optional()), __param(0, Inject(FS_HTML_EDITOR_CONFIG)),
660
671
  __metadata("design:paramtypes", [Object, ChangeDetectorRef,