croco-html 2.4.0 → 2.5.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 (68) hide show
  1. package/README.md +2 -2
  2. package/esm2022/lib/components/add-files-btn/add-files-btn.component.mjs +3 -3
  3. package/esm2022/lib/components/editor/external-video-block/external-video-block.component.mjs +14 -23
  4. package/esm2022/lib/components/editor/external-video-block/vk-video-player/vk-video-player.component.mjs +20 -0
  5. package/esm2022/lib/components/editor/html-raw-editor/html-raw-editor.component.mjs +7 -8
  6. package/esm2022/lib/components/editor/image-editor/image-editor.component.mjs +9 -10
  7. package/esm2022/lib/components/editor/index.mjs +1 -1
  8. package/esm2022/lib/components/editor/main-editor/main-editor.component.mjs +13 -14
  9. package/esm2022/lib/components/editor/main-editor-block/main-editor-block.component.mjs +12 -13
  10. package/esm2022/lib/components/editor/text-editor/text-editor.component.mjs +9 -10
  11. package/esm2022/lib/components/editor/visual-editor/DefaultAligments.mjs +1 -1
  12. package/esm2022/lib/components/editor/visual-editor/DefaultTags.mjs +2 -2
  13. package/esm2022/lib/components/editor/visual-editor/visual-editor.component.mjs +27 -24
  14. package/esm2022/lib/components/file-id-select/file-id-select.component.mjs +3 -3
  15. package/esm2022/lib/components/index.mjs +1 -1
  16. package/esm2022/lib/components/upload-files-btn/upload-files-btn.component.mjs +3 -3
  17. package/esm2022/lib/components/xml-tags/file-image-tag-view/file-image-tag-view.component.mjs +3 -3
  18. package/esm2022/lib/components/xml-tags/index.mjs +1 -1
  19. package/esm2022/lib/components/xml-tags/xml-tag-external-video/resize-observable.mjs +1 -1
  20. package/esm2022/lib/components/xml-tags/xml-tag-external-video/xml-tag-external-video.component.mjs +22 -6
  21. package/esm2022/lib/components/xml-tags/xml-tag-header-inner-text-view/xml-tag-header-inner-text-view.component.mjs +3 -4
  22. package/esm2022/lib/components/xml-tags/xml-tag-header-text-view/xml-tag-header-text-view.component.mjs +4 -5
  23. package/esm2022/lib/components/xml-tags/xml-tag-html-view/xml-tag-html-view.component.mjs +3 -3
  24. package/esm2022/lib/components/xml-tags/xml-tag-rich-text-view/xml-tag-rich-text-view.component.mjs +4 -5
  25. package/esm2022/lib/components/xml-tags/xml-tag-table-view/xml-tag-table-view.component.mjs +4 -5
  26. package/esm2022/lib/components/xml-tags/xml-tag-text-view/xml-tag-text-view.component.mjs +3 -4
  27. package/esm2022/lib/components/xml-tags/xml-tag-view/xml-tag-view.component.mjs +12 -11
  28. package/esm2022/lib/croco-html.module.mjs +6 -3
  29. package/esm2022/lib/extensions/AngularMaterialTableMethods.mjs +1 -1
  30. package/esm2022/lib/extensions/BodyTagsExtensions.mjs +8 -7
  31. package/esm2022/lib/extensions/BootstrapTableMethods.mjs +1 -1
  32. package/esm2022/lib/extensions/HtmlExtractionMethods.mjs +1 -1
  33. package/esm2022/lib/extensions/HtmlRawTagDataConsts.mjs +1 -1
  34. package/esm2022/lib/extensions/ImageMethods.mjs +1 -1
  35. package/esm2022/lib/extensions/InterfaceBlock.mjs +1 -1
  36. package/esm2022/lib/extensions/TableBuilder.mjs +1 -1
  37. package/esm2022/lib/extensions/TableMethods.mjs +1 -1
  38. package/esm2022/lib/extensions/Tags.mjs +20 -0
  39. package/esm2022/lib/extensions/TextMethods.mjs +11 -2
  40. package/esm2022/lib/extensions/TextSimpleMethods.mjs +1 -1
  41. package/esm2022/lib/extensions/VideoMethods.mjs +12 -1
  42. package/esm2022/lib/extensions/XmlExtensions.mjs +1 -1
  43. package/esm2022/lib/extensions/index.mjs +1 -1
  44. package/esm2022/lib/index.mjs +1 -1
  45. package/esm2022/lib/models/models.mjs +1 -1
  46. package/esm2022/lib/pipes/RichTextToHtmlPipe.mjs +1 -1
  47. package/esm2022/lib/pipes/TagToSpanPipe.mjs +1 -1
  48. package/esm2022/lib/pipes/ToHtmlBodyTagsPipe.mjs +1 -1
  49. package/esm2022/lib/pipes/ToPreviewHtmlPipe.mjs +1 -1
  50. package/esm2022/lib/pipes/index.mjs +1 -1
  51. package/esm2022/lib/pipes/to-preview.pipe.mjs +1 -1
  52. package/esm2022/lib/services/file-upload.service.mjs +1 -1
  53. package/esm2022/lib/services/files-query.service.mjs +1 -1
  54. package/esm2022/public-api.mjs +1 -1
  55. package/fesm2022/croco-html.mjs +970 -903
  56. package/fesm2022/croco-html.mjs.map +1 -1
  57. package/lib/components/editor/external-video-block/external-video-block.component.d.ts +4 -6
  58. package/lib/components/editor/external-video-block/vk-video-player/vk-video-player.component.d.ts +10 -0
  59. package/lib/components/editor/main-editor-block/main-editor-block.component.d.ts +0 -1
  60. package/lib/components/editor/visual-editor/visual-editor.component.d.ts +9 -0
  61. package/lib/components/xml-tags/xml-tag-external-video/xml-tag-external-video.component.d.ts +3 -1
  62. package/lib/components/xml-tags/xml-tag-view/xml-tag-view.component.d.ts +1 -1
  63. package/lib/croco-html.module.d.ts +2 -1
  64. package/lib/extensions/Tags.d.ts +15 -0
  65. package/lib/extensions/TextMethods.d.ts +10 -1
  66. package/lib/extensions/VideoMethods.d.ts +5 -0
  67. package/lib/index.d.ts +4 -4
  68. package/package.json +1 -1
@@ -1,47 +1,46 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { Injectable, Inject, EventEmitter, Component, ViewChild, Input, Output, signal, ChangeDetectionStrategy, ViewEncapsulation, Pipe, NgModule } from '@angular/core';
3
- import * as i2 from '@angular/material/button';
3
+ import * as i1$1 from '@angular/material/button';
4
4
  import { MatButtonModule } from '@angular/material/button';
5
5
  import * as i1 from '@angular/common/http';
6
6
  import { HttpEventType, HttpResponse } from '@angular/common/http';
7
7
  import { throwError, Observable, map, distinctUntilChanged } from 'rxjs';
8
8
  import { filter, switchMap } from 'rxjs/operators';
9
- import * as i1$1 from '@angular/common';
10
- import { CommonModule } from '@angular/common';
11
- import * as i2$2 from '@angular/forms';
9
+ import * as i1$4 from '@angular/forms';
12
10
  import { FormsModule, ReactiveFormsModule } from '@angular/forms';
13
- import * as i3 from '@angular/material/form-field';
11
+ import * as i2 from '@angular/material/form-field';
14
12
  import { MatFormFieldModule } from '@angular/material/form-field';
15
- import * as i4 from '@angular/material/input';
13
+ import * as i3 from '@angular/material/input';
16
14
  import { MatInputModule } from '@angular/material/input';
17
15
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
18
- import * as i2$1 from '@angular/youtube-player';
16
+ import * as i1$3 from '@angular/youtube-player';
19
17
  import { YouTubePlayerModule } from '@angular/youtube-player';
20
- import * as i5 from '@angular/cdk/text-field';
21
- import * as i5$1 from '@angular/material/icon';
18
+ import * as i1$2 from '@angular/platform-browser';
19
+ import * as i4 from '@angular/cdk/text-field';
20
+ import * as i4$1 from '@angular/material/icon';
22
21
  import { MatIconModule } from '@angular/material/icon';
23
- import * as i6 from '@angular/material/button-toggle';
22
+ import * as i5 from '@angular/material/button-toggle';
24
23
  import { MatButtonToggleModule } from '@angular/material/button-toggle';
25
24
  import * as i3$1 from '@ng-select/ng-select';
26
25
  import { NgSelectModule } from '@ng-select/ng-select';
27
- import * as i1$3 from 'ngx-clipboard';
28
- import * as i2$3 from '@angular/material/snack-bar';
26
+ import * as i1$5 from 'ngx-clipboard';
27
+ import * as i2$1 from '@angular/material/snack-bar';
29
28
  import { MatSnackBarModule } from '@angular/material/snack-bar';
30
- import * as i6$2 from '@angular/material/tabs';
29
+ import * as i5$2 from '@angular/material/tabs';
31
30
  import { MatTabsModule } from '@angular/material/tabs';
32
- import * as i5$2 from '@angular/material/card';
31
+ import * as i4$2 from '@angular/material/card';
33
32
  import { MatCardModule } from '@angular/material/card';
34
- import * as i1$2 from '@angular/platform-browser';
35
- import * as i11 from '@angular/cdk/drag-drop';
33
+ import * as i10 from '@angular/cdk/drag-drop';
36
34
  import { moveItemInArray, DragDropModule } from '@angular/cdk/drag-drop';
37
- import * as i4$1 from '@angular/material/progress-spinner';
35
+ import * as i3$2 from '@angular/material/progress-spinner';
38
36
  import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
39
- import * as i6$1 from '@angular/material/select';
37
+ import * as i5$1 from '@angular/material/select';
40
38
  import { MatSelectModule } from '@angular/material/select';
41
- import * as i7 from '@angular/material/core';
39
+ import * as i6 from '@angular/material/core';
42
40
  import { MatNativeDateModule } from '@angular/material/core';
43
- import * as i2$4 from '@angular/material/table';
41
+ import * as i1$6 from '@angular/material/table';
44
42
  import { MatTableModule } from '@angular/material/table';
43
+ import { CommonModule } from '@angular/common';
45
44
  import * as i38 from '@angular/material/tooltip';
46
45
  import { MatTooltipModule } from '@angular/material/tooltip';
47
46
  import * as i39 from '@angular/material/checkbox';
@@ -197,11 +196,11 @@ class UploadFilesBtnComponent {
197
196
  ngOnInit() {
198
197
  }
199
198
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: UploadFilesBtnComponent, deps: [{ token: FileUploadService }], target: i0.ɵɵFactoryTarget.Component }); }
200
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.4", type: UploadFilesBtnComponent, selector: "croco-app-upload-files-btn", inputs: { extAccepts: "extAccepts", isMultiple: "isMultiple", btnText: "btnText", createLocalCopiesNow: "createLocalCopiesNow", hidden: "hidden" }, outputs: { postFilesStarted: "postFilesStarted", onFilesUploaded: "onFilesUploaded" }, viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["filesInput"], descendants: true }], ngImport: i0, template: "<button [hidden]=\"hidden\" mat-raised-button color=\"primary\" (click)=\"filesInput.click()\">{{btnText}}</button>\r\n<input [hidden]=\"true\" [accept]=\"extAccepts\" [multiple]=\"isMultiple\" type=\"file\" #filesInput (change)=\"handleFileInput($event.target.files)\" />", styles: [""], dependencies: [{ kind: "component", type: i2.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }] }); }
199
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.4", type: UploadFilesBtnComponent, selector: "croco-app-upload-files-btn", inputs: { extAccepts: "extAccepts", isMultiple: "isMultiple", btnText: "btnText", createLocalCopiesNow: "createLocalCopiesNow", hidden: "hidden" }, outputs: { postFilesStarted: "postFilesStarted", onFilesUploaded: "onFilesUploaded" }, viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["filesInput"], descendants: true }], ngImport: i0, template: "<button [hidden]=\"hidden\" mat-raised-button color=\"primary\" (click)=\"filesInput.click()\">{{btnText}}</button>\n<input [hidden]=\"true\" [accept]=\"extAccepts\" [multiple]=\"isMultiple\" type=\"file\" #filesInput (change)=\"handleFileInput($event.target.files)\" />", styles: [""], dependencies: [{ kind: "component", type: i1$1.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }] }); }
201
200
  }
202
201
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: UploadFilesBtnComponent, decorators: [{
203
202
  type: Component,
204
- args: [{ selector: 'croco-app-upload-files-btn', template: "<button [hidden]=\"hidden\" mat-raised-button color=\"primary\" (click)=\"filesInput.click()\">{{btnText}}</button>\r\n<input [hidden]=\"true\" [accept]=\"extAccepts\" [multiple]=\"isMultiple\" type=\"file\" #filesInput (change)=\"handleFileInput($event.target.files)\" />" }]
203
+ args: [{ selector: 'croco-app-upload-files-btn', template: "<button [hidden]=\"hidden\" mat-raised-button color=\"primary\" (click)=\"filesInput.click()\">{{btnText}}</button>\n<input [hidden]=\"true\" [accept]=\"extAccepts\" [multiple]=\"isMultiple\" type=\"file\" #filesInput (change)=\"handleFileInput($event.target.files)\" />" }]
205
204
  }], ctorParameters: () => [{ type: FileUploadService }], propDecorators: { fileInput: [{
206
205
  type: ViewChild,
207
206
  args: ['filesInput']
@@ -255,11 +254,11 @@ class AddFilesBtnComponent {
255
254
  ngOnInit() {
256
255
  }
257
256
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: AddFilesBtnComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
258
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.4", type: AddFilesBtnComponent, selector: "croco-html-add-files-btn", outputs: { postFilesStarted: "postFilesStarted", filesTagsReady: "filesTagsReady" }, viewQueries: [{ propertyName: "fakeBtn", first: true, predicate: ["fakeBtn"], descendants: true }], ngImport: i0, template: "<div [hidden]=\"true\">\r\n <croco-app-upload-files-btn #fakeBtn (onFilesUploaded)=\"filesUploadedHandler($event)\"\r\n [btnText]=\"'\u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F'\" [createLocalCopiesNow]=\"true\"\r\n (postFilesStarted)=\"postFilesStartedEventHandler($event)\" [extAccepts]=\"'image/*'\"></croco-app-upload-files-btn>\r\n</div>\r\n\r\n<div>\r\n <button class=\"w-100\" (click)=\"handleClick()\" mat-stroked-button>\u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F</button>\r\n</div>", styles: [""], dependencies: [{ kind: "component", type: i2.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: UploadFilesBtnComponent, selector: "croco-app-upload-files-btn", inputs: ["extAccepts", "isMultiple", "btnText", "createLocalCopiesNow", "hidden"], outputs: ["postFilesStarted", "onFilesUploaded"] }] }); }
257
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.4", type: AddFilesBtnComponent, selector: "croco-html-add-files-btn", outputs: { postFilesStarted: "postFilesStarted", filesTagsReady: "filesTagsReady" }, viewQueries: [{ propertyName: "fakeBtn", first: true, predicate: ["fakeBtn"], descendants: true }], ngImport: i0, template: "<div [hidden]=\"true\">\n <croco-app-upload-files-btn #fakeBtn (onFilesUploaded)=\"filesUploadedHandler($event)\"\n [btnText]=\"'\u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F'\" [createLocalCopiesNow]=\"true\"\n (postFilesStarted)=\"postFilesStartedEventHandler($event)\" [extAccepts]=\"'image/*'\"></croco-app-upload-files-btn>\n</div>\n\n<div>\n <button class=\"w-100\" (click)=\"handleClick()\" mat-stroked-button>\u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F</button>\n</div>", styles: [""], dependencies: [{ kind: "component", type: i1$1.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: UploadFilesBtnComponent, selector: "croco-app-upload-files-btn", inputs: ["extAccepts", "isMultiple", "btnText", "createLocalCopiesNow", "hidden"], outputs: ["postFilesStarted", "onFilesUploaded"] }] }); }
259
258
  }
260
259
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: AddFilesBtnComponent, decorators: [{
261
260
  type: Component,
262
- args: [{ selector: 'croco-html-add-files-btn', template: "<div [hidden]=\"true\">\r\n <croco-app-upload-files-btn #fakeBtn (onFilesUploaded)=\"filesUploadedHandler($event)\"\r\n [btnText]=\"'\u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F'\" [createLocalCopiesNow]=\"true\"\r\n (postFilesStarted)=\"postFilesStartedEventHandler($event)\" [extAccepts]=\"'image/*'\"></croco-app-upload-files-btn>\r\n</div>\r\n\r\n<div>\r\n <button class=\"w-100\" (click)=\"handleClick()\" mat-stroked-button>\u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F</button>\r\n</div>" }]
261
+ args: [{ selector: 'croco-html-add-files-btn', template: "<div [hidden]=\"true\">\n <croco-app-upload-files-btn #fakeBtn (onFilesUploaded)=\"filesUploadedHandler($event)\"\n [btnText]=\"'\u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F'\" [createLocalCopiesNow]=\"true\"\n (postFilesStarted)=\"postFilesStartedEventHandler($event)\" [extAccepts]=\"'image/*'\"></croco-app-upload-files-btn>\n</div>\n\n<div>\n <button class=\"w-100\" (click)=\"handleClick()\" mat-stroked-button>\u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F</button>\n</div>" }]
263
262
  }], ctorParameters: () => [], propDecorators: { postFilesStarted: [{
264
263
  type: Output
265
264
  }], fakeBtn: [{
@@ -269,942 +268,1037 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImpor
269
268
  type: Output
270
269
  }] } });
271
270
 
272
- class ExternalVideoTagDataConsts {
273
- static { this.TagName = "external-video"; }
274
- static { this.VideoTypeAttrName = "type"; }
275
- static { this.LinkAttrName = "link"; }
276
- }
277
- class ExternalVideoSupportedTypes {
278
- static { this.Youtube = "youtube"; }
279
- }
280
- class VideoMethods {
281
- static ExtractExternalVideoTag(elem) {
282
- return {
283
- type: ExternalVideoTagDataConsts.TagName,
284
- data: {
285
- type: elem.getAttribute(ExternalVideoTagDataConsts.VideoTypeAttrName),
286
- link: elem.getAttribute(ExternalVideoTagDataConsts.LinkAttrName)
271
+ class AngularMaterialTableMethods {
272
+ static getAngularMaterialTableData(columns, rows) {
273
+ let data = [];
274
+ for (let rowIndex = 0; rowIndex < rows.length; rowIndex++) {
275
+ const row = rows[rowIndex];
276
+ var elem = {};
277
+ for (let columnIndex = 0; columnIndex < columns.length; columnIndex++) {
278
+ const column = columns[columnIndex];
279
+ elem[column] = row.columns[columnIndex].data.text;
287
280
  }
281
+ data.push(elem);
282
+ }
283
+ return {
284
+ displayedColumns: columns,
285
+ data: data,
288
286
  };
289
287
  }
290
- }
291
-
292
- function resizeObservable(elem, options) {
293
- return new Observable((subscriber) => {
294
- const resizeObserver = new ResizeObserver(([entry]) => {
295
- subscriber.next(entry);
296
- });
297
- resizeObserver.observe(elem, options);
298
- return function unsubscribe() {
299
- resizeObserver.unobserve(elem);
300
- };
301
- });
302
- }
303
-
304
- class XmlTagExternalVideoComponent {
305
- set data(value) {
306
- this.tagData = value.data;
307
- }
308
- ;
309
- set tagData(value) {
310
- this.videoId = this.getYouTubeId(value.link);
311
- }
312
- ;
313
- constructor(destroyRef) {
314
- this.destroyRef = destroyRef;
315
- this.playerWidth = signal(NaN);
316
- this.playerHeight = signal(NaN);
317
- }
318
- ngOnInit() {
319
- const youtubeIframeApiUrl = 'https://www.youtube.com/iframe_api';
320
- if (!document.querySelector(`script[src="${youtubeIframeApiUrl}"]`)) {
321
- // This code loads the IFrame Player API code asynchronously, according to the instructions at
322
- // https://developers.google.com/youtube/iframe_api_reference#Getting_Started
323
- const tag = document.createElement('script');
324
- tag.setAttribute('src', youtubeIframeApiUrl);
325
- document.body.appendChild(tag);
288
+ static checkHeaders(tableData) {
289
+ if (tableData.header === null) {
290
+ return {
291
+ isSucceeded: false,
292
+ message: "Необходимо указать заголовок таблицы"
293
+ };
326
294
  }
327
- if (this.playerContainerRef) {
328
- resizeObservable(this.playerContainerRef.nativeElement)
329
- .pipe(map(({ contentRect: { height, width } }) => ({ height, width })), distinctUntilChanged((a, b) => a.height === b.height && a.width === b.width), takeUntilDestroyed(this.destroyRef))
330
- .subscribe(({ height, width }) => {
331
- this.playerHeight.set(height);
332
- this.playerWidth.set(width);
333
- });
295
+ let columns = tableData.header.columns;
296
+ var uniqueDislayedColumns = columns.filter((v, i, a) => a.indexOf(v) === i);
297
+ if (uniqueDislayedColumns.length !== columns.length) {
298
+ return {
299
+ isSucceeded: false,
300
+ message: "Ошибка при обработке разметки таблицы. Обнаружены дубликаты заголовков."
301
+ };
334
302
  }
303
+ return {
304
+ isSucceeded: true,
305
+ message: "Ok"
306
+ };
335
307
  }
336
- getYouTubeId(youtubeLink) {
337
- //https://www.youtube.com/watch?v=l3KfbfkxJOU
338
- const url = new URL(youtubeLink);
339
- if (url.pathname.endsWith('watch')) {
340
- return url.searchParams.get("v");
308
+ static checkAngularMaterialTableData(tableData, checkHeaders = true) {
309
+ if (checkHeaders) {
310
+ var checkHeadersResult = this.checkHeaders(tableData);
311
+ if (!checkHeadersResult.isSucceeded) {
312
+ return checkHeadersResult;
313
+ }
341
314
  }
342
- //https://youtu.be/jzBneaWSswY
343
- const bits = url.pathname.split('/');
344
- return bits[bits.length - 1];
315
+ let rows = tableData.rows;
316
+ let columns = tableData.header.columns;
317
+ for (let i = 0; i < rows.length; i++) {
318
+ const row = rows[i];
319
+ if (row.columns.length !== columns.length) {
320
+ return {
321
+ isSucceeded: false,
322
+ message: `Ошибка при обработке разметки таблицы. `
323
+ + `Количество колонок в каждой строке таблицы должно соотвествовать количеству колонок указанных в заголовке. `
324
+ + `В строке таблицы №${i + 1} количество колонок = ${row.columns.length}, а должно быть ${columns.length}.`
325
+ };
326
+ }
327
+ }
328
+ return {
329
+ isSucceeded: true,
330
+ message: "Ok"
331
+ };
345
332
  }
346
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: XmlTagExternalVideoComponent, deps: [{ token: i0.DestroyRef }], target: i0.ɵɵFactoryTarget.Component }); }
347
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.4", type: XmlTagExternalVideoComponent, selector: "croco-html-xml-tag-external-video", inputs: { data: "data", tagData: "tagData" }, viewQueries: [{ propertyName: "playerContainerRef", first: true, predicate: ["playerContainer"], descendants: true, static: true }], ngImport: i0, template: "<div #playerContainer class=\"d-flex justify-content-center y-video\">\r\n <youtube-player [height]=\"playerHeight()\" [width]=\"playerWidth()\" *ngIf=\"videoId\" [videoId]=\"videoId\"></youtube-player>\r\n</div>\r\n", styles: ["@media only screen and (min-width: 769px){.y-video{display:block;width:640px;height:360px;margin:0 auto}}@media only screen and (max-width: 827px){.y-video{display:block;width:100%;height:315px}}\n"], dependencies: [{ kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2$1.YouTubePlayer, selector: "youtube-player", inputs: ["videoId", "height", "width", "startSeconds", "endSeconds", "suggestedQuality", "playerVars", "disableCookies", "loadApi", "disablePlaceholder", "showBeforeIframeApiLoads", "placeholderButtonLabel", "placeholderImageQuality"], outputs: ["ready", "stateChange", "error", "apiChange", "playbackQualityChange", "playbackRateChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
348
333
  }
349
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: XmlTagExternalVideoComponent, decorators: [{
350
- type: Component,
351
- args: [{ selector: 'croco-html-xml-tag-external-video', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div #playerContainer class=\"d-flex justify-content-center y-video\">\r\n <youtube-player [height]=\"playerHeight()\" [width]=\"playerWidth()\" *ngIf=\"videoId\" [videoId]=\"videoId\"></youtube-player>\r\n</div>\r\n", styles: ["@media only screen and (min-width: 769px){.y-video{display:block;width:640px;height:360px;margin:0 auto}}@media only screen and (max-width: 827px){.y-video{display:block;width:100%;height:315px}}\n"] }]
352
- }], ctorParameters: () => [{ type: i0.DestroyRef }], propDecorators: { data: [{
353
- type: Input
354
- }], tagData: [{
355
- type: Input
356
- }], playerContainerRef: [{
357
- type: ViewChild,
358
- args: ['playerContainer', { static: true }]
359
- }] } });
360
334
 
361
- class ExternalVideoBlockComponent {
362
- constructor() {
363
- this.onTagUpdated = new EventEmitter();
364
- this.defaultLink = "https://youtu.be/jzBneaWSswY";
365
- this.data = {
366
- youtubeLink: this.defaultLink
335
+ var EAlignments;
336
+ (function (EAlignments) {
337
+ EAlignments["Left"] = "left";
338
+ EAlignments["Center"] = "center";
339
+ EAlignments["Right"] = "right";
340
+ })(EAlignments || (EAlignments = {}));
341
+ const AlignmentsData = [
342
+ { value: EAlignments.Left, text: 'Слева' },
343
+ { value: EAlignments.Center, text: 'По центру' },
344
+ { value: EAlignments.Right, text: 'Справа' },
345
+ ];
346
+
347
+ const TextTag = "text";
348
+ class TextSimpleMethods {
349
+ static { this.supportedTags = ["sup", "sub", "strong", "b", "i", "u"]; }
350
+ static ExtractTextTag(elem) {
351
+ var hAlignValue = elem.getAttribute("h-align") ?? EAlignments.Left;
352
+ var data = {
353
+ textTagName: elem.tagName.toLowerCase(),
354
+ text: elem.innerText.trim().replace('\n\t', ''),
355
+ html: elem.innerHTML.trim().replace('\n\t', ''),
356
+ horizontalAlignment: hAlignValue,
357
+ validationResult: {
358
+ isSucceeded: true,
359
+ message: "Ok"
360
+ }
367
361
  };
368
- this.tagData = {
369
- link: this.defaultLink,
370
- type: ExternalVideoSupportedTypes.Youtube
362
+ let result = {
363
+ type: TextTag,
364
+ data: data
371
365
  };
366
+ if (result.data.text === '\n') {
367
+ result.data.text = '';
368
+ }
369
+ if (result.data.html === '\n') {
370
+ result.data.html = '';
371
+ }
372
+ var alignmentVals = [EAlignments.Left, EAlignments.Right, EAlignments.Center];
373
+ if (alignmentVals.indexOf(hAlignValue) < 0) {
374
+ result.data.validationResult = {
375
+ isSucceeded: false,
376
+ message: `Недопустимое значение атрибута h-align. Допустимые значения: ${alignmentVals.join(', ')}. `
377
+ + 'Данный тег можно не указывать, по-умолчанию будет применено выравнивание слева.'
378
+ };
379
+ }
380
+ var html = result.data.html;
381
+ var htmlValidation = this.ValidateTextHtml(html);
382
+ if (!htmlValidation.isSucceeded) {
383
+ result.data.validationResult = htmlValidation;
384
+ }
385
+ return result;
372
386
  }
373
- linkChanged() {
374
- this.tagData.link = this.data.youtubeLink;
375
- this.tag.attributes = this.tagData;
387
+ static ValidateTextHtml(html) {
388
+ var p = document.createElement("p");
389
+ p.innerHTML = html;
390
+ for (let i = 0; i < p.children.length; i++) {
391
+ const element = p.children.item(i);
392
+ var validationResult = this.ValidateTag(element);
393
+ if (!validationResult.isSucceeded) {
394
+ return validationResult;
395
+ }
396
+ }
397
+ return {
398
+ isSucceeded: true,
399
+ message: `Ok`
400
+ };
376
401
  }
377
- ngOnInit() {
378
- if (!this.tag?.attributes?.['link']) {
379
- this.linkChanged();
402
+ static ValidateTag(element) {
403
+ let lowerTag = element.tagName.toLowerCase();
404
+ if (!this.supportedTags.includes(lowerTag)) {
405
+ return {
406
+ isSucceeded: false,
407
+ message: `Тег <${lowerTag}> не поддерживается внутри тега <text>`
408
+ };
409
+ }
410
+ for (let i = 0; i < element.children.length; i++) {
411
+ const nElement = element.children.item(i);
412
+ var innerValidationResult = this.ValidateTag(nElement);
413
+ if (!innerValidationResult.isSucceeded) {
414
+ return innerValidationResult;
415
+ }
380
416
  }
381
- this.tagData = this.tag.attributes;
382
- this.data.youtubeLink = this.tagData.link;
417
+ return {
418
+ isSucceeded: true,
419
+ message: "Ok"
420
+ };
383
421
  }
384
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: ExternalVideoBlockComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
385
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.4", type: ExternalVideoBlockComponent, selector: "croco-html-external-video-block", inputs: { tag: "tag" }, outputs: { onTagUpdated: "onTagUpdated" }, ngImport: i0, template: "<div *ngIf=\"tag.presentOrEdit\">\r\n \r\n <div>\r\n \u0421\u0441\u044B\u043B\u043A\u0430 \u043D\u0430 YouTube: {{data.youtubeLink}}\r\n </div>\r\n\r\n <div style=\"height: 10px;\"></div>\r\n\r\n <croco-html-xml-tag-external-video [tagData]=\"tagData\">\r\n </croco-html-xml-tag-external-video>\r\n</div>\r\n\r\n<div *ngIf=\"!tag.presentOrEdit\">\r\n <div>\r\n <div>\r\n <mat-form-field class=\"w-100\">\r\n <input matInput placeholder=\"\u0421\u0441\u044B\u043B\u043A\u0430 \u043D\u0430 YouTube\"\r\n new-autocomplete=\"off\"\r\n autocomplete=\"off\"\r\n [(ngModel)]=\"data.youtubeLink\"\r\n (ngModelChange)=\"linkChanged()\">\r\n </mat-form-field>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n", styles: [""], dependencies: [{ kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: XmlTagExternalVideoComponent, selector: "croco-html-xml-tag-external-video", inputs: ["data", "tagData"] }] }); }
386
422
  }
387
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: ExternalVideoBlockComponent, decorators: [{
388
- type: Component,
389
- args: [{ selector: 'croco-html-external-video-block', template: "<div *ngIf=\"tag.presentOrEdit\">\r\n \r\n <div>\r\n \u0421\u0441\u044B\u043B\u043A\u0430 \u043D\u0430 YouTube: {{data.youtubeLink}}\r\n </div>\r\n\r\n <div style=\"height: 10px;\"></div>\r\n\r\n <croco-html-xml-tag-external-video [tagData]=\"tagData\">\r\n </croco-html-xml-tag-external-video>\r\n</div>\r\n\r\n<div *ngIf=\"!tag.presentOrEdit\">\r\n <div>\r\n <div>\r\n <mat-form-field class=\"w-100\">\r\n <input matInput placeholder=\"\u0421\u0441\u044B\u043B\u043A\u0430 \u043D\u0430 YouTube\"\r\n new-autocomplete=\"off\"\r\n autocomplete=\"off\"\r\n [(ngModel)]=\"data.youtubeLink\"\r\n (ngModelChange)=\"linkChanged()\">\r\n </mat-form-field>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n" }]
390
- }], propDecorators: { tag: [{
391
- type: Input
392
- }], onTagUpdated: [{
393
- type: Output
394
- }] } });
395
423
 
396
- class HtmlRawEditorComponent {
397
- constructor() {
398
- this.onTagUpdated = new EventEmitter();
424
+ class BootstrapTableMethods {
425
+ static BuildTable(data) {
426
+ let result = `<table class="table table-bordered">`;
427
+ result += this.BuildHeader(data.header);
428
+ result += this.BuildBody(data.rows);
429
+ result += "</table>";
430
+ return result;
399
431
  }
400
- ngOnInit() {
432
+ static BuildHeader(data) {
433
+ if (data === null) {
434
+ return "";
435
+ }
436
+ let result = "<thead>";
437
+ result += "<tr>";
438
+ for (let index = 0; index < data.columns.length; index++) {
439
+ result += `<th>${data.columns[index]}</th>`;
440
+ }
441
+ result += "</tr>";
442
+ result += "</thead>";
443
+ return result;
401
444
  }
402
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: HtmlRawEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
403
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.4", type: HtmlRawEditorComponent, selector: "croco-html-html-raw-editor", inputs: { tag: "tag" }, outputs: { onTagUpdated: "onTagUpdated" }, ngImport: i0, template: "<div *ngIf=\"tag.presentOrEdit\">\r\n <div [innerHTML]=\"tag.innerHtml\"></div>\r\n</div>\r\n\r\n<div *ngIf=\"!tag.presentOrEdit\">\r\n <div style=\"height: 10px;\">\r\n </div>\r\n <div>\r\n <mat-form-field class=\"w-100\">\r\n <textarea matInput cdkTextareaAutosize #autosize=\"cdkTextareaAutosize\"\r\n cdkAutosizeMinRows=\"1\"\r\n placeholder=\"\u0412\u043D\u0443\u0442\u0440\u0435\u043D\u043D\u044F\u044F \u0440\u0430\u0437\u043C\u0435\u0442\u043A\u0430 \u0442\u0435\u0433\u0430\"\r\n [(ngModel)]=\"tag.innerHtml\"></textarea>\r\n </mat-form-field>\r\n </div>\r\n</div>\r\n\r\n", styles: [""], dependencies: [{ kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "directive", type: i5.CdkTextareaAutosize, selector: "textarea[cdkTextareaAutosize]", inputs: ["cdkAutosizeMinRows", "cdkAutosizeMaxRows", "cdkTextareaAutosize", "placeholder"], exportAs: ["cdkTextareaAutosize"] }] }); }
404
- }
405
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: HtmlRawEditorComponent, decorators: [{
406
- type: Component,
407
- args: [{ selector: 'croco-html-html-raw-editor', template: "<div *ngIf=\"tag.presentOrEdit\">\r\n <div [innerHTML]=\"tag.innerHtml\"></div>\r\n</div>\r\n\r\n<div *ngIf=\"!tag.presentOrEdit\">\r\n <div style=\"height: 10px;\">\r\n </div>\r\n <div>\r\n <mat-form-field class=\"w-100\">\r\n <textarea matInput cdkTextareaAutosize #autosize=\"cdkTextareaAutosize\"\r\n cdkAutosizeMinRows=\"1\"\r\n placeholder=\"\u0412\u043D\u0443\u0442\u0440\u0435\u043D\u043D\u044F\u044F \u0440\u0430\u0437\u043C\u0435\u0442\u043A\u0430 \u0442\u0435\u0433\u0430\"\r\n [(ngModel)]=\"tag.innerHtml\"></textarea>\r\n </mat-form-field>\r\n </div>\r\n</div>\r\n\r\n" }]
408
- }], ctorParameters: () => [], propDecorators: { tag: [{
409
- type: Input
410
- }], onTagUpdated: [{
411
- type: Output
412
- }] } });
413
-
414
- const CrocoHtmlOptionsToken = "croco-html-options";
415
-
416
- var FileType;
417
- (function (FileType) {
418
- FileType["Undefined"] = "Undefined";
419
- FileType["Unknown"] = "Unknown";
420
- FileType["Image"] = "Image";
421
- FileType["Audio"] = "Audio";
422
- FileType["Video"] = "Video";
423
- FileType["Document"] = "Document";
424
- FileType["Archive"] = "Archive";
425
- })(FileType || (FileType = {}));
426
- class FilesQueryService {
427
- constructor(_httpClient, baseUrl) {
428
- this._httpClient = _httpClient;
429
- this._baseControllerUrl = `${baseUrl}Api/Files`;
445
+ static BuildBody(rows) {
446
+ let result = "<tbody>";
447
+ for (let i = 0; i < rows.length; i++) {
448
+ const row = rows[i];
449
+ result += "<tr>";
450
+ for (let j = 0; j < row.columns.length; j++) {
451
+ const col = row.columns[j];
452
+ result += `<td class="align-middle">${this.BuildInnerTags(col.data.children)}</td>`;
453
+ }
454
+ result += "</tr>";
455
+ }
456
+ result += "</tbody>";
457
+ return result;
430
458
  }
431
- getFilesWithRelations(model) {
432
- return this._httpClient.post(this._baseControllerUrl + `/GetFiles/WithRelations`, model);
459
+ static BuildInnerTags(tags) {
460
+ let result = "";
461
+ for (let i = 0; i < tags.length; i++) {
462
+ result += this.BuildInnerTag(tags[i]);
463
+ }
464
+ return result;
433
465
  }
434
- getFiles(model) {
435
- return this._httpClient.post(this._baseControllerUrl + `/GetFiles`, model);
466
+ static BuildInnerTag(data) {
467
+ if (data.type === FileImageTagDataConsts.TagName) {
468
+ let fileImageTag = data;
469
+ return `<img src=${fileImageTag.data.src} class="mx-auto d-block img-fluid" />`;
470
+ }
471
+ else if (data.type === TextTag) {
472
+ let simpleTextTag = data;
473
+ var map = {
474
+ ["left"]: "text-start",
475
+ ["center"]: "text-center",
476
+ ["right"]: "text-end"
477
+ };
478
+ if (!simpleTextTag.data.validationResult.isSucceeded) {
479
+ return `<span>Ошибка в тексте ${simpleTextTag.data.validationResult.message}</span>`;
480
+ }
481
+ return `<div class="${map[simpleTextTag.data.horizontalAlignment]}"><span>${simpleTextTag.data.html}</span></div>`;
482
+ }
483
+ else {
484
+ return `<p>Тег ${data.type} не поддерживается</p>`;
485
+ }
436
486
  }
437
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: FilesQueryService, deps: [{ token: i1.HttpClient }, { token: 'BASE_URL' }], target: i0.ɵɵFactoryTarget.Injectable }); }
438
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: FilesQueryService, providedIn: 'root' }); }
439
487
  }
440
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: FilesQueryService, decorators: [{
441
- type: Injectable,
442
- args: [{
443
- providedIn: 'root'
444
- }]
445
- }], ctorParameters: () => [{ type: i1.HttpClient }, { type: undefined, decorators: [{
446
- type: Inject,
447
- args: ['BASE_URL']
448
- }] }] });
449
488
 
450
- class FileIdSelectComponent {
451
- constructor(_fileService, _options) {
452
- this._fileService = _fileService;
453
- this._options = _options;
454
- this.labelText = "Поиск файлов";
455
- this.loading = false;
456
- this.files = [];
457
- this.onFileIdChanged = new EventEmitter();
489
+ class TableTypes {
490
+ static { this.TableRowColumnData = "table-row-column-data"; }
491
+ static { this.Table = "table"; }
492
+ static { this.TableRowColumn = "table-row-column"; }
493
+ }
494
+ class TableMethods {
495
+ static getTableFromHtmlTag(tableTag, options) {
496
+ let tableData = {
497
+ header: TableMethods.getHeader(tableTag),
498
+ rows: TableMethods.getTableRows(tableTag, options)
499
+ };
500
+ var result = {
501
+ type: TableTypes.Table,
502
+ data: tableData,
503
+ validationResult: this.checkTable(tableData),
504
+ bootstrapHtml: ""
505
+ };
506
+ if (!result.validationResult) {
507
+ return result;
508
+ }
509
+ result.bootstrapHtml = BootstrapTableMethods.BuildTable(result.data);
510
+ var angularMaterialTableDataCheck = AngularMaterialTableMethods.checkAngularMaterialTableData(tableData);
511
+ if (!angularMaterialTableDataCheck.isSucceeded) {
512
+ return {
513
+ ...result,
514
+ angularMaterialTableDataCheck
515
+ };
516
+ }
517
+ return {
518
+ ...result,
519
+ angularMaterialTableDataCheck,
520
+ html: tableTag.outerHTML,
521
+ angularMaterialTableData: AngularMaterialTableMethods.getAngularMaterialTableData(tableData.header.columns, tableData.rows),
522
+ };
458
523
  }
459
- onModelChanged(fileId) {
460
- this.onFileIdChanged.emit(fileId);
524
+ static checkTable(tableData) {
525
+ let rows = tableData.rows;
526
+ let prevRowCount = -1;
527
+ for (let i = 0; i < rows.length; i++) {
528
+ const row = rows[i];
529
+ if (row.columns.length !== prevRowCount && prevRowCount != -1) {
530
+ return {
531
+ isSucceeded: false,
532
+ message: `Ошибка при обработке разметки таблицы. `
533
+ + `Количество колонок в каждой строке таблицы должно соотвествовать друг другу. `
534
+ + `В строке таблицы №${i + 1} количество колонок = ${row.columns.length}, а в строке выше ${prevRowCount}.`
535
+ };
536
+ }
537
+ prevRowCount = row.columns.length;
538
+ }
539
+ return {
540
+ isSucceeded: true,
541
+ message: "Ok"
542
+ };
461
543
  }
462
- getSrc(fileId) {
463
- return ImageMethods.buildSmallUrl(fileId, this._options);
544
+ static getHeader(tableTag) {
545
+ let header = tableTag.tHead;
546
+ if (header === null) {
547
+ return null;
548
+ }
549
+ let tr = header.children.item(0);
550
+ let headerColumns = [];
551
+ for (let j = 0; j < tr.children.length; j++) {
552
+ const jElement = tr.children.item(j);
553
+ headerColumns.push(jElement.innerHTML);
554
+ }
555
+ return {
556
+ type: "table-header",
557
+ columns: headerColumns
558
+ };
464
559
  }
465
- ngOnInit() {
466
- this.loadFiles();
560
+ static getTableRows(tableTag, options) {
561
+ let tBody = tableTag.tBodies.item(0);
562
+ let rows = [];
563
+ for (let i = 0; i < tBody.children.length; i++) {
564
+ const iElement = tBody.children.item(i);
565
+ let rowColumns = [];
566
+ for (let j = 0; j < iElement.children.length; j++) {
567
+ const jElement = iElement.children.item(j);
568
+ let children = HtmlExtractionMethods.transformHtmlElementToBlocks(jElement, options);
569
+ if (children.length === 0) {
570
+ var textTag = document.createElement("p");
571
+ textTag.innerHTML = jElement.innerHTML;
572
+ var textElem = TextSimpleMethods.ExtractTextTag(textTag);
573
+ children.push(textElem);
574
+ }
575
+ var result = {
576
+ type: TableTypes.TableRowColumnData,
577
+ data: {
578
+ text: jElement.innerHTML,
579
+ children
580
+ }
581
+ };
582
+ rowColumns.push(result);
583
+ }
584
+ rows.push({
585
+ type: TableTypes.TableRowColumn,
586
+ columns: rowColumns
587
+ });
588
+ }
589
+ return rows;
467
590
  }
468
- loadFiles() {
469
- this.loading = true;
470
- this._fileService.getFiles({
471
- count: 10,
472
- offSet: 0,
473
- fileName: null,
474
- fileTypes: [FileType.Image],
475
- applicationId: null,
476
- q: this.q
477
- }).subscribe(data => {
478
- this.files = [...data.list];
479
- this.loading = false;
480
- });
591
+ }
592
+
593
+ class TextTags {
594
+ static { this.text = "text"; }
595
+ static { this.h1 = "h1"; }
596
+ static { this.h2 = "h2"; }
597
+ static { this.h3 = "h3"; }
598
+ static { this.h4 = "h4"; }
599
+ static { this.h5 = "h5"; }
600
+ static { this.h6 = "h6"; }
601
+ static { this.allTextTags = [TextTags.text, TextTags.h1, TextTags.h2, TextTags.h3, TextTags.h4, TextTags.h5, TextTags.h6]; }
602
+ }
603
+ class TextMethods {
604
+ static ExtractRichTextData(elem) {
605
+ let children = [];
606
+ for (let i = 0; i < elem.children.length; i++) {
607
+ const child = elem.children.item(i);
608
+ if (child.tagName === "text-block".toUpperCase()) {
609
+ children.push({
610
+ type: "text-block",
611
+ data: {
612
+ text: child.innerHTML
613
+ }
614
+ });
615
+ }
616
+ else if (child.tagName === "line-break".toUpperCase()) {
617
+ children.push({
618
+ type: "line-break"
619
+ });
620
+ }
621
+ }
622
+ return {
623
+ type: "rich-text",
624
+ data: {
625
+ children
626
+ }
627
+ };
481
628
  }
482
- onSearchChanged(q) {
483
- this.q = q.term;
484
- this.loadFiles();
629
+ }
630
+
631
+ class ExternalVideoTagDataConsts {
632
+ static { this.TagName = "external-video"; }
633
+ static { this.VideoTypeAttrName = "type"; }
634
+ static { this.LinkAttrName = "link"; }
635
+ }
636
+ class ExternalVideoSupportedTypes {
637
+ static { this.Youtube = "youtube"; }
638
+ static { this.VkVideo = "vk-video"; }
639
+ }
640
+ const ExternalVideoPlayers = [
641
+ {
642
+ type: ExternalVideoSupportedTypes.Youtube,
643
+ displayValue: 'Внешнее видео Youtube',
644
+ },
645
+ {
646
+ type: ExternalVideoSupportedTypes.VkVideo,
647
+ displayValue: 'Внешнее видео Vk Video',
485
648
  }
486
- ngOnChanges(changes) {
487
- this.loadFiles();
649
+ ];
650
+ class VideoMethods {
651
+ static ExtractExternalVideoTag(elem) {
652
+ return {
653
+ type: ExternalVideoTagDataConsts.TagName,
654
+ data: {
655
+ type: elem.getAttribute(ExternalVideoTagDataConsts.VideoTypeAttrName),
656
+ link: elem.getAttribute(ExternalVideoTagDataConsts.LinkAttrName)
657
+ }
658
+ };
488
659
  }
489
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: FileIdSelectComponent, deps: [{ token: FilesQueryService }, { token: CrocoHtmlOptionsToken }], target: i0.ɵɵFactoryTarget.Component }); }
490
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.4", type: FileIdSelectComponent, selector: "croco-html-file-id-select", inputs: { labelText: "labelText", fileId: "fileId" }, outputs: { fileId: "fileId", onFileIdChanged: "onFileIdChanged" }, usesOnChanges: true, ngImport: i0, template: "<div>\r\n <div class=\"form-group\">\r\n <label for=\"fileName\">{{labelText}}</label>\r\n <ng-select [(ngModel)]=\"fileId\" (ngModelChange)=\"onModelChanged($event)\"\r\n [items]=\"files\"\r\n #select\r\n bindLabel=\"fileName\"\r\n (search)=\"onSearchChanged($event)\"\r\n [loading]=\"loading\"\r\n [loadingText]=\"'\u0417\u0430\u0433\u0440\u0443\u0436\u0430\u044E \u0444\u0430\u0439\u043B\u044B'\"\r\n dropdownPosition=\"auto\"\r\n bindValue=\"fileId\"\r\n labelForId=\"fileName\"\r\n placeholder=\"\u0412\u044B\u0431\u0440\u0430\u0442\u044C \u0444\u0430\u0439\u043B\"\r\n [virtualScroll]=\"true\">\r\n <ng-template ng-option-tmp let-item=\"item\" let-index=\"index\" let-search=\"searchTerm\">\r\n <div>\r\n <img class=\"mx-auto d-block img-fluid\" [src]=\"getSrc(item.fileId)\"/>\r\n </div>\r\n <div>\r\n <span class=\"h5\">\u0424\u0430\u0439\u043B: </span>\r\n <span class=\"h5\" [ngOptionHighlight]=\"search\"><b>{{item.fileName}}</b></span>\r\n </div>\r\n <div>\r\n <small>\r\n <span>\r\n \u0418\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u043E\u0440 \u0444\u0430\u0439\u043B\u0430: <b>{{item.fileId}}</b>\r\n </span>\r\n </small>\r\n </div>\r\n </ng-template>\r\n </ng-select>\r\n </div>\r\n</div>\r\n\r\n<div>\r\n \u0418\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u043E\u0440 \u0444\u0430\u0439\u043B\u0430: {{fileId}}\r\n</div>\r\n", styles: [""], dependencies: [{ kind: "directive", type: i2$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i3$1.NgSelectComponent, selector: "ng-select", inputs: ["bindLabel", "bindValue", "markFirst", "placeholder", "notFoundText", "typeToSearchText", "addTagText", "loadingText", "clearAllText", "appearance", "dropdownPosition", "appendTo", "loading", "closeOnSelect", "hideSelected", "selectOnTab", "openOnEnter", "maxSelectedItems", "groupBy", "groupValue", "bufferAmount", "virtualScroll", "selectableGroup", "selectableGroupAsModel", "searchFn", "trackByFn", "clearOnBackspace", "labelForId", "inputAttrs", "tabIndex", "readonly", "searchWhileComposing", "minTermLength", "editableSearchTerm", "keyDownFn", "typeahead", "multiple", "addTag", "searchable", "clearable", "isOpen", "items", "compareWith", "clearSearchOnAdd", "deselectOnClick"], outputs: ["blur", "focus", "change", "open", "close", "search", "clear", "add", "remove", "scroll", "scrollToEnd"] }, { kind: "directive", type: i3$1.NgOptionTemplateDirective, selector: "[ng-option-tmp]" }] }); }
491
660
  }
492
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: FileIdSelectComponent, decorators: [{
493
- type: Component,
494
- args: [{ selector: 'croco-html-file-id-select', template: "<div>\r\n <div class=\"form-group\">\r\n <label for=\"fileName\">{{labelText}}</label>\r\n <ng-select [(ngModel)]=\"fileId\" (ngModelChange)=\"onModelChanged($event)\"\r\n [items]=\"files\"\r\n #select\r\n bindLabel=\"fileName\"\r\n (search)=\"onSearchChanged($event)\"\r\n [loading]=\"loading\"\r\n [loadingText]=\"'\u0417\u0430\u0433\u0440\u0443\u0436\u0430\u044E \u0444\u0430\u0439\u043B\u044B'\"\r\n dropdownPosition=\"auto\"\r\n bindValue=\"fileId\"\r\n labelForId=\"fileName\"\r\n placeholder=\"\u0412\u044B\u0431\u0440\u0430\u0442\u044C \u0444\u0430\u0439\u043B\"\r\n [virtualScroll]=\"true\">\r\n <ng-template ng-option-tmp let-item=\"item\" let-index=\"index\" let-search=\"searchTerm\">\r\n <div>\r\n <img class=\"mx-auto d-block img-fluid\" [src]=\"getSrc(item.fileId)\"/>\r\n </div>\r\n <div>\r\n <span class=\"h5\">\u0424\u0430\u0439\u043B: </span>\r\n <span class=\"h5\" [ngOptionHighlight]=\"search\"><b>{{item.fileName}}</b></span>\r\n </div>\r\n <div>\r\n <small>\r\n <span>\r\n \u0418\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u043E\u0440 \u0444\u0430\u0439\u043B\u0430: <b>{{item.fileId}}</b>\r\n </span>\r\n </small>\r\n </div>\r\n </ng-template>\r\n </ng-select>\r\n </div>\r\n</div>\r\n\r\n<div>\r\n \u0418\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u043E\u0440 \u0444\u0430\u0439\u043B\u0430: {{fileId}}\r\n</div>\r\n" }]
495
- }], ctorParameters: () => [{ type: FilesQueryService }, { type: undefined, decorators: [{
496
- type: Inject,
497
- args: [CrocoHtmlOptionsToken]
498
- }] }], propDecorators: { labelText: [{
499
- type: Input
500
- }], fileId: [{
501
- type: Input
502
- }, {
503
- type: Output
504
- }], onFileIdChanged: [{
505
- type: Output
506
- }] } });
507
661
 
508
- class ImageEditorComponent {
509
- onErrorHandler() {
510
- this.hasImageError = true;
511
- }
512
- constructor(_options) {
513
- this._options = _options;
514
- this.hasImageError = false;
515
- this.searchOrEdit = "search";
516
- this.onTagUpdated = new EventEmitter();
517
- }
518
- getSrc() {
519
- return ImageMethods.buildUrl(this.tag.attributes[FileImageTagDataConsts.FileIdAttrName], "Medium", this._options);
520
- }
521
- hasFileId() {
522
- return this.tag.attributes.hasOwnProperty(FileImageTagDataConsts.FileIdAttrName) && !isNaN(this.tag.attributes[FileImageTagDataConsts.FileIdAttrName]);
523
- }
524
- onFileIdChanged(fileId) {
525
- this.tag.attributes[FileImageTagDataConsts.FileIdAttrName] = fileId;
526
- this.removeImageError();
527
- }
528
- removeImageError() {
529
- this.hasImageError = false;
530
- }
531
- ngOnInit() {
662
+ class HtmlExtractionMethods {
663
+ static ExtractHeaderTag(elem, tagName) {
664
+ var data = TextSimpleMethods.ExtractTextTag(elem);
665
+ data.type = tagName;
666
+ return data;
532
667
  }
533
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: ImageEditorComponent, deps: [{ token: CrocoHtmlOptionsToken }], target: i0.ɵɵFactoryTarget.Component }); }
534
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.4", type: ImageEditorComponent, selector: "croco-html-image-editor", inputs: { tag: "tag" }, outputs: { onTagUpdated: "onTagUpdated" }, ngImport: i0, template: "<div>\r\n <div style=\"height: 10px;\">\r\n </div>\r\n \r\n <div *ngIf=\"hasImageError\" class=\"error-block\">\r\n \u0418\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435 \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D\u043E \u043F\u043E \u0443\u043A\u0430\u0437\u0430\u043D\u043D\u043E\u043C\u0443 \u0438\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u043E\u0440\u0443, \u0432\u043E\u0437\u043C\u043E\u0436\u043D\u043E \u0444\u0430\u0439\u043B \u043D\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0438\u043B\u0438 \u043E\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043D\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435.\r\n </div>\r\n\r\n <div *ngIf=\"hasFileId() && !hasImageError\">\r\n <img class=\"mx-auto d-block img-fluid\" [src]=\"getSrc()\" (error)=\"onErrorHandler()\"/>\r\n </div>\r\n\r\n <div *ngIf=\"!hasFileId()\">\r\n <h5>[\u0418\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435 \u043D\u0435 \u0432\u044B\u0431\u0440\u0430\u043D\u043E]</h5>\r\n </div>\r\n</div>\r\n\r\n<div *ngIf=\"!tag.presentOrEdit\">\r\n <div style=\"height: 10px;\"></div>\r\n\r\n <div style=\"overflow-x:auto;\">\r\n <mat-button-toggle-group [(ngModel)]=\"searchOrEdit\">\r\n <mat-button-toggle value=\"search\">\r\n \u0418\u0441\u043A\u0430\u0442\u044C \u0444\u0430\u0439\u043B <mat-icon>search</mat-icon>\r\n </mat-button-toggle>\r\n <mat-button-toggle value=\"edit\">\r\n \u0423\u043A\u0430\u0437\u0430\u0442\u044C \u043F\u043E \u0438\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u043E\u0440\u0443 <mat-icon>settings</mat-icon>\r\n </mat-button-toggle>\r\n </mat-button-toggle-group>\r\n </div>\r\n \r\n\r\n <div style=\"height: 10px;\"></div>\r\n\r\n <div [hidden]=\"searchOrEdit !== 'search'\">\r\n <croco-html-file-id-select\r\n [labelText]=\"'\u0412\u044B\u0431\u0440\u0430\u0442\u044C \u0444\u0430\u0439\u043B'\"\r\n [(fileId)]=\"tag.attributes['file-id']\"\r\n (onFileIdChanged)=\"onFileIdChanged($event)\">\r\n </croco-html-file-id-select>\r\n </div>\r\n\r\n <div [hidden]=\"searchOrEdit !== 'edit'\">\r\n <div>\r\n <mat-form-field class=\"w-100\">\r\n <input matInput placeholder=\"\u0418\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u043E\u0440 \u0444\u0430\u0439\u043B\u0430\" new-autocomplete=\"off\" autocomplete=\"off\"\r\n type=\"number\"\r\n [(ngModel)]=\"tag.attributes['file-id']\"\r\n (ngModelChange)=\"removeImageError()\">\r\n </mat-form-field>\r\n </div>\r\n </div>\r\n</div>", styles: [".error-block{background-color:#f32323;color:#fff;text-align:center;border-radius:10px;padding:10px}\n"], dependencies: [{ kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i5$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i6.MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled", "hideSingleSelectionIndicator", "hideMultipleSelectionIndicator"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { kind: "component", type: i6.MatButtonToggle, selector: "mat-button-toggle", inputs: ["aria-label", "aria-labelledby", "id", "name", "value", "tabIndex", "disableRipple", "appearance", "checked", "disabled"], outputs: ["change"], exportAs: ["matButtonToggle"] }, { kind: "component", type: FileIdSelectComponent, selector: "croco-html-file-id-select", inputs: ["labelText", "fileId"], outputs: ["fileId", "onFileIdChanged"] }] }); }
535
- }
536
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: ImageEditorComponent, decorators: [{
537
- type: Component,
538
- args: [{ selector: 'croco-html-image-editor', template: "<div>\r\n <div style=\"height: 10px;\">\r\n </div>\r\n \r\n <div *ngIf=\"hasImageError\" class=\"error-block\">\r\n \u0418\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435 \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D\u043E \u043F\u043E \u0443\u043A\u0430\u0437\u0430\u043D\u043D\u043E\u043C\u0443 \u0438\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u043E\u0440\u0443, \u0432\u043E\u0437\u043C\u043E\u0436\u043D\u043E \u0444\u0430\u0439\u043B \u043D\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0438\u043B\u0438 \u043E\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043D\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435.\r\n </div>\r\n\r\n <div *ngIf=\"hasFileId() && !hasImageError\">\r\n <img class=\"mx-auto d-block img-fluid\" [src]=\"getSrc()\" (error)=\"onErrorHandler()\"/>\r\n </div>\r\n\r\n <div *ngIf=\"!hasFileId()\">\r\n <h5>[\u0418\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435 \u043D\u0435 \u0432\u044B\u0431\u0440\u0430\u043D\u043E]</h5>\r\n </div>\r\n</div>\r\n\r\n<div *ngIf=\"!tag.presentOrEdit\">\r\n <div style=\"height: 10px;\"></div>\r\n\r\n <div style=\"overflow-x:auto;\">\r\n <mat-button-toggle-group [(ngModel)]=\"searchOrEdit\">\r\n <mat-button-toggle value=\"search\">\r\n \u0418\u0441\u043A\u0430\u0442\u044C \u0444\u0430\u0439\u043B <mat-icon>search</mat-icon>\r\n </mat-button-toggle>\r\n <mat-button-toggle value=\"edit\">\r\n \u0423\u043A\u0430\u0437\u0430\u0442\u044C \u043F\u043E \u0438\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u043E\u0440\u0443 <mat-icon>settings</mat-icon>\r\n </mat-button-toggle>\r\n </mat-button-toggle-group>\r\n </div>\r\n \r\n\r\n <div style=\"height: 10px;\"></div>\r\n\r\n <div [hidden]=\"searchOrEdit !== 'search'\">\r\n <croco-html-file-id-select\r\n [labelText]=\"'\u0412\u044B\u0431\u0440\u0430\u0442\u044C \u0444\u0430\u0439\u043B'\"\r\n [(fileId)]=\"tag.attributes['file-id']\"\r\n (onFileIdChanged)=\"onFileIdChanged($event)\">\r\n </croco-html-file-id-select>\r\n </div>\r\n\r\n <div [hidden]=\"searchOrEdit !== 'edit'\">\r\n <div>\r\n <mat-form-field class=\"w-100\">\r\n <input matInput placeholder=\"\u0418\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u043E\u0440 \u0444\u0430\u0439\u043B\u0430\" new-autocomplete=\"off\" autocomplete=\"off\"\r\n type=\"number\"\r\n [(ngModel)]=\"tag.attributes['file-id']\"\r\n (ngModelChange)=\"removeImageError()\">\r\n </mat-form-field>\r\n </div>\r\n </div>\r\n</div>", styles: [".error-block{background-color:#f32323;color:#fff;text-align:center;border-radius:10px;padding:10px}\n"] }]
539
- }], ctorParameters: () => [{ type: undefined, decorators: [{
540
- type: Inject,
541
- args: [CrocoHtmlOptionsToken]
542
- }] }], propDecorators: { tag: [{
543
- type: Input
544
- }], onTagUpdated: [{
545
- type: Output
546
- }] } });
547
-
548
- class XmlTagHtmlViewComponent {
549
- constructor() {
550
- this.html = "";
668
+ static { this.Extractors = {
669
+ ["TEXT"]: (elem, options) => TextSimpleMethods.ExtractTextTag(elem),
670
+ ["FILE-IMAGE"]: (elem, options) => ImageMethods.ExtractImage(elem, options),
671
+ ["TABLE"]: (elem, options) => TableMethods.getTableFromHtmlTag(elem, options),
672
+ ["RICH-TEXT"]: (elem, options) => TextMethods.ExtractRichTextData(elem),
673
+ ["HTML-RAW"]: (elem, options) => ({
674
+ type: "html-raw",
675
+ data: {
676
+ innerHTML: elem.innerHTML
677
+ }
678
+ }),
679
+ ["H1"]: (elem, options) => HtmlExtractionMethods.ExtractHeaderTag(elem, "h1"),
680
+ ["H2"]: (elem, options) => HtmlExtractionMethods.ExtractHeaderTag(elem, "h2"),
681
+ ["H3"]: (elem, options) => HtmlExtractionMethods.ExtractHeaderTag(elem, "h3"),
682
+ ["H4"]: (elem, options) => HtmlExtractionMethods.ExtractHeaderTag(elem, "h4"),
683
+ ["H5"]: (elem, options) => HtmlExtractionMethods.ExtractHeaderTag(elem, "h5"),
684
+ ["H6"]: (elem, options) => HtmlExtractionMethods.ExtractHeaderTag(elem, "h6"),
685
+ [ExternalVideoTagDataConsts.TagName.toUpperCase()]: (elem, options) => VideoMethods.ExtractExternalVideoTag(elem)
686
+ }; }
687
+ static transformHtmlElementToBlocks(element, options) {
688
+ var data = [];
689
+ for (let i = 0; i < element.children.length; i++) {
690
+ var elem = element.children.item(i);
691
+ if (!HtmlExtractionMethods.Extractors.hasOwnProperty(elem.tagName)) {
692
+ data.push({
693
+ type: "unsupported-tag",
694
+ data: {
695
+ tagString: elem.outerHTML
696
+ }
697
+ });
698
+ }
699
+ else {
700
+ var extractor = HtmlExtractionMethods.Extractors[elem.tagName];
701
+ var result = extractor(elem, options);
702
+ data.push(result);
703
+ }
704
+ }
705
+ return data;
551
706
  }
552
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: XmlTagHtmlViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
553
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.4", type: XmlTagHtmlViewComponent, selector: "croco-html-xml-tag-html-view", inputs: { html: "html" }, ngImport: i0, template: "<div class=\"col\" [innerHTML]=\"html\">\r\n</div>", styles: [""] }); }
554
- }
555
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: XmlTagHtmlViewComponent, decorators: [{
556
- type: Component,
557
- args: [{ selector: 'croco-html-xml-tag-html-view', template: "<div class=\"col\" [innerHTML]=\"html\">\r\n</div>" }]
558
- }], ctorParameters: () => [], propDecorators: { html: [{
559
- type: Input
560
- }] } });
561
-
562
- class XmlTagTextViewComponent {
563
- constructor() { }
564
- ngOnInit() {
707
+ static transformHtmlStringToBlocks(value, options) {
708
+ if (value === undefined || value === null) {
709
+ return [];
710
+ }
711
+ value = value
712
+ .replace('\n', '')
713
+ .replace('\t', '');
714
+ var div = document.createElement("div");
715
+ div.innerHTML = value;
716
+ return this.transformHtmlElementToBlocks(div, options);
565
717
  }
566
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: XmlTagTextViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
567
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.4", type: XmlTagTextViewComponent, selector: "croco-html-xml-tag-text-view", inputs: { item: "item" }, ngImport: i0, template: "<div *ngIf=\"item.data.validationResult.isSucceeded && item.data.horizontalAlignment === 'left'\" style=\"text-align: left;\">\r\n <span *ngIf=\"item.data.html.length === 0 || !item.data.html\">&nbsp;</span>\r\n <span *ngIf=\"item.data.html.length > 0\" [innerHtml]=\"item.data.html\"></span>\r\n</div>\r\n\r\n<div *ngIf=\"item.data.validationResult.isSucceeded && item.data.horizontalAlignment === 'right'\" style=\"text-align: right;\">\r\n <span *ngIf=\"item.data.html.length === 0 || !item.data.html\">&nbsp;</span>\r\n <span *ngIf=\"item.data.html.length > 0\" [innerHtml]=\"item.data.html\"></span>\r\n</div>\r\n\r\n<div *ngIf=\"item.data.validationResult.isSucceeded && item.data.horizontalAlignment === 'center'\" style=\"text-align: center;\">\r\n <span *ngIf=\"item.data.html.length === 0 || !item.data.html\">&nbsp;</span>\r\n <span *ngIf=\"item.data.html.length > 0\" [innerHtml]=\"item.data.html\"></span>\r\n</div>\r\n\r\n<div *ngIf=\"!item.data.validationResult.isSucceeded\" class=\"red\" style=\"margin-top: 10px;\" >\r\n <h4>\u0414\u043E\u043F\u0443\u0449\u0435\u043D\u0430 \u043E\u0448\u0438\u0431\u043A\u0430 \u0432 \u0442\u0435\u0433\u0435 &lt;text&gt;</h4>\r\n <span>\r\n {{item.data.validationResult.message}}\r\n </span>\r\n</div>", styles: [""], dependencies: [{ kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); }
568
718
  }
569
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: XmlTagTextViewComponent, decorators: [{
570
- type: Component,
571
- args: [{ selector: 'croco-html-xml-tag-text-view', template: "<div *ngIf=\"item.data.validationResult.isSucceeded && item.data.horizontalAlignment === 'left'\" style=\"text-align: left;\">\r\n <span *ngIf=\"item.data.html.length === 0 || !item.data.html\">&nbsp;</span>\r\n <span *ngIf=\"item.data.html.length > 0\" [innerHtml]=\"item.data.html\"></span>\r\n</div>\r\n\r\n<div *ngIf=\"item.data.validationResult.isSucceeded && item.data.horizontalAlignment === 'right'\" style=\"text-align: right;\">\r\n <span *ngIf=\"item.data.html.length === 0 || !item.data.html\">&nbsp;</span>\r\n <span *ngIf=\"item.data.html.length > 0\" [innerHtml]=\"item.data.html\"></span>\r\n</div>\r\n\r\n<div *ngIf=\"item.data.validationResult.isSucceeded && item.data.horizontalAlignment === 'center'\" style=\"text-align: center;\">\r\n <span *ngIf=\"item.data.html.length === 0 || !item.data.html\">&nbsp;</span>\r\n <span *ngIf=\"item.data.html.length > 0\" [innerHtml]=\"item.data.html\"></span>\r\n</div>\r\n\r\n<div *ngIf=\"!item.data.validationResult.isSucceeded\" class=\"red\" style=\"margin-top: 10px;\" >\r\n <h4>\u0414\u043E\u043F\u0443\u0449\u0435\u043D\u0430 \u043E\u0448\u0438\u0431\u043A\u0430 \u0432 \u0442\u0435\u0433\u0435 &lt;text&gt;</h4>\r\n <span>\r\n {{item.data.validationResult.message}}\r\n </span>\r\n</div>" }]
572
- }], ctorParameters: () => [], propDecorators: { item: [{
573
- type: Input
574
- }] } });
575
719
 
576
- class XmlTagHeaderInnerTextViewComponent {
577
- constructor() { }
578
- ngOnInit() {
579
- }
580
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: XmlTagHeaderInnerTextViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
581
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.4", type: XmlTagHeaderInnerTextViewComponent, selector: "croco-html-xml-tag-header-inner-text-view", inputs: { item: "item" }, ngImport: i0, template: "<h1 *ngIf=\"item.type === 'h1'\" \r\n [innerHtml]=\"item.data.html\">\r\n</h1>\r\n<h2 *ngIf=\"item.type === 'h2'\" \r\n [innerHtml]=\"item.data.html\">\r\n</h2>\r\n<h3 *ngIf=\"item.type === 'h3'\" \r\n [innerHtml]=\"item.data.html\">\r\n</h3>\r\n<h4 *ngIf=\"item.type === 'h4'\" \r\n [innerHtml]=\"item.data.html\">\r\n</h4>\r\n<h5 *ngIf=\"item.type === 'h5'\" \r\n [innerHtml]=\"item.data.html\">\r\n</h5>\r\n<h6 *ngIf=\"item.type === 'h6'\" \r\n [innerHtml]=\"item.data.html\">\r\n</h6>", styles: [""], dependencies: [{ kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); }
720
+ class HtmlRawTagDataConsts {
721
+ static { this.TagName = "html-raw"; }
582
722
  }
583
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: XmlTagHeaderInnerTextViewComponent, decorators: [{
584
- type: Component,
585
- args: [{ selector: 'croco-html-xml-tag-header-inner-text-view', template: "<h1 *ngIf=\"item.type === 'h1'\" \r\n [innerHtml]=\"item.data.html\">\r\n</h1>\r\n<h2 *ngIf=\"item.type === 'h2'\" \r\n [innerHtml]=\"item.data.html\">\r\n</h2>\r\n<h3 *ngIf=\"item.type === 'h3'\" \r\n [innerHtml]=\"item.data.html\">\r\n</h3>\r\n<h4 *ngIf=\"item.type === 'h4'\" \r\n [innerHtml]=\"item.data.html\">\r\n</h4>\r\n<h5 *ngIf=\"item.type === 'h5'\" \r\n [innerHtml]=\"item.data.html\">\r\n</h5>\r\n<h6 *ngIf=\"item.type === 'h6'\" \r\n [innerHtml]=\"item.data.html\">\r\n</h6>" }]
586
- }], ctorParameters: () => [], propDecorators: { item: [{
587
- type: Input
588
- }] } });
589
723
 
590
- class XmlTagHeaderTextViewComponent {
591
- constructor() { }
592
- ngOnInit() {
593
- }
594
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: XmlTagHeaderTextViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
595
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.4", type: XmlTagHeaderTextViewComponent, selector: "croco-html-xml-tag-header-text-view", inputs: { item: "item" }, ngImport: i0, template: "<div *ngIf=\"item.data.validationResult.isSucceeded && item.data.horizontalAlignment === 'left'\" style=\"text-align: left;\">\r\n <span *ngIf=\"item.data.html.length === 0 || !item.data.html\">&nbsp;</span>\r\n <croco-html-xml-tag-header-inner-text-view *ngIf=\"item.data.html.length > 0\" [item]=\"item\">\r\n </croco-html-xml-tag-header-inner-text-view>\r\n</div>\r\n\r\n<div *ngIf=\"item.data.validationResult.isSucceeded && item.data.horizontalAlignment === 'right'\" style=\"text-align: right;\">\r\n <span *ngIf=\"item.data.html.length === 0 || !item.data.html\">&nbsp;</span>\r\n <croco-html-xml-tag-header-inner-text-view *ngIf=\"item.data.html.length > 0\" [item]=\"item\">\r\n </croco-html-xml-tag-header-inner-text-view>\r\n</div>\r\n\r\n<div *ngIf=\"item.data.validationResult.isSucceeded && item.data.horizontalAlignment === 'center'\" style=\"text-align: center;\">\r\n <span *ngIf=\"item.data.html.length === 0 || !item.data.html\">&nbsp;</span>\r\n\r\n <croco-html-xml-tag-header-inner-text-view *ngIf=\"item.data.html.length > 0\" [item]=\"item\">\r\n </croco-html-xml-tag-header-inner-text-view>\r\n</div>\r\n\r\n<div *ngIf=\"!item.data.validationResult.isSucceeded\" class=\"red\" style=\"margin-top: 10px;\" >\r\n <h4>\u0414\u043E\u043F\u0443\u0449\u0435\u043D\u0430 \u043E\u0448\u0438\u0431\u043A\u0430 \u0432 \u0442\u0435\u0433\u0435 &lt;text&gt;</h4>\r\n <span>\r\n {{item.data.validationResult.message}}\r\n </span>\r\n</div>", styles: [""], dependencies: [{ kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: XmlTagHeaderInnerTextViewComponent, selector: "croco-html-xml-tag-header-inner-text-view", inputs: ["item"] }] }); }
724
+ class Tags {
725
+ static { this.Text = TextTags.text; }
726
+ static { this.H1 = TextTags.h1; }
727
+ static { this.H2 = TextTags.h2; }
728
+ static { this.H3 = TextTags.h3; }
729
+ static { this.H4 = TextTags.h4; }
730
+ static { this.H5 = TextTags.h5; }
731
+ static { this.H6 = TextTags.h6; }
732
+ static { this.HtmlRaw = HtmlRawTagDataConsts.TagName; }
733
+ static { this.FileImage = FileImageTagDataConsts.TagName; }
734
+ static { this.Table = 'table'; }
735
+ static { this.RichText = 'rich-text'; }
736
+ static { this.ExternalVideo = ExternalVideoTagDataConsts.TagName; }
737
+ static { this.UnsupportedTag = 'unsupported-tag'; }
596
738
  }
597
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: XmlTagHeaderTextViewComponent, decorators: [{
598
- type: Component,
599
- args: [{ selector: 'croco-html-xml-tag-header-text-view', template: "<div *ngIf=\"item.data.validationResult.isSucceeded && item.data.horizontalAlignment === 'left'\" style=\"text-align: left;\">\r\n <span *ngIf=\"item.data.html.length === 0 || !item.data.html\">&nbsp;</span>\r\n <croco-html-xml-tag-header-inner-text-view *ngIf=\"item.data.html.length > 0\" [item]=\"item\">\r\n </croco-html-xml-tag-header-inner-text-view>\r\n</div>\r\n\r\n<div *ngIf=\"item.data.validationResult.isSucceeded && item.data.horizontalAlignment === 'right'\" style=\"text-align: right;\">\r\n <span *ngIf=\"item.data.html.length === 0 || !item.data.html\">&nbsp;</span>\r\n <croco-html-xml-tag-header-inner-text-view *ngIf=\"item.data.html.length > 0\" [item]=\"item\">\r\n </croco-html-xml-tag-header-inner-text-view>\r\n</div>\r\n\r\n<div *ngIf=\"item.data.validationResult.isSucceeded && item.data.horizontalAlignment === 'center'\" style=\"text-align: center;\">\r\n <span *ngIf=\"item.data.html.length === 0 || !item.data.html\">&nbsp;</span>\r\n\r\n <croco-html-xml-tag-header-inner-text-view *ngIf=\"item.data.html.length > 0\" [item]=\"item\">\r\n </croco-html-xml-tag-header-inner-text-view>\r\n</div>\r\n\r\n<div *ngIf=\"!item.data.validationResult.isSucceeded\" class=\"red\" style=\"margin-top: 10px;\" >\r\n <h4>\u0414\u043E\u043F\u0443\u0449\u0435\u043D\u0430 \u043E\u0448\u0438\u0431\u043A\u0430 \u0432 \u0442\u0435\u0433\u0435 &lt;text&gt;</h4>\r\n <span>\r\n {{item.data.validationResult.message}}\r\n </span>\r\n</div>" }]
600
- }], ctorParameters: () => [], propDecorators: { item: [{
601
- type: Input
602
- }] } });
603
739
 
604
- class HtmlRawViewComponent {
605
- constructor(_sanitizer) {
606
- this._sanitizer = _sanitizer;
607
- this.rawHtml = "";
608
- this.isInitialized = false;
609
- }
610
- ngOnInit() {
611
- this.safeHtml = this._sanitizer.bypassSecurityTrustHtml(this.rawHtml);
740
+ class BodyTagsExtensions {
741
+ static getDescription(tagName) {
742
+ var descriptions = {
743
+ "text": "Текст",
744
+ "h1": "Заголовок 1 уровня",
745
+ "h2": "Заголовок 2 уровня",
746
+ "h3": "Заголовок 3 уровня",
747
+ "h4": "Заголовок 4 уровня",
748
+ "h5": "Заголовок 5 уровня",
749
+ "h6": "Заголовок 6 уровня",
750
+ [FileImageTagDataConsts.TagName]: "Изображение",
751
+ [ExternalVideoTagDataConsts.TagName]: "Внешнее видео",
752
+ [HtmlRawTagDataConsts.TagName]: "Html разметка"
753
+ };
754
+ return descriptions[tagName];
612
755
  }
613
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: HtmlRawViewComponent, deps: [{ token: i1$2.DomSanitizer }], target: i0.ɵɵFactoryTarget.Component }); }
614
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.4", type: HtmlRawViewComponent, selector: "croco-html-raw-view", inputs: { rawHtml: "rawHtml" }, ngImport: i0, template: "<div [innerHTML]=\"safeHtml\">\n</div>", styles: [""] }); }
615
- }
616
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: HtmlRawViewComponent, decorators: [{
617
- type: Component,
618
- args: [{ selector: 'croco-html-raw-view', template: "<div [innerHTML]=\"safeHtml\">\n</div>" }]
619
- }], ctorParameters: () => [{ type: i1$2.DomSanitizer }], propDecorators: { rawHtml: [{
620
- type: Input
621
- }] } });
622
-
623
- class FileImageTagViewComponent {
624
- constructor() {
625
- this.imageSrc = "";
756
+ static toHtml(bodyTags) {
757
+ let htmls = bodyTags.map(x => {
758
+ if (TextTags.allTextTags.includes(x.tagDescription.tag)) {
759
+ return `<${x.tagDescription.tag} h-align="${x.attributes['h-align']}">${x.innerHtml}</${x.tagDescription.tag}>`;
760
+ }
761
+ if (x.tagDescription.tag === ExternalVideoTagDataConsts.TagName) {
762
+ return `<${x.tagDescription.tag} type="${x.attributes['type']}" link="${x.attributes['link']}">${x.innerHtml}</${x.tagDescription.tag}>`;
763
+ }
764
+ if (x.tagDescription.tag === "html-raw") {
765
+ return `<${x.tagDescription.tag}>${x.innerHtml}</${x.tagDescription.tag}>`;
766
+ }
767
+ return BodyTagsExtensions.imageTagToHtml(x);
768
+ });
769
+ let result = "";
770
+ for (let index = 0; index < htmls.length; index++) {
771
+ const element = htmls[index];
772
+ result += element;
773
+ }
774
+ return result;
626
775
  }
627
- ngOnInit() {
628
- let data = this.item.data;
629
- this.imageSrc = data.src;
776
+ static imageTagToHtml(imageTag) {
777
+ var attrStr = "";
778
+ var attrValue = imageTag.attributes[FileImageTagDataConsts.FileIdAttrName];
779
+ if (imageTag.attributes.hasOwnProperty(FileImageTagDataConsts.FileIdAttrName) && attrValue) {
780
+ attrStr = `${FileImageTagDataConsts.FileIdAttrName}="${attrValue}"`;
781
+ }
782
+ return `<${FileImageTagDataConsts.TagName} ${attrStr}></${FileImageTagDataConsts.TagName}>`;
630
783
  }
631
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: FileImageTagViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
632
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.4", type: FileImageTagViewComponent, selector: "croco-html-file-image-tag-view", inputs: { item: "item" }, ngImport: i0, template: "\r\n<img class=\"mx-auto d-block img-fluid\" [src]=\"imageSrc\" alt=\"\u0418\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435 \u043D\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043D\u043E\"/>", styles: [""] }); }
633
- }
634
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: FileImageTagViewComponent, decorators: [{
635
- type: Component,
636
- args: [{ selector: 'croco-html-file-image-tag-view', template: "\r\n<img class=\"mx-auto d-block img-fluid\" [src]=\"imageSrc\" alt=\"\u0418\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435 \u043D\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043D\u043E\"/>" }]
637
- }], propDecorators: { item: [{
638
- type: Input
639
- }] } });
640
-
641
- class XmlTagViewComponent {
642
- constructor() {
643
- this.data = [];
784
+ static getBodyTags(html, options) {
785
+ let result = HtmlExtractionMethods.transformHtmlStringToBlocks(html, options);
786
+ return result.map(x => BodyTagsExtensions.toBodyTag(x));
644
787
  }
645
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: XmlTagViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
646
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.4", type: XmlTagViewComponent, selector: "croco-html-xml-tag-view", inputs: { data: "data" }, ngImport: i0, template: "<div>\r\n <div class=\"row\" *ngFor=\"let item of data\">\r\n <div *ngIf=\"item.type === 'text'\">\r\n <croco-html-xml-tag-text-view [item]=\"item\"></croco-html-xml-tag-text-view>\r\n </div>\r\n <div *ngIf=\"item.type === 'html-raw'\">\r\n <croco-html-raw-view [rawHtml]=\"item.data.innerHTML\">\r\n </croco-html-raw-view>\r\n </div>\r\n <div *ngIf=\"item.type === 'h1' || item.type === 'h2' || item.type === 'h3' || item.type === 'h4' || item.type === 'h5' || item.type === 'h6'\">\r\n <croco-html-xml-tag-header-text-view [item]=\"item\"></croco-html-xml-tag-header-text-view>\r\n </div>\r\n <div *ngIf=\"item.type === 'file-image'\">\r\n <croco-html-file-image-tag-view [item]=\"item\" [viewOptions]=\"viewOptions\"></croco-html-file-image-tag-view>\r\n </div>\r\n <div *ngIf=\"item.type === 'table'\">\r\n \r\n <croco-html-xml-tag-html-view *ngIf=\"item.validationResult.isSucceeded\" [html]=\"item.bootstrapHtml\">\r\n </croco-html-xml-tag-html-view>\r\n \r\n <app-tutor-baseapiresponse-banner \r\n *ngIf=\"item.validationResult && !item.validationResult.isSucceeded\" \r\n [message]=\"item.validationResult.message\">\r\n </app-tutor-baseapiresponse-banner>\r\n </div>\r\n \r\n <div *ngIf=\"item.type === 'rich-text'\">\r\n <croco-html-xml-tag-text-view [richTextData]=\"item\"></croco-html-xml-tag-text-view>\r\n </div>\r\n <div *ngIf=\"item.type === 'external-video'\">\r\n <croco-html-xml-tag-external-video [data]=\"item\"></croco-html-xml-tag-external-video>\r\n </div>\r\n <div *ngIf=\"item.type === 'unsupported-tag'\" class=\"red\" style=\"margin-top: 10px;\" >\r\n <h4>\u0414\u0430\u043D\u043D\u044B\u0439 \u0442\u0435\u0433 \u043D\u0435 \u043F\u043E\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044F</h4>\r\n <span>\r\n {{item.data.tagString}}\r\n </span>\r\n </div>\r\n </div>\r\n</div>", styles: [".red{background-color:#c94444;color:#fff}\n"], dependencies: [{ kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: XmlTagHtmlViewComponent, selector: "croco-html-xml-tag-html-view", inputs: ["html"] }, { kind: "component", type: XmlTagTextViewComponent, selector: "croco-html-xml-tag-text-view", inputs: ["item"] }, { kind: "component", type: XmlTagHeaderTextViewComponent, selector: "croco-html-xml-tag-header-text-view", inputs: ["item"] }, { kind: "component", type: XmlTagExternalVideoComponent, selector: "croco-html-xml-tag-external-video", inputs: ["data", "tagData"] }, { kind: "component", type: HtmlRawViewComponent, selector: "croco-html-raw-view", inputs: ["rawHtml"] }, { kind: "component", type: FileImageTagViewComponent, selector: "croco-html-file-image-tag-view", inputs: ["item"] }], encapsulation: i0.ViewEncapsulation.None }); }
647
- }
648
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: XmlTagViewComponent, decorators: [{
649
- type: Component,
650
- args: [{ selector: 'croco-html-xml-tag-view', encapsulation: ViewEncapsulation.None, template: "<div>\r\n <div class=\"row\" *ngFor=\"let item of data\">\r\n <div *ngIf=\"item.type === 'text'\">\r\n <croco-html-xml-tag-text-view [item]=\"item\"></croco-html-xml-tag-text-view>\r\n </div>\r\n <div *ngIf=\"item.type === 'html-raw'\">\r\n <croco-html-raw-view [rawHtml]=\"item.data.innerHTML\">\r\n </croco-html-raw-view>\r\n </div>\r\n <div *ngIf=\"item.type === 'h1' || item.type === 'h2' || item.type === 'h3' || item.type === 'h4' || item.type === 'h5' || item.type === 'h6'\">\r\n <croco-html-xml-tag-header-text-view [item]=\"item\"></croco-html-xml-tag-header-text-view>\r\n </div>\r\n <div *ngIf=\"item.type === 'file-image'\">\r\n <croco-html-file-image-tag-view [item]=\"item\" [viewOptions]=\"viewOptions\"></croco-html-file-image-tag-view>\r\n </div>\r\n <div *ngIf=\"item.type === 'table'\">\r\n \r\n <croco-html-xml-tag-html-view *ngIf=\"item.validationResult.isSucceeded\" [html]=\"item.bootstrapHtml\">\r\n </croco-html-xml-tag-html-view>\r\n \r\n <app-tutor-baseapiresponse-banner \r\n *ngIf=\"item.validationResult && !item.validationResult.isSucceeded\" \r\n [message]=\"item.validationResult.message\">\r\n </app-tutor-baseapiresponse-banner>\r\n </div>\r\n \r\n <div *ngIf=\"item.type === 'rich-text'\">\r\n <croco-html-xml-tag-text-view [richTextData]=\"item\"></croco-html-xml-tag-text-view>\r\n </div>\r\n <div *ngIf=\"item.type === 'external-video'\">\r\n <croco-html-xml-tag-external-video [data]=\"item\"></croco-html-xml-tag-external-video>\r\n </div>\r\n <div *ngIf=\"item.type === 'unsupported-tag'\" class=\"red\" style=\"margin-top: 10px;\" >\r\n <h4>\u0414\u0430\u043D\u043D\u044B\u0439 \u0442\u0435\u0433 \u043D\u0435 \u043F\u043E\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044F</h4>\r\n <span>\r\n {{item.data.tagString}}\r\n </span>\r\n </div>\r\n </div>\r\n</div>", styles: [".red{background-color:#c94444;color:#fff}\n"] }]
651
- }], ctorParameters: () => [], propDecorators: { data: [{
652
- type: Input
653
- }] } });
654
-
655
- class AngularMaterialTableMethods {
656
- static getAngularMaterialTableData(columns, rows) {
657
- let data = [];
658
- for (let rowIndex = 0; rowIndex < rows.length; rowIndex++) {
659
- const row = rows[rowIndex];
660
- var elem = {};
661
- for (let columnIndex = 0; columnIndex < columns.length; columnIndex++) {
662
- const column = columns[columnIndex];
663
- elem[column] = row.columns[columnIndex].data.text;
664
- }
665
- data.push(elem);
666
- }
667
- return {
668
- displayedColumns: columns,
669
- data: data,
670
- };
788
+ static sanitizeInnerHtml(html) {
789
+ return html.trim().replace('\n\t', '');
671
790
  }
672
- static checkHeaders(tableData) {
673
- if (tableData.header === null) {
791
+ static toBodyTag(data) {
792
+ if (TextTags.allTextTags.includes(data.type)) {
793
+ let textTagData = data.data;
674
794
  return {
675
- isSucceeded: false,
676
- message: "Необходимо указать заголовок таблицы"
677
- };
678
- }
679
- let columns = tableData.header.columns;
680
- var uniqueDislayedColumns = columns.filter((v, i, a) => a.indexOf(v) === i);
681
- if (uniqueDislayedColumns.length !== columns.length) {
682
- return {
683
- isSucceeded: false,
684
- message: "Ошибка при обработке разметки таблицы. Обнаружены дубликаты заголовков."
795
+ presentOrEdit: true,
796
+ tagDescription: {
797
+ tag: textTagData.textTagName,
798
+ displayValue: BodyTagsExtensions.getDescription(data.type)
799
+ },
800
+ attributes: { "h-align": textTagData.horizontalAlignment },
801
+ innerHtml: BodyTagsExtensions.sanitizeInnerHtml(textTagData.html)
685
802
  };
686
803
  }
687
- return {
688
- isSucceeded: true,
689
- message: "Ok"
690
- };
691
- }
692
- static checkAngularMaterialTableData(tableData, checkHeaders = true) {
693
- if (checkHeaders) {
694
- var checkHeadersResult = this.checkHeaders(tableData);
695
- if (!checkHeadersResult.isSucceeded) {
696
- return checkHeadersResult;
804
+ if (data.type === FileImageTagDataConsts.TagName) {
805
+ let fileData = data.data;
806
+ let attrs = {};
807
+ if (fileData.fileId) {
808
+ attrs[FileImageTagDataConsts.FileIdAttrName] = fileData.fileId;
697
809
  }
810
+ return {
811
+ presentOrEdit: true,
812
+ tagDescription: {
813
+ tag: FileImageTagDataConsts.TagName,
814
+ displayValue: BodyTagsExtensions.getDescription(data.type)
815
+ },
816
+ attributes: attrs,
817
+ innerHtml: ""
818
+ };
698
819
  }
699
- let rows = tableData.rows;
700
- let columns = tableData.header.columns;
701
- for (let i = 0; i < rows.length; i++) {
702
- const row = rows[i];
703
- if (row.columns.length !== columns.length) {
704
- return {
705
- isSucceeded: false,
706
- message: `Ошибка при обработке разметки таблицы. `
707
- + `Количество колонок в каждой строке таблицы должно соотвествовать количеству колонок указанных в заголовке. `
708
- + `В строке таблицы №${i + 1} количество колонок = ${row.columns.length}, а должно быть ${columns.length}.`
709
- };
710
- }
820
+ if (data.type === ExternalVideoTagDataConsts.TagName) {
821
+ let fileData = data.data;
822
+ return {
823
+ presentOrEdit: true,
824
+ tagDescription: {
825
+ tag: data.type,
826
+ displayValue: BodyTagsExtensions.getDescription(data.type)
827
+ },
828
+ attributes: fileData,
829
+ innerHtml: ""
830
+ };
831
+ }
832
+ if (data.type === HtmlRawTagDataConsts.TagName) {
833
+ return {
834
+ presentOrEdit: true,
835
+ tagDescription: {
836
+ tag: HtmlRawTagDataConsts.TagName,
837
+ displayValue: BodyTagsExtensions.getDescription(data.type)
838
+ },
839
+ attributes: {},
840
+ innerHtml: BodyTagsExtensions.sanitizeInnerHtml(data.data["innerHTML"])
841
+ };
711
842
  }
712
843
  return {
713
- isSucceeded: true,
714
- message: "Ok"
844
+ presentOrEdit: true,
845
+ tagDescription: {
846
+ tag: Tags.UnsupportedTag,
847
+ displayValue: "Неподдерживаемый тег"
848
+ },
849
+ attributes: {},
850
+ innerHtml: JSON.stringify(data)
715
851
  };
716
852
  }
717
853
  }
718
854
 
719
- var EAlignments;
720
- (function (EAlignments) {
721
- EAlignments["Left"] = "left";
722
- EAlignments["Center"] = "center";
723
- EAlignments["Right"] = "right";
724
- })(EAlignments || (EAlignments = {}));
725
- const AlignmentsData = [
726
- { value: EAlignments.Left, text: 'Слева' },
727
- { value: EAlignments.Center, text: 'По центру' },
728
- { value: EAlignments.Right, text: 'Справа' },
729
- ];
730
-
731
- const TextTag = "text";
732
- class TextSimpleMethods {
733
- static { this.supportedTags = ["sup", "sub", "strong", "b", "i", "u"]; }
734
- static ExtractTextTag(elem) {
735
- var hAlignValue = elem.getAttribute("h-align") ?? EAlignments.Left;
736
- var data = {
737
- textTagName: elem.tagName.toLowerCase(),
738
- text: elem.innerText.trim().replace('\n\t', ''),
739
- html: elem.innerHTML.trim().replace('\n\t', ''),
740
- horizontalAlignment: hAlignValue,
741
- validationResult: {
742
- isSucceeded: true,
743
- message: "Ok"
744
- }
745
- };
746
- let result = {
747
- type: TextTag,
748
- data: data
749
- };
750
- if (result.data.text === '\n') {
751
- result.data.text = '';
752
- }
753
- if (result.data.html === '\n') {
754
- result.data.html = '';
755
- }
756
- var alignmentVals = [EAlignments.Left, EAlignments.Right, EAlignments.Center];
757
- if (alignmentVals.indexOf(hAlignValue) < 0) {
758
- result.data.validationResult = {
759
- isSucceeded: false,
760
- message: `Недопустимое значение атрибута h-align. Допустимые значения: ${alignmentVals.join(', ')}. `
761
- + 'Данный тег можно не указывать, по-умолчанию будет применено выравнивание слева.'
762
- };
763
- }
764
- var html = result.data.html;
765
- var htmlValidation = this.ValidateTextHtml(html);
766
- if (!htmlValidation.isSucceeded) {
767
- result.data.validationResult = htmlValidation;
768
- }
769
- return result;
855
+ class XmlExtensions {
856
+ static formatXml(xml, tab = '\t') {
857
+ var formatted = '', indent = '';
858
+ tab = tab || '\t';
859
+ xml.split(/>\s*</).forEach(function (node) {
860
+ if (node.match(/^\/\w/))
861
+ indent = indent.substring(tab.length); // decrease indent by one 'tab'
862
+ formatted += indent + '<' + node + '>\r\n';
863
+ if (node.match(/^<?\w[^>]*[^\/]$/))
864
+ indent += tab; // increase indent
865
+ });
866
+ return formatted.substring(1, formatted.length - 3);
770
867
  }
771
- static ValidateTextHtml(html) {
772
- var p = document.createElement("p");
773
- p.innerHTML = html;
774
- for (let i = 0; i < p.children.length; i++) {
775
- const element = p.children.item(i);
776
- var validationResult = this.ValidateTag(element);
777
- if (!validationResult.isSucceeded) {
778
- return validationResult;
779
- }
780
- }
781
- return {
782
- isSucceeded: true,
783
- message: `Ok`
784
- };
868
+ static tagsToLower(xml) {
869
+ xml = this.replaceTagToLower(xml, "Body");
870
+ xml = this.replaceTagToLower(xml, "Image");
871
+ xml = this.replaceTagToLower(xml, "Text");
872
+ return xml;
785
873
  }
786
- static ValidateTag(element) {
787
- let lowerTag = element.tagName.toLowerCase();
788
- if (!this.supportedTags.includes(lowerTag)) {
789
- return {
790
- isSucceeded: false,
791
- message: `Тег <${lowerTag}> не поддерживается внутри тега <text>`
792
- };
793
- }
794
- for (let i = 0; i < element.children.length; i++) {
795
- const nElement = element.children.item(i);
796
- var innerValidationResult = this.ValidateTag(nElement);
797
- if (!innerValidationResult.isSucceeded) {
798
- return innerValidationResult;
799
- }
800
- }
801
- return {
802
- isSucceeded: true,
803
- message: "Ok"
804
- };
874
+ static replaceTagToLower(xml, tag) {
875
+ return xml
876
+ .replace(new RegExp(`<${tag}`, 'g'), `<${tag.toLowerCase()}`)
877
+ .replace(new RegExp(`</${tag}>`, 'g'), `</${tag.toLowerCase()}>`);
805
878
  }
806
879
  }
807
880
 
808
- class BootstrapTableMethods {
809
- static BuildTable(data) {
810
- let result = `<table class="table table-bordered">`;
811
- result += this.BuildHeader(data.header);
812
- result += this.BuildBody(data.rows);
881
+ class TableBuilder {
882
+ static getTableMarkUp(rows, cols, generateHeaders) {
883
+ rows = +rows;
884
+ cols = +cols;
885
+ let result = "<table>";
886
+ if (generateHeaders) {
887
+ result += TableBuilder.getTableHeaderMarkUp(cols);
888
+ }
889
+ result += TableBuilder.getTableBodyMarkUp(cols, rows);
813
890
  result += "</table>";
814
- return result;
891
+ return XmlExtensions.formatXml(result);
815
892
  }
816
- static BuildHeader(data) {
817
- if (data === null) {
818
- return "";
819
- }
820
- let result = "<thead>";
821
- result += "<tr>";
822
- for (let index = 0; index < data.columns.length; index++) {
823
- result += `<th>${data.columns[index]}</th>`;
893
+ static getTableHeaderMarkUp(cols) {
894
+ let result = "<thead><tr>";
895
+ for (let i = 0; i < cols; i++) {
896
+ result += `<th>Колонка #${i + 1}</th>`;
824
897
  }
825
- result += "</tr>";
826
- result += "</thead>";
898
+ result += "</tr></thead>";
827
899
  return result;
828
900
  }
829
- static BuildBody(rows) {
901
+ static getTableBodyMarkUp(cols, rows) {
830
902
  let result = "<tbody>";
831
- for (let i = 0; i < rows.length; i++) {
832
- const row = rows[i];
903
+ for (let row = 0; row < rows; row++) {
833
904
  result += "<tr>";
834
- for (let j = 0; j < row.columns.length; j++) {
835
- const col = row.columns[j];
836
- result += `<td class="align-middle">${this.BuildInnerTags(col.data.children)}</td>`;
905
+ for (let i = 0; i < cols; i++) {
906
+ result += `<td>Ряд№${row + 1} Колонка #${i + 1}</td>`;
837
907
  }
838
908
  result += "</tr>";
839
909
  }
840
910
  result += "</tbody>";
841
911
  return result;
842
912
  }
843
- static BuildInnerTags(tags) {
844
- let result = "";
845
- for (let i = 0; i < tags.length; i++) {
846
- result += this.BuildInnerTag(tags[i]);
847
- }
848
- return result;
849
- }
850
- static BuildInnerTag(data) {
851
- if (data.type === FileImageTagDataConsts.TagName) {
852
- let fileImageTag = data;
853
- return `<img src=${fileImageTag.data.src} class="mx-auto d-block img-fluid" />`;
854
- }
855
- else if (data.type === TextTag) {
856
- let simpleTextTag = data;
857
- var map = {
858
- ["left"]: "text-start",
859
- ["center"]: "text-center",
860
- ["right"]: "text-end"
861
- };
862
- if (!simpleTextTag.data.validationResult.isSucceeded) {
863
- return `<span>Ошибка в тексте ${simpleTextTag.data.validationResult.message}</span>`;
864
- }
865
- return `<div class="${map[simpleTextTag.data.horizontalAlignment]}"><span>${simpleTextTag.data.html}</span></div>`;
866
- }
867
- else {
868
- return `<p>Тег ${data.type} не поддерживается</p>`;
869
- }
870
- }
871
913
  }
872
914
 
873
- class TableTypes {
874
- static { this.TableRowColumnData = "table-row-column-data"; }
875
- static { this.Table = "table"; }
876
- static { this.TableRowColumn = "table-row-column"; }
877
- }
878
- class TableMethods {
879
- static getTableFromHtmlTag(tableTag, options) {
880
- let tableData = {
881
- header: TableMethods.getHeader(tableTag),
882
- rows: TableMethods.getTableRows(tableTag, options)
915
+ function resizeObservable(elem, options) {
916
+ return new Observable((subscriber) => {
917
+ const resizeObserver = new ResizeObserver(([entry]) => {
918
+ subscriber.next(entry);
919
+ });
920
+ resizeObserver.observe(elem, options);
921
+ return function unsubscribe() {
922
+ resizeObserver.unobserve(elem);
883
923
  };
884
- var result = {
885
- type: TableTypes.Table,
886
- data: tableData,
887
- validationResult: this.checkTable(tableData),
888
- bootstrapHtml: ""
924
+ });
925
+ }
926
+
927
+ class VkVideoPlayerComponent {
928
+ set link(link) {
929
+ this.safeUrl = this.sanitizer.bypassSecurityTrustResourceUrl(link);
930
+ }
931
+ constructor(sanitizer) {
932
+ this.sanitizer = sanitizer;
933
+ }
934
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: VkVideoPlayerComponent, deps: [{ token: i1$2.DomSanitizer }], target: i0.ɵɵFactoryTarget.Component }); }
935
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.4", type: VkVideoPlayerComponent, isStandalone: true, selector: "vk-video-player", inputs: { link: "link" }, ngImport: i0, template: "<div class=\"vk-video-player\">\n <iframe\n [src]=\"safeUrl\"\n width=\"100%\"\n height=\"100%\"\n allow=\"autoplay; encrypted-media; fullscreen; picture-in-picture;\"\n frameborder=\"0\"\n allowfullscreen></iframe>\n</div>\n", styles: [".vk-video-player{margin:0 auto;max-width:640px;width:100%;height:360px}@media screen and (max-width: 760px){.vk-video-player{height:300px}}@media screen and (max-width: 540px){.vk-video-player{height:250px}}@media screen and (max-width: 450px){.vk-video-player{height:200px}}@media screen and (max-width: 380px){.vk-video-player{height:180px}}\n"] }); }
936
+ }
937
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: VkVideoPlayerComponent, decorators: [{
938
+ type: Component,
939
+ args: [{ selector: 'vk-video-player', standalone: true, imports: [], template: "<div class=\"vk-video-player\">\n <iframe\n [src]=\"safeUrl\"\n width=\"100%\"\n height=\"100%\"\n allow=\"autoplay; encrypted-media; fullscreen; picture-in-picture;\"\n frameborder=\"0\"\n allowfullscreen></iframe>\n</div>\n", styles: [".vk-video-player{margin:0 auto;max-width:640px;width:100%;height:360px}@media screen and (max-width: 760px){.vk-video-player{height:300px}}@media screen and (max-width: 540px){.vk-video-player{height:250px}}@media screen and (max-width: 450px){.vk-video-player{height:200px}}@media screen and (max-width: 380px){.vk-video-player{height:180px}}\n"] }]
940
+ }], ctorParameters: () => [{ type: i1$2.DomSanitizer }], propDecorators: { link: [{
941
+ type: Input
942
+ }] } });
943
+
944
+ class XmlTagExternalVideoComponent {
945
+ set data(value) {
946
+ this.tagData = value.data;
947
+ }
948
+ ;
949
+ set tagData(value) {
950
+ this._block = {
951
+ type: value.type,
952
+ link: value.link
889
953
  };
890
- if (!result.validationResult) {
891
- return result;
954
+ if (this._block.type === ExternalVideoSupportedTypes.VkVideo) {
955
+ return;
892
956
  }
893
- result.bootstrapHtml = BootstrapTableMethods.BuildTable(result.data);
894
- var angularMaterialTableDataCheck = AngularMaterialTableMethods.checkAngularMaterialTableData(tableData);
895
- if (!angularMaterialTableDataCheck.isSucceeded) {
896
- return {
897
- ...result,
898
- angularMaterialTableDataCheck
899
- };
900
- }
901
- return {
902
- ...result,
903
- angularMaterialTableDataCheck,
904
- html: tableTag.outerHTML,
905
- angularMaterialTableData: AngularMaterialTableMethods.getAngularMaterialTableData(tableData.header.columns, tableData.rows),
906
- };
957
+ this.videoId = this.getYouTubeId(this._block.link);
907
958
  }
908
- static checkTable(tableData) {
909
- let rows = tableData.rows;
910
- let prevRowCount = -1;
911
- for (let i = 0; i < rows.length; i++) {
912
- const row = rows[i];
913
- if (row.columns.length !== prevRowCount && prevRowCount != -1) {
914
- return {
915
- isSucceeded: false,
916
- message: `Ошибка при обработке разметки таблицы. `
917
- + `Количество колонок в каждой строке таблицы должно соотвествовать друг другу. `
918
- + `В строке таблицы №${i + 1} количество колонок = ${row.columns.length}, а в строке выше ${prevRowCount}.`
919
- };
920
- }
921
- prevRowCount = row.columns.length;
922
- }
923
- return {
924
- isSucceeded: true,
925
- message: "Ok"
959
+ ;
960
+ constructor(destroyRef) {
961
+ this.destroyRef = destroyRef;
962
+ this._block = {
963
+ type: '',
964
+ link: ''
926
965
  };
966
+ this.playerWidth = signal(NaN);
967
+ this.playerHeight = signal(NaN);
968
+ this.ExternalVideoSupportedTypes = ExternalVideoSupportedTypes;
927
969
  }
928
- static getHeader(tableTag) {
929
- let header = tableTag.tHead;
930
- if (header === null) {
931
- return null;
970
+ ngOnInit() {
971
+ if (this._block.type === ExternalVideoSupportedTypes.VkVideo) {
972
+ return;
932
973
  }
933
- let tr = header.children.item(0);
934
- let headerColumns = [];
935
- for (let j = 0; j < tr.children.length; j++) {
936
- const jElement = tr.children.item(j);
937
- headerColumns.push(jElement.innerHTML);
974
+ const youtubeIframeApiUrl = 'https://www.youtube.com/iframe_api';
975
+ if (!document.querySelector(`script[src="${youtubeIframeApiUrl}"]`)) {
976
+ // This code loads the IFrame Player API code asynchronously, according to the instructions at
977
+ // https://developers.google.com/youtube/iframe_api_reference#Getting_Started
978
+ const tag = document.createElement('script');
979
+ tag.setAttribute('src', youtubeIframeApiUrl);
980
+ document.body.appendChild(tag);
938
981
  }
939
- return {
940
- type: "table-header",
941
- columns: headerColumns
942
- };
943
- }
944
- static getTableRows(tableTag, options) {
945
- let tBody = tableTag.tBodies.item(0);
946
- let rows = [];
947
- for (let i = 0; i < tBody.children.length; i++) {
948
- const iElement = tBody.children.item(i);
949
- let rowColumns = [];
950
- for (let j = 0; j < iElement.children.length; j++) {
951
- const jElement = iElement.children.item(j);
952
- let children = HtmlExtractionMethods.transformHtmlElementToBlocks(jElement, options);
953
- if (children.length === 0) {
954
- var textTag = document.createElement("p");
955
- textTag.innerHTML = jElement.innerHTML;
956
- var textElem = TextSimpleMethods.ExtractTextTag(textTag);
957
- children.push(textElem);
958
- }
959
- var result = {
960
- type: TableTypes.TableRowColumnData,
961
- data: {
962
- text: jElement.innerHTML,
963
- children
964
- }
965
- };
966
- rowColumns.push(result);
967
- }
968
- rows.push({
969
- type: TableTypes.TableRowColumn,
970
- columns: rowColumns
982
+ if (this.playerContainerRef) {
983
+ resizeObservable(this.playerContainerRef.nativeElement)
984
+ .pipe(map(({ contentRect: { height, width } }) => ({ height, width })), distinctUntilChanged((a, b) => a.height === b.height && a.width === b.width), takeUntilDestroyed(this.destroyRef))
985
+ .subscribe(({ height, width }) => {
986
+ this.playerHeight.set(height);
987
+ this.playerWidth.set(width);
971
988
  });
972
989
  }
973
- return rows;
974
990
  }
991
+ getYouTubeId(youtubeLink) {
992
+ //https://www.youtube.com/watch?v=l3KfbfkxJOU
993
+ const url = new URL(youtubeLink);
994
+ if (url.pathname.endsWith('watch')) {
995
+ return url.searchParams.get("v");
996
+ }
997
+ //https://youtu.be/jzBneaWSswY
998
+ const bits = url.pathname.split('/');
999
+ return bits[bits.length - 1];
1000
+ }
1001
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: XmlTagExternalVideoComponent, deps: [{ token: i0.DestroyRef }], target: i0.ɵɵFactoryTarget.Component }); }
1002
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.4", type: XmlTagExternalVideoComponent, selector: "croco-html-xml-tag-external-video", inputs: { data: "data", tagData: "tagData" }, viewQueries: [{ propertyName: "playerContainerRef", first: true, predicate: ["playerContainer"], descendants: true, static: true }], ngImport: i0, template: "@switch (_block.type) {\n @case (ExternalVideoSupportedTypes.VkVideo) {\n <vk-video-player [link]=\"_block.link\"></vk-video-player>\n }\n @case (ExternalVideoSupportedTypes.Youtube) {\n <div #playerContainer class=\"d-flex justify-content-center y-video\">\n @if (videoId) {\n <youtube-player [height]=\"playerHeight()\" [width]=\"playerWidth()\" [videoId]=\"videoId\"></youtube-player>\n }\n </div>\n }\n}\n", styles: ["@media only screen and (min-width: 769px){.y-video{display:block;width:640px;height:360px;margin:0 auto}}@media only screen and (max-width: 827px){.y-video{display:block;width:100%;height:315px}}\n"], dependencies: [{ kind: "component", type: i1$3.YouTubePlayer, selector: "youtube-player", inputs: ["videoId", "height", "width", "startSeconds", "endSeconds", "suggestedQuality", "playerVars", "disableCookies", "loadApi", "disablePlaceholder", "showBeforeIframeApiLoads", "placeholderButtonLabel", "placeholderImageQuality"], outputs: ["ready", "stateChange", "error", "apiChange", "playbackQualityChange", "playbackRateChange"] }, { kind: "component", type: VkVideoPlayerComponent, selector: "vk-video-player", inputs: ["link"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
975
1003
  }
1004
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: XmlTagExternalVideoComponent, decorators: [{
1005
+ type: Component,
1006
+ args: [{ selector: 'croco-html-xml-tag-external-video', changeDetection: ChangeDetectionStrategy.OnPush, template: "@switch (_block.type) {\n @case (ExternalVideoSupportedTypes.VkVideo) {\n <vk-video-player [link]=\"_block.link\"></vk-video-player>\n }\n @case (ExternalVideoSupportedTypes.Youtube) {\n <div #playerContainer class=\"d-flex justify-content-center y-video\">\n @if (videoId) {\n <youtube-player [height]=\"playerHeight()\" [width]=\"playerWidth()\" [videoId]=\"videoId\"></youtube-player>\n }\n </div>\n }\n}\n", styles: ["@media only screen and (min-width: 769px){.y-video{display:block;width:640px;height:360px;margin:0 auto}}@media only screen and (max-width: 827px){.y-video{display:block;width:100%;height:315px}}\n"] }]
1007
+ }], ctorParameters: () => [{ type: i0.DestroyRef }], propDecorators: { data: [{
1008
+ type: Input
1009
+ }], tagData: [{
1010
+ type: Input
1011
+ }], playerContainerRef: [{
1012
+ type: ViewChild,
1013
+ args: ['playerContainer', { static: true }]
1014
+ }] } });
976
1015
 
977
- class TextMethods {
978
- static { this.textTags = ["text", "h1", "h2", "h3", "h4", "h5", "h6"]; }
979
- static ExtractRichTextData(elem) {
980
- let children = [];
981
- for (let i = 0; i < elem.children.length; i++) {
982
- const child = elem.children.item(i);
983
- if (child.tagName === "text-block".toUpperCase()) {
984
- children.push({
985
- type: "text-block",
986
- data: {
987
- text: child.innerHTML
988
- }
989
- });
990
- }
991
- else if (child.tagName === "line-break".toUpperCase()) {
992
- children.push({
993
- type: "line-break"
994
- });
995
- }
996
- }
997
- return {
998
- type: "rich-text",
999
- data: {
1000
- children
1001
- }
1016
+ class ExternalVideoBlockComponent {
1017
+ constructor() {
1018
+ this.onTagUpdated = new EventEmitter();
1019
+ this.defaultYoutubeLink = "https://youtu.be/jzBneaWSswY";
1020
+ this.defaultVkLink = "https://vk.com/video_ext.php?oid=-22822305&id=456241864&hd=2";
1021
+ this.ExternalVideoSupportedTypes = ExternalVideoSupportedTypes;
1022
+ this.tagData = {
1023
+ link: this.defaultYoutubeLink,
1024
+ type: ExternalVideoSupportedTypes.Youtube
1002
1025
  };
1003
1026
  }
1027
+ ngOnInit() {
1028
+ this.tagData.link = this.tag.attributes.type === ExternalVideoSupportedTypes.VkVideo ? this.defaultVkLink : this.defaultYoutubeLink;
1029
+ this.tagData.type = this.tag.attributes.type;
1030
+ }
1031
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: ExternalVideoBlockComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1032
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.4", type: ExternalVideoBlockComponent, selector: "croco-html-external-video-block", inputs: { tag: "tag" }, outputs: { onTagUpdated: "onTagUpdated" }, ngImport: i0, template: "@if (tag.presentOrEdit) {\n <div>\n <div>\n @switch (tagData.type) {\n @case (ExternalVideoSupportedTypes.VkVideo) {\n \u0421\u0441\u044B\u043B\u043A\u0430 \u043D\u0430 Vk Video: {{tagData.link}}\n }\n @case (ExternalVideoSupportedTypes.Youtube) {\n \u0421\u0441\u044B\u043B\u043A\u0430 \u043D\u0430 YouTube: {{tagData.link}}\n }\n }\n </div>\n <div style=\"height: 10px;\"></div>\n <croco-html-xml-tag-external-video [tagData]=\"tagData\"></croco-html-xml-tag-external-video>\n </div>\n}\n\n@if (!tag.presentOrEdit) {\n <div>\n <div>\n <div>\n <mat-form-field class=\"w-100\">\n <input matInput placeholder=\"\u0421\u0441\u044B\u043B\u043A\u0430 \u043D\u0430 YouTube\"\n autocomplete=\"off\"\n [(ngModel)]=\"tagData.link\">\n </mat-form-field>\n </div>\n </div>\n </div>\n}\n", styles: [""], dependencies: [{ kind: "directive", type: i1$4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i2.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: XmlTagExternalVideoComponent, selector: "croco-html-xml-tag-external-video", inputs: ["data", "tagData"] }] }); }
1004
1033
  }
1034
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: ExternalVideoBlockComponent, decorators: [{
1035
+ type: Component,
1036
+ args: [{ selector: 'croco-html-external-video-block', template: "@if (tag.presentOrEdit) {\n <div>\n <div>\n @switch (tagData.type) {\n @case (ExternalVideoSupportedTypes.VkVideo) {\n \u0421\u0441\u044B\u043B\u043A\u0430 \u043D\u0430 Vk Video: {{tagData.link}}\n }\n @case (ExternalVideoSupportedTypes.Youtube) {\n \u0421\u0441\u044B\u043B\u043A\u0430 \u043D\u0430 YouTube: {{tagData.link}}\n }\n }\n </div>\n <div style=\"height: 10px;\"></div>\n <croco-html-xml-tag-external-video [tagData]=\"tagData\"></croco-html-xml-tag-external-video>\n </div>\n}\n\n@if (!tag.presentOrEdit) {\n <div>\n <div>\n <div>\n <mat-form-field class=\"w-100\">\n <input matInput placeholder=\"\u0421\u0441\u044B\u043B\u043A\u0430 \u043D\u0430 YouTube\"\n autocomplete=\"off\"\n [(ngModel)]=\"tagData.link\">\n </mat-form-field>\n </div>\n </div>\n </div>\n}\n" }]
1037
+ }], propDecorators: { tag: [{
1038
+ type: Input
1039
+ }], onTagUpdated: [{
1040
+ type: Output
1041
+ }] } });
1005
1042
 
1006
- class HtmlExtractionMethods {
1007
- static ExtractHeaderTag(elem, tagName) {
1008
- var data = TextSimpleMethods.ExtractTextTag(elem);
1009
- data.type = tagName;
1010
- return data;
1043
+ class HtmlRawEditorComponent {
1044
+ constructor() {
1045
+ this.onTagUpdated = new EventEmitter();
1011
1046
  }
1012
- static { this.Extractors = {
1013
- ["TEXT"]: (elem, options) => TextSimpleMethods.ExtractTextTag(elem),
1014
- ["FILE-IMAGE"]: (elem, options) => ImageMethods.ExtractImage(elem, options),
1015
- ["TABLE"]: (elem, options) => TableMethods.getTableFromHtmlTag(elem, options),
1016
- ["RICH-TEXT"]: (elem, options) => TextMethods.ExtractRichTextData(elem),
1017
- ["HTML-RAW"]: (elem, options) => ({
1018
- type: "html-raw",
1019
- data: {
1020
- innerHTML: elem.innerHTML
1021
- }
1022
- }),
1023
- ["H1"]: (elem, options) => HtmlExtractionMethods.ExtractHeaderTag(elem, "h1"),
1024
- ["H2"]: (elem, options) => HtmlExtractionMethods.ExtractHeaderTag(elem, "h2"),
1025
- ["H3"]: (elem, options) => HtmlExtractionMethods.ExtractHeaderTag(elem, "h3"),
1026
- ["H4"]: (elem, options) => HtmlExtractionMethods.ExtractHeaderTag(elem, "h4"),
1027
- ["H5"]: (elem, options) => HtmlExtractionMethods.ExtractHeaderTag(elem, "h5"),
1028
- ["H6"]: (elem, options) => HtmlExtractionMethods.ExtractHeaderTag(elem, "h6"),
1029
- [ExternalVideoTagDataConsts.TagName.toUpperCase()]: (elem, options) => VideoMethods.ExtractExternalVideoTag(elem)
1030
- }; }
1031
- static transformHtmlElementToBlocks(element, options) {
1032
- var data = [];
1033
- for (let i = 0; i < element.children.length; i++) {
1034
- var elem = element.children.item(i);
1035
- if (!HtmlExtractionMethods.Extractors.hasOwnProperty(elem.tagName)) {
1036
- data.push({
1037
- type: "unsupported-tag",
1038
- data: {
1039
- tagString: elem.outerHTML
1040
- }
1041
- });
1042
- }
1043
- else {
1044
- var extractor = HtmlExtractionMethods.Extractors[elem.tagName];
1045
- var result = extractor(elem, options);
1046
- data.push(result);
1047
- }
1048
- }
1049
- return data;
1047
+ ngOnInit() {
1050
1048
  }
1051
- static transformHtmlStringToBlocks(value, options) {
1052
- if (value === undefined || value === null) {
1053
- return [];
1054
- }
1055
- value = value
1056
- .replace('\n', '')
1057
- .replace('\t', '');
1058
- var div = document.createElement("div");
1059
- div.innerHTML = value;
1060
- return this.transformHtmlElementToBlocks(div, options);
1049
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: HtmlRawEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1050
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.4", type: HtmlRawEditorComponent, selector: "croco-html-html-raw-editor", inputs: { tag: "tag" }, outputs: { onTagUpdated: "onTagUpdated" }, ngImport: i0, template: "@if (tag.presentOrEdit) {\n <div>\n <div [innerHTML]=\"tag.innerHtml\"></div>\n </div>\n}\n\n@if (!tag.presentOrEdit) {\n <div>\n <div style=\"height: 10px;\">\n </div>\n <div>\n <mat-form-field class=\"w-100\">\n <textarea matInput cdkTextareaAutosize #autosize=\"cdkTextareaAutosize\"\n cdkAutosizeMinRows=\"1\"\n placeholder=\"\u0412\u043D\u0443\u0442\u0440\u0435\u043D\u043D\u044F\u044F \u0440\u0430\u0437\u043C\u0435\u0442\u043A\u0430 \u0442\u0435\u0433\u0430\"\n [(ngModel)]=\"tag.innerHtml\"></textarea>\n </mat-form-field>\n </div>\n </div>\n}\n\n", styles: [""], dependencies: [{ kind: "directive", type: i1$4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i2.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "directive", type: i4.CdkTextareaAutosize, selector: "textarea[cdkTextareaAutosize]", inputs: ["cdkAutosizeMinRows", "cdkAutosizeMaxRows", "cdkTextareaAutosize", "placeholder"], exportAs: ["cdkTextareaAutosize"] }] }); }
1051
+ }
1052
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: HtmlRawEditorComponent, decorators: [{
1053
+ type: Component,
1054
+ args: [{ selector: 'croco-html-html-raw-editor', template: "@if (tag.presentOrEdit) {\n <div>\n <div [innerHTML]=\"tag.innerHtml\"></div>\n </div>\n}\n\n@if (!tag.presentOrEdit) {\n <div>\n <div style=\"height: 10px;\">\n </div>\n <div>\n <mat-form-field class=\"w-100\">\n <textarea matInput cdkTextareaAutosize #autosize=\"cdkTextareaAutosize\"\n cdkAutosizeMinRows=\"1\"\n placeholder=\"\u0412\u043D\u0443\u0442\u0440\u0435\u043D\u043D\u044F\u044F \u0440\u0430\u0437\u043C\u0435\u0442\u043A\u0430 \u0442\u0435\u0433\u0430\"\n [(ngModel)]=\"tag.innerHtml\"></textarea>\n </mat-form-field>\n </div>\n </div>\n}\n\n" }]
1055
+ }], ctorParameters: () => [], propDecorators: { tag: [{
1056
+ type: Input
1057
+ }], onTagUpdated: [{
1058
+ type: Output
1059
+ }] } });
1060
+
1061
+ const CrocoHtmlOptionsToken = "croco-html-options";
1062
+
1063
+ var FileType;
1064
+ (function (FileType) {
1065
+ FileType["Undefined"] = "Undefined";
1066
+ FileType["Unknown"] = "Unknown";
1067
+ FileType["Image"] = "Image";
1068
+ FileType["Audio"] = "Audio";
1069
+ FileType["Video"] = "Video";
1070
+ FileType["Document"] = "Document";
1071
+ FileType["Archive"] = "Archive";
1072
+ })(FileType || (FileType = {}));
1073
+ class FilesQueryService {
1074
+ constructor(_httpClient, baseUrl) {
1075
+ this._httpClient = _httpClient;
1076
+ this._baseControllerUrl = `${baseUrl}Api/Files`;
1077
+ }
1078
+ getFilesWithRelations(model) {
1079
+ return this._httpClient.post(this._baseControllerUrl + `/GetFiles/WithRelations`, model);
1080
+ }
1081
+ getFiles(model) {
1082
+ return this._httpClient.post(this._baseControllerUrl + `/GetFiles`, model);
1083
+ }
1084
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: FilesQueryService, deps: [{ token: i1.HttpClient }, { token: 'BASE_URL' }], target: i0.ɵɵFactoryTarget.Injectable }); }
1085
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: FilesQueryService, providedIn: 'root' }); }
1086
+ }
1087
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: FilesQueryService, decorators: [{
1088
+ type: Injectable,
1089
+ args: [{
1090
+ providedIn: 'root'
1091
+ }]
1092
+ }], ctorParameters: () => [{ type: i1.HttpClient }, { type: undefined, decorators: [{
1093
+ type: Inject,
1094
+ args: ['BASE_URL']
1095
+ }] }] });
1096
+
1097
+ class FileIdSelectComponent {
1098
+ constructor(_fileService, _options) {
1099
+ this._fileService = _fileService;
1100
+ this._options = _options;
1101
+ this.labelText = "Поиск файлов";
1102
+ this.loading = false;
1103
+ this.files = [];
1104
+ this.onFileIdChanged = new EventEmitter();
1105
+ }
1106
+ onModelChanged(fileId) {
1107
+ this.onFileIdChanged.emit(fileId);
1108
+ }
1109
+ getSrc(fileId) {
1110
+ return ImageMethods.buildSmallUrl(fileId, this._options);
1111
+ }
1112
+ ngOnInit() {
1113
+ this.loadFiles();
1114
+ }
1115
+ loadFiles() {
1116
+ this.loading = true;
1117
+ this._fileService.getFiles({
1118
+ count: 10,
1119
+ offSet: 0,
1120
+ fileName: null,
1121
+ fileTypes: [FileType.Image],
1122
+ applicationId: null,
1123
+ q: this.q
1124
+ }).subscribe(data => {
1125
+ this.files = [...data.list];
1126
+ this.loading = false;
1127
+ });
1128
+ }
1129
+ onSearchChanged(q) {
1130
+ this.q = q.term;
1131
+ this.loadFiles();
1132
+ }
1133
+ ngOnChanges(changes) {
1134
+ this.loadFiles();
1135
+ }
1136
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: FileIdSelectComponent, deps: [{ token: FilesQueryService }, { token: CrocoHtmlOptionsToken }], target: i0.ɵɵFactoryTarget.Component }); }
1137
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.4", type: FileIdSelectComponent, selector: "croco-html-file-id-select", inputs: { labelText: "labelText", fileId: "fileId" }, outputs: { fileId: "fileId", onFileIdChanged: "onFileIdChanged" }, usesOnChanges: true, ngImport: i0, template: "<div>\n <div class=\"form-group\">\n <label for=\"fileName\">{{labelText}}</label>\n <ng-select [(ngModel)]=\"fileId\" (ngModelChange)=\"onModelChanged($event)\"\n [items]=\"files\"\n #select\n bindLabel=\"fileName\"\n (search)=\"onSearchChanged($event)\"\n [loading]=\"loading\"\n [loadingText]=\"'\u0417\u0430\u0433\u0440\u0443\u0436\u0430\u044E \u0444\u0430\u0439\u043B\u044B'\"\n dropdownPosition=\"auto\"\n bindValue=\"fileId\"\n labelForId=\"fileName\"\n placeholder=\"\u0412\u044B\u0431\u0440\u0430\u0442\u044C \u0444\u0430\u0439\u043B\"\n [virtualScroll]=\"true\">\n <ng-template ng-option-tmp let-item=\"item\" let-index=\"index\" let-search=\"searchTerm\">\n <div>\n <img class=\"mx-auto d-block img-fluid\" [src]=\"getSrc(item.fileId)\"/>\n </div>\n <div>\n <span class=\"h5\">\u0424\u0430\u0439\u043B: </span>\n <span class=\"h5\" [ngOptionHighlight]=\"search\"><b>{{item.fileName}}</b></span>\n </div>\n <div>\n <small>\n <span>\n \u0418\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u043E\u0440 \u0444\u0430\u0439\u043B\u0430: <b>{{item.fileId}}</b>\n </span>\n </small>\n </div>\n </ng-template>\n </ng-select>\n </div>\n</div>\n\n<div>\n \u0418\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u043E\u0440 \u0444\u0430\u0439\u043B\u0430: {{fileId}}\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i3$1.NgSelectComponent, selector: "ng-select", inputs: ["bindLabel", "bindValue", "markFirst", "placeholder", "notFoundText", "typeToSearchText", "addTagText", "loadingText", "clearAllText", "appearance", "dropdownPosition", "appendTo", "loading", "closeOnSelect", "hideSelected", "selectOnTab", "openOnEnter", "maxSelectedItems", "groupBy", "groupValue", "bufferAmount", "virtualScroll", "selectableGroup", "selectableGroupAsModel", "searchFn", "trackByFn", "clearOnBackspace", "labelForId", "inputAttrs", "tabIndex", "readonly", "searchWhileComposing", "minTermLength", "editableSearchTerm", "keyDownFn", "typeahead", "multiple", "addTag", "searchable", "clearable", "isOpen", "items", "compareWith", "clearSearchOnAdd", "deselectOnClick"], outputs: ["blur", "focus", "change", "open", "close", "search", "clear", "add", "remove", "scroll", "scrollToEnd"] }, { kind: "directive", type: i3$1.NgOptionTemplateDirective, selector: "[ng-option-tmp]" }] }); }
1138
+ }
1139
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: FileIdSelectComponent, decorators: [{
1140
+ type: Component,
1141
+ args: [{ selector: 'croco-html-file-id-select', template: "<div>\n <div class=\"form-group\">\n <label for=\"fileName\">{{labelText}}</label>\n <ng-select [(ngModel)]=\"fileId\" (ngModelChange)=\"onModelChanged($event)\"\n [items]=\"files\"\n #select\n bindLabel=\"fileName\"\n (search)=\"onSearchChanged($event)\"\n [loading]=\"loading\"\n [loadingText]=\"'\u0417\u0430\u0433\u0440\u0443\u0436\u0430\u044E \u0444\u0430\u0439\u043B\u044B'\"\n dropdownPosition=\"auto\"\n bindValue=\"fileId\"\n labelForId=\"fileName\"\n placeholder=\"\u0412\u044B\u0431\u0440\u0430\u0442\u044C \u0444\u0430\u0439\u043B\"\n [virtualScroll]=\"true\">\n <ng-template ng-option-tmp let-item=\"item\" let-index=\"index\" let-search=\"searchTerm\">\n <div>\n <img class=\"mx-auto d-block img-fluid\" [src]=\"getSrc(item.fileId)\"/>\n </div>\n <div>\n <span class=\"h5\">\u0424\u0430\u0439\u043B: </span>\n <span class=\"h5\" [ngOptionHighlight]=\"search\"><b>{{item.fileName}}</b></span>\n </div>\n <div>\n <small>\n <span>\n \u0418\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u043E\u0440 \u0444\u0430\u0439\u043B\u0430: <b>{{item.fileId}}</b>\n </span>\n </small>\n </div>\n </ng-template>\n </ng-select>\n </div>\n</div>\n\n<div>\n \u0418\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u043E\u0440 \u0444\u0430\u0439\u043B\u0430: {{fileId}}\n</div>\n" }]
1142
+ }], ctorParameters: () => [{ type: FilesQueryService }, { type: undefined, decorators: [{
1143
+ type: Inject,
1144
+ args: [CrocoHtmlOptionsToken]
1145
+ }] }], propDecorators: { labelText: [{
1146
+ type: Input
1147
+ }], fileId: [{
1148
+ type: Input
1149
+ }, {
1150
+ type: Output
1151
+ }], onFileIdChanged: [{
1152
+ type: Output
1153
+ }] } });
1154
+
1155
+ class ImageEditorComponent {
1156
+ onErrorHandler() {
1157
+ this.hasImageError = true;
1158
+ }
1159
+ constructor(_options) {
1160
+ this._options = _options;
1161
+ this.hasImageError = false;
1162
+ this.searchOrEdit = "search";
1163
+ this.onTagUpdated = new EventEmitter();
1164
+ }
1165
+ getSrc() {
1166
+ return ImageMethods.buildUrl(this.tag.attributes[FileImageTagDataConsts.FileIdAttrName], "Medium", this._options);
1167
+ }
1168
+ hasFileId() {
1169
+ return this.tag.attributes.hasOwnProperty(FileImageTagDataConsts.FileIdAttrName) && !isNaN(this.tag.attributes[FileImageTagDataConsts.FileIdAttrName]);
1170
+ }
1171
+ onFileIdChanged(fileId) {
1172
+ this.tag.attributes[FileImageTagDataConsts.FileIdAttrName] = fileId;
1173
+ this.removeImageError();
1174
+ }
1175
+ removeImageError() {
1176
+ this.hasImageError = false;
1177
+ }
1178
+ ngOnInit() {
1061
1179
  }
1180
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: ImageEditorComponent, deps: [{ token: CrocoHtmlOptionsToken }], target: i0.ɵɵFactoryTarget.Component }); }
1181
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.4", type: ImageEditorComponent, selector: "croco-html-image-editor", inputs: { tag: "tag" }, outputs: { onTagUpdated: "onTagUpdated" }, ngImport: i0, template: "<div>\n <div style=\"height: 10px;\">\n </div>\n\n @if (hasImageError) {\n <div class=\"error-block\">\n \u0418\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435 \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D\u043E \u043F\u043E \u0443\u043A\u0430\u0437\u0430\u043D\u043D\u043E\u043C\u0443 \u0438\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u043E\u0440\u0443, \u0432\u043E\u0437\u043C\u043E\u0436\u043D\u043E \u0444\u0430\u0439\u043B \u043D\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0438\u043B\u0438 \u043E\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043D\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435.\n </div>\n }\n\n @if (hasFileId() && !hasImageError) {\n <div>\n <img class=\"mx-auto d-block img-fluid\" [src]=\"getSrc()\" (error)=\"onErrorHandler()\"/>\n </div>\n }\n\n @if (!hasFileId()) {\n <div>\n <h5>[\u0418\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435 \u043D\u0435 \u0432\u044B\u0431\u0440\u0430\u043D\u043E]</h5>\n </div>\n }\n</div>\n\n@if (!tag.presentOrEdit) {\n <div>\n <div style=\"height: 10px;\"></div>\n <div style=\"overflow-x:auto;\">\n <mat-button-toggle-group [(ngModel)]=\"searchOrEdit\">\n <mat-button-toggle value=\"search\">\n \u0418\u0441\u043A\u0430\u0442\u044C \u0444\u0430\u0439\u043B <mat-icon>search</mat-icon>\n </mat-button-toggle>\n <mat-button-toggle value=\"edit\">\n \u0423\u043A\u0430\u0437\u0430\u0442\u044C \u043F\u043E \u0438\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u043E\u0440\u0443 <mat-icon>settings</mat-icon>\n </mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n <div style=\"height: 10px;\"></div>\n <div [hidden]=\"searchOrEdit !== 'search'\">\n <croco-html-file-id-select\n [labelText]=\"'\u0412\u044B\u0431\u0440\u0430\u0442\u044C \u0444\u0430\u0439\u043B'\"\n [(fileId)]=\"tag.attributes['file-id']\"\n (onFileIdChanged)=\"onFileIdChanged($event)\">\n </croco-html-file-id-select>\n </div>\n <div [hidden]=\"searchOrEdit !== 'edit'\">\n <div>\n <mat-form-field class=\"w-100\">\n <input matInput placeholder=\"\u0418\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u043E\u0440 \u0444\u0430\u0439\u043B\u0430\" new-autocomplete=\"off\" autocomplete=\"off\"\n type=\"number\"\n [(ngModel)]=\"tag.attributes['file-id']\"\n (ngModelChange)=\"removeImageError()\">\n </mat-form-field>\n </div>\n </div>\n </div>\n}", styles: [".error-block{background-color:#f32323;color:#fff;text-align:center;border-radius:10px;padding:10px}\n"], dependencies: [{ kind: "directive", type: i1$4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$4.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i2.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i5.MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled", "hideSingleSelectionIndicator", "hideMultipleSelectionIndicator"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { kind: "component", type: i5.MatButtonToggle, selector: "mat-button-toggle", inputs: ["aria-label", "aria-labelledby", "id", "name", "value", "tabIndex", "disableRipple", "appearance", "checked", "disabled"], outputs: ["change"], exportAs: ["matButtonToggle"] }, { kind: "component", type: FileIdSelectComponent, selector: "croco-html-file-id-select", inputs: ["labelText", "fileId"], outputs: ["fileId", "onFileIdChanged"] }] }); }
1062
1182
  }
1183
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: ImageEditorComponent, decorators: [{
1184
+ type: Component,
1185
+ args: [{ selector: 'croco-html-image-editor', template: "<div>\n <div style=\"height: 10px;\">\n </div>\n\n @if (hasImageError) {\n <div class=\"error-block\">\n \u0418\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435 \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D\u043E \u043F\u043E \u0443\u043A\u0430\u0437\u0430\u043D\u043D\u043E\u043C\u0443 \u0438\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u043E\u0440\u0443, \u0432\u043E\u0437\u043C\u043E\u0436\u043D\u043E \u0444\u0430\u0439\u043B \u043D\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0438\u043B\u0438 \u043E\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043D\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435.\n </div>\n }\n\n @if (hasFileId() && !hasImageError) {\n <div>\n <img class=\"mx-auto d-block img-fluid\" [src]=\"getSrc()\" (error)=\"onErrorHandler()\"/>\n </div>\n }\n\n @if (!hasFileId()) {\n <div>\n <h5>[\u0418\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435 \u043D\u0435 \u0432\u044B\u0431\u0440\u0430\u043D\u043E]</h5>\n </div>\n }\n</div>\n\n@if (!tag.presentOrEdit) {\n <div>\n <div style=\"height: 10px;\"></div>\n <div style=\"overflow-x:auto;\">\n <mat-button-toggle-group [(ngModel)]=\"searchOrEdit\">\n <mat-button-toggle value=\"search\">\n \u0418\u0441\u043A\u0430\u0442\u044C \u0444\u0430\u0439\u043B <mat-icon>search</mat-icon>\n </mat-button-toggle>\n <mat-button-toggle value=\"edit\">\n \u0423\u043A\u0430\u0437\u0430\u0442\u044C \u043F\u043E \u0438\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u043E\u0440\u0443 <mat-icon>settings</mat-icon>\n </mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n <div style=\"height: 10px;\"></div>\n <div [hidden]=\"searchOrEdit !== 'search'\">\n <croco-html-file-id-select\n [labelText]=\"'\u0412\u044B\u0431\u0440\u0430\u0442\u044C \u0444\u0430\u0439\u043B'\"\n [(fileId)]=\"tag.attributes['file-id']\"\n (onFileIdChanged)=\"onFileIdChanged($event)\">\n </croco-html-file-id-select>\n </div>\n <div [hidden]=\"searchOrEdit !== 'edit'\">\n <div>\n <mat-form-field class=\"w-100\">\n <input matInput placeholder=\"\u0418\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u043E\u0440 \u0444\u0430\u0439\u043B\u0430\" new-autocomplete=\"off\" autocomplete=\"off\"\n type=\"number\"\n [(ngModel)]=\"tag.attributes['file-id']\"\n (ngModelChange)=\"removeImageError()\">\n </mat-form-field>\n </div>\n </div>\n </div>\n}", styles: [".error-block{background-color:#f32323;color:#fff;text-align:center;border-radius:10px;padding:10px}\n"] }]
1186
+ }], ctorParameters: () => [{ type: undefined, decorators: [{
1187
+ type: Inject,
1188
+ args: [CrocoHtmlOptionsToken]
1189
+ }] }], propDecorators: { tag: [{
1190
+ type: Input
1191
+ }], onTagUpdated: [{
1192
+ type: Output
1193
+ }] } });
1063
1194
 
1064
- class HtmlRawTagDataConsts {
1065
- static { this.TagName = "html-raw"; }
1195
+ class XmlTagHtmlViewComponent {
1196
+ constructor() {
1197
+ this.html = "";
1198
+ }
1199
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: XmlTagHtmlViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1200
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.4", type: XmlTagHtmlViewComponent, selector: "croco-html-xml-tag-html-view", inputs: { html: "html" }, ngImport: i0, template: "<div class=\"col\" [innerHTML]=\"html\">\n</div>", styles: [""] }); }
1066
1201
  }
1202
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: XmlTagHtmlViewComponent, decorators: [{
1203
+ type: Component,
1204
+ args: [{ selector: 'croco-html-xml-tag-html-view', template: "<div class=\"col\" [innerHTML]=\"html\">\n</div>" }]
1205
+ }], ctorParameters: () => [], propDecorators: { html: [{
1206
+ type: Input
1207
+ }] } });
1067
1208
 
1068
- class BodyTagsExtensions {
1069
- static getDescription(tagName) {
1070
- var descriptions = {
1071
- "text": "Текст",
1072
- "h1": "Заголовок 1 уровня",
1073
- "h2": "Заголовок 2 уровня",
1074
- "h3": "Заголовок 3 уровня",
1075
- "h4": "Заголовок 4 уровня",
1076
- "h5": "Заголовок 5 уровня",
1077
- "h6": "Заголовок 6 уровня",
1078
- [FileImageTagDataConsts.TagName]: "Изображение",
1079
- [ExternalVideoTagDataConsts.TagName]: "Внешнее видео YouTube",
1080
- [HtmlRawTagDataConsts.TagName]: "Html разметка"
1081
- };
1082
- return descriptions[tagName];
1083
- }
1084
- static toHtml(bodyTags) {
1085
- let htmls = bodyTags.map(x => {
1086
- if (TextMethods.textTags.includes(x.tagDescription.tag)) {
1087
- return `<${x.tagDescription.tag} h-align="${x.attributes['h-align']}">${x.innerHtml}</${x.tagDescription.tag}>`;
1088
- }
1089
- if (x.tagDescription.tag === ExternalVideoTagDataConsts.TagName) {
1090
- return `<${x.tagDescription.tag} type="${x.attributes['type']}" link="${x.attributes['link']}">${x.innerHtml}</${x.tagDescription.tag}>`;
1091
- }
1092
- if (x.tagDescription.tag === "html-raw") {
1093
- return `<${x.tagDescription.tag}>${x.innerHtml}</${x.tagDescription.tag}>`;
1094
- }
1095
- return BodyTagsExtensions.imageTagToHtml(x);
1096
- });
1097
- let result = "";
1098
- for (let index = 0; index < htmls.length; index++) {
1099
- const element = htmls[index];
1100
- result += element;
1101
- }
1102
- return result;
1209
+ class XmlTagTextViewComponent {
1210
+ constructor() { }
1211
+ ngOnInit() {
1103
1212
  }
1104
- static imageTagToHtml(imageTag) {
1105
- var attrStr = "";
1106
- var attrValue = imageTag.attributes[FileImageTagDataConsts.FileIdAttrName];
1107
- if (imageTag.attributes.hasOwnProperty(FileImageTagDataConsts.FileIdAttrName) && attrValue) {
1108
- attrStr = `${FileImageTagDataConsts.FileIdAttrName}="${attrValue}"`;
1109
- }
1110
- return `<${FileImageTagDataConsts.TagName} ${attrStr}></${FileImageTagDataConsts.TagName}>`;
1213
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: XmlTagTextViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1214
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.4", type: XmlTagTextViewComponent, selector: "croco-html-xml-tag-text-view", inputs: { item: "item" }, ngImport: i0, template: "@if (item.data.validationResult.isSucceeded && item.data.horizontalAlignment === 'left') {\n <div style=\"text-align: left;\">\n @if (item.data.html.length === 0 || !item.data.html) {\n <span>&nbsp;</span>\n }\n @if (item.data.html.length > 0) {\n <span [innerHtml]=\"item.data.html\"></span>\n }\n </div>\n}\n\n@if (item.data.validationResult.isSucceeded && item.data.horizontalAlignment === 'right') {\n <div style=\"text-align: right;\">\n @if (item.data.html.length === 0 || !item.data.html) {\n <span>&nbsp;</span>\n }\n @if (item.data.html.length > 0) {\n <span [innerHtml]=\"item.data.html\"></span>\n }\n </div>\n}\n\n@if (item.data.validationResult.isSucceeded && item.data.horizontalAlignment === 'center') {\n <div style=\"text-align: center;\">\n @if (item.data.html.length === 0 || !item.data.html) {\n <span>&nbsp;</span>\n }\n @if (item.data.html.length > 0) {\n <span [innerHtml]=\"item.data.html\"></span>\n }\n </div>\n}\n\n@if (!item.data.validationResult.isSucceeded) {\n <div class=\"red\" style=\"margin-top: 10px;\" >\n <h4>\u0414\u043E\u043F\u0443\u0449\u0435\u043D\u0430 \u043E\u0448\u0438\u0431\u043A\u0430 \u0432 \u0442\u0435\u0433\u0435 &lt;text&gt;</h4>\n <span>\n {{item.data.validationResult.message}}\n </span>\n </div>\n}", styles: [""] }); }
1215
+ }
1216
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: XmlTagTextViewComponent, decorators: [{
1217
+ type: Component,
1218
+ args: [{ selector: 'croco-html-xml-tag-text-view', template: "@if (item.data.validationResult.isSucceeded && item.data.horizontalAlignment === 'left') {\n <div style=\"text-align: left;\">\n @if (item.data.html.length === 0 || !item.data.html) {\n <span>&nbsp;</span>\n }\n @if (item.data.html.length > 0) {\n <span [innerHtml]=\"item.data.html\"></span>\n }\n </div>\n}\n\n@if (item.data.validationResult.isSucceeded && item.data.horizontalAlignment === 'right') {\n <div style=\"text-align: right;\">\n @if (item.data.html.length === 0 || !item.data.html) {\n <span>&nbsp;</span>\n }\n @if (item.data.html.length > 0) {\n <span [innerHtml]=\"item.data.html\"></span>\n }\n </div>\n}\n\n@if (item.data.validationResult.isSucceeded && item.data.horizontalAlignment === 'center') {\n <div style=\"text-align: center;\">\n @if (item.data.html.length === 0 || !item.data.html) {\n <span>&nbsp;</span>\n }\n @if (item.data.html.length > 0) {\n <span [innerHtml]=\"item.data.html\"></span>\n }\n </div>\n}\n\n@if (!item.data.validationResult.isSucceeded) {\n <div class=\"red\" style=\"margin-top: 10px;\" >\n <h4>\u0414\u043E\u043F\u0443\u0449\u0435\u043D\u0430 \u043E\u0448\u0438\u0431\u043A\u0430 \u0432 \u0442\u0435\u0433\u0435 &lt;text&gt;</h4>\n <span>\n {{item.data.validationResult.message}}\n </span>\n </div>\n}" }]
1219
+ }], ctorParameters: () => [], propDecorators: { item: [{
1220
+ type: Input
1221
+ }] } });
1222
+
1223
+ class XmlTagHeaderInnerTextViewComponent {
1224
+ constructor() { }
1225
+ ngOnInit() {
1111
1226
  }
1112
- static getBodyTags(html, options) {
1113
- let result = HtmlExtractionMethods.transformHtmlStringToBlocks(html, options);
1114
- return result.map(x => BodyTagsExtensions.toBodyTag(x));
1227
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: XmlTagHeaderInnerTextViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1228
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.4", type: XmlTagHeaderInnerTextViewComponent, selector: "croco-html-xml-tag-header-inner-text-view", inputs: { item: "item" }, ngImport: i0, template: "@if (item.type === 'h1') {\n <h1\n [innerHtml]=\"item.data.html\">\n </h1>\n}\n@if (item.type === 'h2') {\n <h2\n [innerHtml]=\"item.data.html\">\n </h2>\n}\n@if (item.type === 'h3') {\n <h3\n [innerHtml]=\"item.data.html\">\n </h3>\n}\n@if (item.type === 'h4') {\n <h4\n [innerHtml]=\"item.data.html\">\n </h4>\n}\n@if (item.type === 'h5') {\n <h5\n [innerHtml]=\"item.data.html\">\n </h5>\n}\n@if (item.type === 'h6') {\n <h6\n [innerHtml]=\"item.data.html\">\n </h6>\n}", styles: [""] }); }
1229
+ }
1230
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: XmlTagHeaderInnerTextViewComponent, decorators: [{
1231
+ type: Component,
1232
+ args: [{ selector: 'croco-html-xml-tag-header-inner-text-view', template: "@if (item.type === 'h1') {\n <h1\n [innerHtml]=\"item.data.html\">\n </h1>\n}\n@if (item.type === 'h2') {\n <h2\n [innerHtml]=\"item.data.html\">\n </h2>\n}\n@if (item.type === 'h3') {\n <h3\n [innerHtml]=\"item.data.html\">\n </h3>\n}\n@if (item.type === 'h4') {\n <h4\n [innerHtml]=\"item.data.html\">\n </h4>\n}\n@if (item.type === 'h5') {\n <h5\n [innerHtml]=\"item.data.html\">\n </h5>\n}\n@if (item.type === 'h6') {\n <h6\n [innerHtml]=\"item.data.html\">\n </h6>\n}" }]
1233
+ }], ctorParameters: () => [], propDecorators: { item: [{
1234
+ type: Input
1235
+ }] } });
1236
+
1237
+ class XmlTagHeaderTextViewComponent {
1238
+ constructor() { }
1239
+ ngOnInit() {
1115
1240
  }
1116
- static sanitizeInnerHtml(html) {
1117
- return html.trim().replace('\n\t', '');
1241
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: XmlTagHeaderTextViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1242
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.4", type: XmlTagHeaderTextViewComponent, selector: "croco-html-xml-tag-header-text-view", inputs: { item: "item" }, ngImport: i0, template: "@if (item.data.validationResult.isSucceeded && item.data.horizontalAlignment === 'left') {\n <div style=\"text-align: left;\">\n @if (item.data.html.length === 0 || !item.data.html) {\n <span>&nbsp;</span>\n }\n @if (item.data.html.length > 0) {\n <croco-html-xml-tag-header-inner-text-view [item]=\"item\">\n </croco-html-xml-tag-header-inner-text-view>\n }\n </div>\n}\n\n@if (item.data.validationResult.isSucceeded && item.data.horizontalAlignment === 'right') {\n <div style=\"text-align: right;\">\n @if (item.data.html.length === 0 || !item.data.html) {\n <span>&nbsp;</span>\n }\n @if (item.data.html.length > 0) {\n <croco-html-xml-tag-header-inner-text-view [item]=\"item\">\n </croco-html-xml-tag-header-inner-text-view>\n }\n </div>\n}\n\n@if (item.data.validationResult.isSucceeded && item.data.horizontalAlignment === 'center') {\n <div style=\"text-align: center;\">\n @if (item.data.html.length === 0 || !item.data.html) {\n <span>&nbsp;</span>\n }\n @if (item.data.html.length > 0) {\n <croco-html-xml-tag-header-inner-text-view [item]=\"item\">\n </croco-html-xml-tag-header-inner-text-view>\n }\n </div>\n}\n\n@if (!item.data.validationResult.isSucceeded) {\n <div class=\"red\" style=\"margin-top: 10px;\" >\n <h4>\u0414\u043E\u043F\u0443\u0449\u0435\u043D\u0430 \u043E\u0448\u0438\u0431\u043A\u0430 \u0432 \u0442\u0435\u0433\u0435 &lt;text&gt;</h4>\n <span>\n {{item.data.validationResult.message}}\n </span>\n </div>\n}", styles: [""], dependencies: [{ kind: "component", type: XmlTagHeaderInnerTextViewComponent, selector: "croco-html-xml-tag-header-inner-text-view", inputs: ["item"] }] }); }
1243
+ }
1244
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: XmlTagHeaderTextViewComponent, decorators: [{
1245
+ type: Component,
1246
+ args: [{ selector: 'croco-html-xml-tag-header-text-view', template: "@if (item.data.validationResult.isSucceeded && item.data.horizontalAlignment === 'left') {\n <div style=\"text-align: left;\">\n @if (item.data.html.length === 0 || !item.data.html) {\n <span>&nbsp;</span>\n }\n @if (item.data.html.length > 0) {\n <croco-html-xml-tag-header-inner-text-view [item]=\"item\">\n </croco-html-xml-tag-header-inner-text-view>\n }\n </div>\n}\n\n@if (item.data.validationResult.isSucceeded && item.data.horizontalAlignment === 'right') {\n <div style=\"text-align: right;\">\n @if (item.data.html.length === 0 || !item.data.html) {\n <span>&nbsp;</span>\n }\n @if (item.data.html.length > 0) {\n <croco-html-xml-tag-header-inner-text-view [item]=\"item\">\n </croco-html-xml-tag-header-inner-text-view>\n }\n </div>\n}\n\n@if (item.data.validationResult.isSucceeded && item.data.horizontalAlignment === 'center') {\n <div style=\"text-align: center;\">\n @if (item.data.html.length === 0 || !item.data.html) {\n <span>&nbsp;</span>\n }\n @if (item.data.html.length > 0) {\n <croco-html-xml-tag-header-inner-text-view [item]=\"item\">\n </croco-html-xml-tag-header-inner-text-view>\n }\n </div>\n}\n\n@if (!item.data.validationResult.isSucceeded) {\n <div class=\"red\" style=\"margin-top: 10px;\" >\n <h4>\u0414\u043E\u043F\u0443\u0449\u0435\u043D\u0430 \u043E\u0448\u0438\u0431\u043A\u0430 \u0432 \u0442\u0435\u0433\u0435 &lt;text&gt;</h4>\n <span>\n {{item.data.validationResult.message}}\n </span>\n </div>\n}" }]
1247
+ }], ctorParameters: () => [], propDecorators: { item: [{
1248
+ type: Input
1249
+ }] } });
1250
+
1251
+ class HtmlRawViewComponent {
1252
+ constructor(_sanitizer) {
1253
+ this._sanitizer = _sanitizer;
1254
+ this.rawHtml = "";
1255
+ this.isInitialized = false;
1118
1256
  }
1119
- static toBodyTag(data) {
1120
- if (TextMethods.textTags.includes(data.type)) {
1121
- let textTagData = data.data;
1122
- return {
1123
- presentOrEdit: true,
1124
- tagDescription: {
1125
- tag: textTagData.textTagName,
1126
- displayValue: BodyTagsExtensions.getDescription(data.type)
1127
- },
1128
- attributes: { "h-align": textTagData.horizontalAlignment },
1129
- innerHtml: BodyTagsExtensions.sanitizeInnerHtml(textTagData.html)
1130
- };
1131
- }
1132
- if (data.type === FileImageTagDataConsts.TagName) {
1133
- let fileData = data.data;
1134
- let attrs = {};
1135
- if (fileData.fileId) {
1136
- attrs[FileImageTagDataConsts.FileIdAttrName] = fileData.fileId;
1137
- }
1138
- return {
1139
- presentOrEdit: true,
1140
- tagDescription: {
1141
- tag: FileImageTagDataConsts.TagName,
1142
- displayValue: BodyTagsExtensions.getDescription(data.type)
1143
- },
1144
- attributes: attrs,
1145
- innerHtml: ""
1146
- };
1147
- }
1148
- if (data.type === ExternalVideoTagDataConsts.TagName) {
1149
- let fileData = data.data;
1150
- return {
1151
- presentOrEdit: true,
1152
- tagDescription: {
1153
- tag: ExternalVideoTagDataConsts.TagName,
1154
- displayValue: BodyTagsExtensions.getDescription(data.type)
1155
- },
1156
- attributes: fileData,
1157
- innerHtml: ""
1158
- };
1159
- }
1160
- if (data.type === HtmlRawTagDataConsts.TagName) {
1161
- return {
1162
- presentOrEdit: true,
1163
- tagDescription: {
1164
- tag: HtmlRawTagDataConsts.TagName,
1165
- displayValue: BodyTagsExtensions.getDescription(data.type)
1166
- },
1167
- attributes: {},
1168
- innerHtml: BodyTagsExtensions.sanitizeInnerHtml(data.data["innerHTML"])
1169
- };
1170
- }
1171
- return {
1172
- presentOrEdit: true,
1173
- tagDescription: {
1174
- tag: "unsupported-tag",
1175
- displayValue: "Неподдерживаемый тег"
1176
- },
1177
- attributes: {},
1178
- innerHtml: JSON.stringify(data)
1179
- };
1257
+ ngOnInit() {
1258
+ this.safeHtml = this._sanitizer.bypassSecurityTrustHtml(this.rawHtml);
1180
1259
  }
1260
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: HtmlRawViewComponent, deps: [{ token: i1$2.DomSanitizer }], target: i0.ɵɵFactoryTarget.Component }); }
1261
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.4", type: HtmlRawViewComponent, selector: "croco-html-raw-view", inputs: { rawHtml: "rawHtml" }, ngImport: i0, template: "<div [innerHTML]=\"safeHtml\">\n</div>", styles: [""] }); }
1181
1262
  }
1263
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: HtmlRawViewComponent, decorators: [{
1264
+ type: Component,
1265
+ args: [{ selector: 'croco-html-raw-view', template: "<div [innerHTML]=\"safeHtml\">\n</div>" }]
1266
+ }], ctorParameters: () => [{ type: i1$2.DomSanitizer }], propDecorators: { rawHtml: [{
1267
+ type: Input
1268
+ }] } });
1182
1269
 
1183
- class XmlExtensions {
1184
- static formatXml(xml, tab = '\t') {
1185
- var formatted = '', indent = '';
1186
- tab = tab || '\t';
1187
- xml.split(/>\s*</).forEach(function (node) {
1188
- if (node.match(/^\/\w/))
1189
- indent = indent.substring(tab.length); // decrease indent by one 'tab'
1190
- formatted += indent + '<' + node + '>\r\n';
1191
- if (node.match(/^<?\w[^>]*[^\/]$/))
1192
- indent += tab; // increase indent
1193
- });
1194
- return formatted.substring(1, formatted.length - 3);
1270
+ class FileImageTagViewComponent {
1271
+ constructor() {
1272
+ this.imageSrc = "";
1195
1273
  }
1196
- static tagsToLower(xml) {
1197
- xml = this.replaceTagToLower(xml, "Body");
1198
- xml = this.replaceTagToLower(xml, "Image");
1199
- xml = this.replaceTagToLower(xml, "Text");
1200
- return xml;
1274
+ ngOnInit() {
1275
+ let data = this.item.data;
1276
+ this.imageSrc = data.src;
1201
1277
  }
1202
- static replaceTagToLower(xml, tag) {
1203
- return xml
1204
- .replace(new RegExp(`<${tag}`, 'g'), `<${tag.toLowerCase()}`)
1205
- .replace(new RegExp(`</${tag}>`, 'g'), `</${tag.toLowerCase()}>`);
1278
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: FileImageTagViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1279
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.4", type: FileImageTagViewComponent, selector: "croco-html-file-image-tag-view", inputs: { item: "item" }, ngImport: i0, template: "\n<img class=\"mx-auto d-block img-fluid\" [src]=\"imageSrc\" alt=\"\u0418\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435 \u043D\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043D\u043E\"/>", styles: [""] }); }
1280
+ }
1281
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: FileImageTagViewComponent, decorators: [{
1282
+ type: Component,
1283
+ args: [{ selector: 'croco-html-file-image-tag-view', template: "\n<img class=\"mx-auto d-block img-fluid\" [src]=\"imageSrc\" alt=\"\u0418\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435 \u043D\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043D\u043E\"/>" }]
1284
+ }], propDecorators: { item: [{
1285
+ type: Input
1286
+ }] } });
1287
+
1288
+ class XmlTagViewComponent {
1289
+ constructor() {
1290
+ this.data = [];
1291
+ this.textTags = TextTags.allTextTags;
1206
1292
  }
1293
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: XmlTagViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1294
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.4", type: XmlTagViewComponent, selector: "croco-html-xml-tag-view", inputs: { data: "data" }, ngImport: i0, template: "<div>\n @for (item of data; track $index) {\n <div class=\"row\">\n @if (item.type === 'html-raw') {\n <div>\n <croco-html-raw-view [rawHtml]=\"item.data.innerHTML\">\n </croco-html-raw-view>\n </div>\n }\n\n @if (textTags.includes(item.type)) {\n <div>\n <croco-html-xml-tag-header-text-view [item]=\"item\"></croco-html-xml-tag-header-text-view>\n </div>\n }\n\n @if (item.type === 'file-image') {\n <div>\n <croco-html-file-image-tag-view [item]=\"item\"></croco-html-file-image-tag-view>\n </div>\n }\n\n @if (item.type === 'table') {\n <div>\n @if (item.data) {\n <croco-html-xml-tag-html-view [html]=\"item.data\">\n </croco-html-xml-tag-html-view>\n }\n </div>\n }\n\n @if (item.type === 'rich-text') {\n <div>\n <croco-html-xml-tag-text-view></croco-html-xml-tag-text-view>\n </div>\n }\n\n @if (item.type === 'external-video') {\n <div>\n <croco-html-xml-tag-external-video [data]=\"item\"></croco-html-xml-tag-external-video>\n </div>\n }\n\n @if (item.type === 'unsupported-tag') {\n <div class=\"red\" style=\"margin-top: 10px;\">\n <h4>\u0414\u0430\u043D\u043D\u044B\u0439 \u0442\u0435\u0433 \u043D\u0435 \u043F\u043E\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044F</h4>\n <span>\n {{item.data.tagString}}\n </span>\n </div>\n }\n </div>\n }\n</div>", styles: [".red{background-color:#c94444;color:#fff}\n"], dependencies: [{ kind: "component", type: XmlTagHtmlViewComponent, selector: "croco-html-xml-tag-html-view", inputs: ["html"] }, { kind: "component", type: XmlTagTextViewComponent, selector: "croco-html-xml-tag-text-view", inputs: ["item"] }, { kind: "component", type: XmlTagHeaderTextViewComponent, selector: "croco-html-xml-tag-header-text-view", inputs: ["item"] }, { kind: "component", type: XmlTagExternalVideoComponent, selector: "croco-html-xml-tag-external-video", inputs: ["data", "tagData"] }, { kind: "component", type: HtmlRawViewComponent, selector: "croco-html-raw-view", inputs: ["rawHtml"] }, { kind: "component", type: FileImageTagViewComponent, selector: "croco-html-file-image-tag-view", inputs: ["item"] }], encapsulation: i0.ViewEncapsulation.None }); }
1207
1295
  }
1296
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: XmlTagViewComponent, decorators: [{
1297
+ type: Component,
1298
+ args: [{ selector: 'croco-html-xml-tag-view', encapsulation: ViewEncapsulation.None, template: "<div>\n @for (item of data; track $index) {\n <div class=\"row\">\n @if (item.type === 'html-raw') {\n <div>\n <croco-html-raw-view [rawHtml]=\"item.data.innerHTML\">\n </croco-html-raw-view>\n </div>\n }\n\n @if (textTags.includes(item.type)) {\n <div>\n <croco-html-xml-tag-header-text-view [item]=\"item\"></croco-html-xml-tag-header-text-view>\n </div>\n }\n\n @if (item.type === 'file-image') {\n <div>\n <croco-html-file-image-tag-view [item]=\"item\"></croco-html-file-image-tag-view>\n </div>\n }\n\n @if (item.type === 'table') {\n <div>\n @if (item.data) {\n <croco-html-xml-tag-html-view [html]=\"item.data\">\n </croco-html-xml-tag-html-view>\n }\n </div>\n }\n\n @if (item.type === 'rich-text') {\n <div>\n <croco-html-xml-tag-text-view></croco-html-xml-tag-text-view>\n </div>\n }\n\n @if (item.type === 'external-video') {\n <div>\n <croco-html-xml-tag-external-video [data]=\"item\"></croco-html-xml-tag-external-video>\n </div>\n }\n\n @if (item.type === 'unsupported-tag') {\n <div class=\"red\" style=\"margin-top: 10px;\">\n <h4>\u0414\u0430\u043D\u043D\u044B\u0439 \u0442\u0435\u0433 \u043D\u0435 \u043F\u043E\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044F</h4>\n <span>\n {{item.data.tagString}}\n </span>\n </div>\n }\n </div>\n }\n</div>", styles: [".red{background-color:#c94444;color:#fff}\n"] }]
1299
+ }], propDecorators: { data: [{
1300
+ type: Input
1301
+ }] } });
1208
1302
 
1209
1303
  class DefaultTags {
1210
1304
  static { this.textTags = [
@@ -1218,7 +1312,7 @@ class DefaultTags {
1218
1312
  ]; }
1219
1313
  static { this.tags = [
1220
1314
  { tag: FileImageTagDataConsts.TagName, displayValue: 'Изображение' },
1221
- { tag: ExternalVideoTagDataConsts.TagName, displayValue: 'Внешнее видео Youtube' },
1315
+ { tag: ExternalVideoTagDataConsts.TagName, displayValue: 'Внешнее видео' },
1222
1316
  ...DefaultTags.textTags
1223
1317
  ]; }
1224
1318
  static { this.htmlRawTag = {
@@ -1243,11 +1337,11 @@ class TextEditorComponent {
1243
1337
  return `<${this.tag.tagDescription.tag}>${this.tag.innerHtml}<${this.tag.tagDescription.tag}/>`;
1244
1338
  }
1245
1339
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: TextEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1246
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.4", type: TextEditorComponent, selector: "croco-html-text-editor", inputs: { tag: "tag" }, outputs: { onTagUpdated: "onTagUpdated" }, ngImport: i0, template: "<div *ngIf=\"tag.presentOrEdit\">\r\n <div style=\"height: 10px;\">\r\n </div>\r\n\r\n <div style=\"text-align: left;\" *ngIf=\"tag.attributes['h-align'] === 'left'\" [innerHtml]=\"getInnerHtml()\">\r\n </div>\r\n <div style=\"text-align: right;\" *ngIf=\"tag.attributes['h-align'] === 'right'\" [innerHtml]=\"getInnerHtml()\">\r\n </div>\r\n <div style=\"text-align: center;\" *ngIf=\"tag.attributes['h-align'] === 'center'\" [innerHtml]=\"getInnerHtml()\">\r\n </div>\r\n</div>\r\n\r\n<div *ngIf=\"!tag.presentOrEdit\">\r\n <div style=\"overflow-x: auto;\">\r\n <mat-button-toggle-group [(ngModel)]=\"tag.attributes['h-align']\">\r\n <mat-button-toggle value=\"center\">\r\n \u041F\u043E \u0446\u0435\u043D\u0442\u0440\u0443 <mat-icon>format_align_center</mat-icon>\r\n </mat-button-toggle>\r\n <mat-button-toggle value=\"left\">\r\n \u0421\u043B\u0435\u0432\u0430 <mat-icon>format_align_left</mat-icon>\r\n </mat-button-toggle>\r\n <mat-button-toggle value=\"right\">\r\n \u0421\u043F\u0440\u0430\u0432\u0430 <mat-icon> format_align_right</mat-icon>\r\n </mat-button-toggle>\r\n </mat-button-toggle-group>\r\n </div>\r\n\r\n <div style=\"height: 10px;\">\r\n </div>\r\n <div>\r\n <mat-form-field class=\"w-100\">\r\n <textarea matInput cdkTextareaAutosize #autosize=\"cdkTextareaAutosize\"\r\n cdkAutosizeMinRows=\"1\"\r\n placeholder=\"\u0412\u043D\u0443\u0442\u0440\u0435\u043D\u043D\u044F\u044F \u0440\u0430\u0437\u043C\u0435\u0442\u043A\u0430 \u0442\u0435\u043A\u0441\u0442\u043E\u0432\u043E\u0433\u043E \u0442\u0435\u0433\u0430\"\r\n [(ngModel)]=\"tag.innerHtml\"></textarea>\r\n </mat-form-field>\r\n </div>\r\n</div>", styles: [""], dependencies: [{ kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "directive", type: i5.CdkTextareaAutosize, selector: "textarea[cdkTextareaAutosize]", inputs: ["cdkAutosizeMinRows", "cdkAutosizeMaxRows", "cdkTextareaAutosize", "placeholder"], exportAs: ["cdkTextareaAutosize"] }, { kind: "component", type: i5$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i6.MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled", "hideSingleSelectionIndicator", "hideMultipleSelectionIndicator"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { kind: "component", type: i6.MatButtonToggle, selector: "mat-button-toggle", inputs: ["aria-label", "aria-labelledby", "id", "name", "value", "tabIndex", "disableRipple", "appearance", "checked", "disabled"], outputs: ["change"], exportAs: ["matButtonToggle"] }] }); }
1340
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.4", type: TextEditorComponent, selector: "croco-html-text-editor", inputs: { tag: "tag" }, outputs: { onTagUpdated: "onTagUpdated" }, ngImport: i0, template: "@if (tag.presentOrEdit) {\n <div>\n <div style=\"height: 10px;\">\n </div>\n @if (tag.attributes['h-align'] === 'left') {\n <div style=\"text-align: left;\" [innerHtml]=\"getInnerHtml()\">\n </div>\n }\n @if (tag.attributes['h-align'] === 'right') {\n <div style=\"text-align: right;\" [innerHtml]=\"getInnerHtml()\">\n </div>\n }\n @if (tag.attributes['h-align'] === 'center') {\n <div style=\"text-align: center;\" [innerHtml]=\"getInnerHtml()\">\n </div>\n }\n </div>\n}\n\n@if (!tag.presentOrEdit) {\n <div>\n <div style=\"overflow-x: auto;\">\n <mat-button-toggle-group [(ngModel)]=\"tag.attributes['h-align']\">\n <mat-button-toggle value=\"center\">\n \u041F\u043E \u0446\u0435\u043D\u0442\u0440\u0443 <mat-icon>format_align_center</mat-icon>\n </mat-button-toggle>\n <mat-button-toggle value=\"left\">\n \u0421\u043B\u0435\u0432\u0430 <mat-icon>format_align_left</mat-icon>\n </mat-button-toggle>\n <mat-button-toggle value=\"right\">\n \u0421\u043F\u0440\u0430\u0432\u0430 <mat-icon> format_align_right</mat-icon>\n </mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n <div style=\"height: 10px;\">\n </div>\n <div>\n <mat-form-field class=\"w-100\">\n <textarea matInput cdkTextareaAutosize #autosize=\"cdkTextareaAutosize\"\n cdkAutosizeMinRows=\"1\"\n placeholder=\"\u0412\u043D\u0443\u0442\u0440\u0435\u043D\u043D\u044F\u044F \u0440\u0430\u0437\u043C\u0435\u0442\u043A\u0430 \u0442\u0435\u043A\u0441\u0442\u043E\u0432\u043E\u0433\u043E \u0442\u0435\u0433\u0430\"\n [(ngModel)]=\"tag.innerHtml\"></textarea>\n </mat-form-field>\n </div>\n </div>\n}", styles: [""], dependencies: [{ kind: "directive", type: i1$4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i2.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "directive", type: i4.CdkTextareaAutosize, selector: "textarea[cdkTextareaAutosize]", inputs: ["cdkAutosizeMinRows", "cdkAutosizeMaxRows", "cdkTextareaAutosize", "placeholder"], exportAs: ["cdkTextareaAutosize"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i5.MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled", "hideSingleSelectionIndicator", "hideMultipleSelectionIndicator"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { kind: "component", type: i5.MatButtonToggle, selector: "mat-button-toggle", inputs: ["aria-label", "aria-labelledby", "id", "name", "value", "tabIndex", "disableRipple", "appearance", "checked", "disabled"], outputs: ["change"], exportAs: ["matButtonToggle"] }] }); }
1247
1341
  }
1248
1342
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: TextEditorComponent, decorators: [{
1249
1343
  type: Component,
1250
- args: [{ selector: 'croco-html-text-editor', template: "<div *ngIf=\"tag.presentOrEdit\">\r\n <div style=\"height: 10px;\">\r\n </div>\r\n\r\n <div style=\"text-align: left;\" *ngIf=\"tag.attributes['h-align'] === 'left'\" [innerHtml]=\"getInnerHtml()\">\r\n </div>\r\n <div style=\"text-align: right;\" *ngIf=\"tag.attributes['h-align'] === 'right'\" [innerHtml]=\"getInnerHtml()\">\r\n </div>\r\n <div style=\"text-align: center;\" *ngIf=\"tag.attributes['h-align'] === 'center'\" [innerHtml]=\"getInnerHtml()\">\r\n </div>\r\n</div>\r\n\r\n<div *ngIf=\"!tag.presentOrEdit\">\r\n <div style=\"overflow-x: auto;\">\r\n <mat-button-toggle-group [(ngModel)]=\"tag.attributes['h-align']\">\r\n <mat-button-toggle value=\"center\">\r\n \u041F\u043E \u0446\u0435\u043D\u0442\u0440\u0443 <mat-icon>format_align_center</mat-icon>\r\n </mat-button-toggle>\r\n <mat-button-toggle value=\"left\">\r\n \u0421\u043B\u0435\u0432\u0430 <mat-icon>format_align_left</mat-icon>\r\n </mat-button-toggle>\r\n <mat-button-toggle value=\"right\">\r\n \u0421\u043F\u0440\u0430\u0432\u0430 <mat-icon> format_align_right</mat-icon>\r\n </mat-button-toggle>\r\n </mat-button-toggle-group>\r\n </div>\r\n\r\n <div style=\"height: 10px;\">\r\n </div>\r\n <div>\r\n <mat-form-field class=\"w-100\">\r\n <textarea matInput cdkTextareaAutosize #autosize=\"cdkTextareaAutosize\"\r\n cdkAutosizeMinRows=\"1\"\r\n placeholder=\"\u0412\u043D\u0443\u0442\u0440\u0435\u043D\u043D\u044F\u044F \u0440\u0430\u0437\u043C\u0435\u0442\u043A\u0430 \u0442\u0435\u043A\u0441\u0442\u043E\u0432\u043E\u0433\u043E \u0442\u0435\u0433\u0430\"\r\n [(ngModel)]=\"tag.innerHtml\"></textarea>\r\n </mat-form-field>\r\n </div>\r\n</div>" }]
1344
+ args: [{ selector: 'croco-html-text-editor', template: "@if (tag.presentOrEdit) {\n <div>\n <div style=\"height: 10px;\">\n </div>\n @if (tag.attributes['h-align'] === 'left') {\n <div style=\"text-align: left;\" [innerHtml]=\"getInnerHtml()\">\n </div>\n }\n @if (tag.attributes['h-align'] === 'right') {\n <div style=\"text-align: right;\" [innerHtml]=\"getInnerHtml()\">\n </div>\n }\n @if (tag.attributes['h-align'] === 'center') {\n <div style=\"text-align: center;\" [innerHtml]=\"getInnerHtml()\">\n </div>\n }\n </div>\n}\n\n@if (!tag.presentOrEdit) {\n <div>\n <div style=\"overflow-x: auto;\">\n <mat-button-toggle-group [(ngModel)]=\"tag.attributes['h-align']\">\n <mat-button-toggle value=\"center\">\n \u041F\u043E \u0446\u0435\u043D\u0442\u0440\u0443 <mat-icon>format_align_center</mat-icon>\n </mat-button-toggle>\n <mat-button-toggle value=\"left\">\n \u0421\u043B\u0435\u0432\u0430 <mat-icon>format_align_left</mat-icon>\n </mat-button-toggle>\n <mat-button-toggle value=\"right\">\n \u0421\u043F\u0440\u0430\u0432\u0430 <mat-icon> format_align_right</mat-icon>\n </mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n <div style=\"height: 10px;\">\n </div>\n <div>\n <mat-form-field class=\"w-100\">\n <textarea matInput cdkTextareaAutosize #autosize=\"cdkTextareaAutosize\"\n cdkAutosizeMinRows=\"1\"\n placeholder=\"\u0412\u043D\u0443\u0442\u0440\u0435\u043D\u043D\u044F\u044F \u0440\u0430\u0437\u043C\u0435\u0442\u043A\u0430 \u0442\u0435\u043A\u0441\u0442\u043E\u0432\u043E\u0433\u043E \u0442\u0435\u0433\u0430\"\n [(ngModel)]=\"tag.innerHtml\"></textarea>\n </mat-form-field>\n </div>\n </div>\n}" }]
1251
1345
  }], ctorParameters: () => [], propDecorators: { tag: [{
1252
1346
  type: Input
1253
1347
  }], onTagUpdated: [{
@@ -1256,7 +1350,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImpor
1256
1350
 
1257
1351
  class MainEditorBlockComponent {
1258
1352
  constructor() {
1259
- this.textTags = TextMethods.textTags;
1353
+ this.textTags = TextTags.allTextTags;
1260
1354
  this.onTagSaved = new EventEmitter();
1261
1355
  this.onTagRemoved = new EventEmitter();
1262
1356
  }
@@ -1272,12 +1366,12 @@ class MainEditorBlockComponent {
1272
1366
  ngOnInit() {
1273
1367
  }
1274
1368
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: MainEditorBlockComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1275
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.4", type: MainEditorBlockComponent, selector: "croco-html-main-editor-block", inputs: { tag: "tag" }, outputs: { onTagSaved: "onTagSaved", onTagRemoved: "onTagRemoved" }, ngImport: i0, template: "<div>\r\n <div>\r\n <div *ngIf=\"textTags.includes(tag.tagDescription.tag)\">\r\n <croco-html-text-editor (onTagUpdated)=\"tagUpdatedHandler($event)\" [tag]=\"tag\">\r\n </croco-html-text-editor>\r\n </div>\r\n\r\n <div *ngIf=\"tag.tagDescription.tag === 'file-image'\"> \r\n <croco-html-image-editor (onTagUpdated)=\"tagUpdatedHandler($event)\" [tag]=\"tag\">\r\n </croco-html-image-editor>\r\n </div>\r\n\r\n <div *ngIf=\"tag.tagDescription.tag === 'external-video'\">\r\n <croco-html-external-video-block (onTagUpdated)=\"tagUpdatedHandler($event)\" [tag]=\"tag\">\r\n </croco-html-external-video-block>\r\n </div>\r\n\r\n <div *ngIf=\"tag.tagDescription.tag === 'html-raw'\">\r\n <croco-html-html-raw-editor (onTagUpdated)=\"tagUpdatedHandler($event)\" [tag]=\"tag\">\r\n </croco-html-html-raw-editor>\r\n </div>\r\n\r\n </div>\r\n\r\n <div class=\"d-flex justify-content-between\">\r\n <div class=\"d-flex justify-content-end align-self-center\">\r\n <div>\r\n <button *ngIf=\"tag.presentOrEdit\" (click)=\"tag.presentOrEdit = false\" mat-icon-button>\r\n <mat-icon>edit</mat-icon>\r\n </button>\r\n <button *ngIf=\"!tag.presentOrEdit\" (click)=\"save()\" mat-icon-button>\r\n <mat-icon>save</mat-icon>\r\n </button>\r\n <button (click)=\"deleteItem()\" mat-icon-button color=\"warn\">\r\n <mat-icon>delete</mat-icon>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n </div>\r\n</div>", styles: [""], dependencies: [{ kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i5$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: TextEditorComponent, selector: "croco-html-text-editor", inputs: ["tag"], outputs: ["onTagUpdated"] }, { kind: "component", type: ExternalVideoBlockComponent, selector: "croco-html-external-video-block", inputs: ["tag"], outputs: ["onTagUpdated"] }, { kind: "component", type: ImageEditorComponent, selector: "croco-html-image-editor", inputs: ["tag"], outputs: ["onTagUpdated"] }, { kind: "component", type: HtmlRawEditorComponent, selector: "croco-html-html-raw-editor", inputs: ["tag"], outputs: ["onTagUpdated"] }] }); }
1369
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.4", type: MainEditorBlockComponent, selector: "croco-html-main-editor-block", inputs: { tag: "tag" }, outputs: { onTagSaved: "onTagSaved", onTagRemoved: "onTagRemoved" }, ngImport: i0, template: "<div>\n <div>\n @if (textTags.includes(tag.tagDescription.tag)) {\n <div>\n <croco-html-text-editor (onTagUpdated)=\"tagUpdatedHandler($event)\" [tag]=\"tag\">\n </croco-html-text-editor>\n </div>\n }\n\n @if (tag.tagDescription.tag === 'file-image') {\n <div>\n <croco-html-image-editor (onTagUpdated)=\"tagUpdatedHandler($event)\" [tag]=\"tag\">\n </croco-html-image-editor>\n </div>\n }\n\n @if (tag.tagDescription.tag === 'external-video') {\n <div>\n <croco-html-external-video-block (onTagUpdated)=\"tagUpdatedHandler($event)\" [tag]=\"tag\">\n </croco-html-external-video-block>\n </div>\n }\n\n @if (tag.tagDescription.tag === 'html-raw') {\n <div>\n <croco-html-html-raw-editor (onTagUpdated)=\"tagUpdatedHandler($event)\" [tag]=\"tag\">\n </croco-html-html-raw-editor>\n </div>\n }\n\n </div>\n\n <div class=\"d-flex justify-content-between\">\n <div class=\"d-flex justify-content-end align-self-center\">\n <div>\n @if (tag.presentOrEdit) {\n <button (click)=\"tag.presentOrEdit = false\" mat-icon-button>\n <mat-icon>edit</mat-icon>\n </button>\n }\n @if (!tag.presentOrEdit) {\n <button (click)=\"save()\" mat-icon-button>\n <mat-icon>save</mat-icon>\n </button>\n }\n <button (click)=\"deleteItem()\" mat-icon-button color=\"warn\">\n <mat-icon>delete</mat-icon>\n </button>\n </div>\n </div>\n\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "component", type: i1$1.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: TextEditorComponent, selector: "croco-html-text-editor", inputs: ["tag"], outputs: ["onTagUpdated"] }, { kind: "component", type: ExternalVideoBlockComponent, selector: "croco-html-external-video-block", inputs: ["tag"], outputs: ["onTagUpdated"] }, { kind: "component", type: ImageEditorComponent, selector: "croco-html-image-editor", inputs: ["tag"], outputs: ["onTagUpdated"] }, { kind: "component", type: HtmlRawEditorComponent, selector: "croco-html-html-raw-editor", inputs: ["tag"], outputs: ["onTagUpdated"] }] }); }
1276
1370
  }
1277
1371
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: MainEditorBlockComponent, decorators: [{
1278
1372
  type: Component,
1279
- args: [{ selector: 'croco-html-main-editor-block', template: "<div>\r\n <div>\r\n <div *ngIf=\"textTags.includes(tag.tagDescription.tag)\">\r\n <croco-html-text-editor (onTagUpdated)=\"tagUpdatedHandler($event)\" [tag]=\"tag\">\r\n </croco-html-text-editor>\r\n </div>\r\n\r\n <div *ngIf=\"tag.tagDescription.tag === 'file-image'\"> \r\n <croco-html-image-editor (onTagUpdated)=\"tagUpdatedHandler($event)\" [tag]=\"tag\">\r\n </croco-html-image-editor>\r\n </div>\r\n\r\n <div *ngIf=\"tag.tagDescription.tag === 'external-video'\">\r\n <croco-html-external-video-block (onTagUpdated)=\"tagUpdatedHandler($event)\" [tag]=\"tag\">\r\n </croco-html-external-video-block>\r\n </div>\r\n\r\n <div *ngIf=\"tag.tagDescription.tag === 'html-raw'\">\r\n <croco-html-html-raw-editor (onTagUpdated)=\"tagUpdatedHandler($event)\" [tag]=\"tag\">\r\n </croco-html-html-raw-editor>\r\n </div>\r\n\r\n </div>\r\n\r\n <div class=\"d-flex justify-content-between\">\r\n <div class=\"d-flex justify-content-end align-self-center\">\r\n <div>\r\n <button *ngIf=\"tag.presentOrEdit\" (click)=\"tag.presentOrEdit = false\" mat-icon-button>\r\n <mat-icon>edit</mat-icon>\r\n </button>\r\n <button *ngIf=\"!tag.presentOrEdit\" (click)=\"save()\" mat-icon-button>\r\n <mat-icon>save</mat-icon>\r\n </button>\r\n <button (click)=\"deleteItem()\" mat-icon-button color=\"warn\">\r\n <mat-icon>delete</mat-icon>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n </div>\r\n</div>" }]
1280
- }], ctorParameters: () => [], propDecorators: { tag: [{
1373
+ args: [{ selector: 'croco-html-main-editor-block', template: "<div>\n <div>\n @if (textTags.includes(tag.tagDescription.tag)) {\n <div>\n <croco-html-text-editor (onTagUpdated)=\"tagUpdatedHandler($event)\" [tag]=\"tag\">\n </croco-html-text-editor>\n </div>\n }\n\n @if (tag.tagDescription.tag === 'file-image') {\n <div>\n <croco-html-image-editor (onTagUpdated)=\"tagUpdatedHandler($event)\" [tag]=\"tag\">\n </croco-html-image-editor>\n </div>\n }\n\n @if (tag.tagDescription.tag === 'external-video') {\n <div>\n <croco-html-external-video-block (onTagUpdated)=\"tagUpdatedHandler($event)\" [tag]=\"tag\">\n </croco-html-external-video-block>\n </div>\n }\n\n @if (tag.tagDescription.tag === 'html-raw') {\n <div>\n <croco-html-html-raw-editor (onTagUpdated)=\"tagUpdatedHandler($event)\" [tag]=\"tag\">\n </croco-html-html-raw-editor>\n </div>\n }\n\n </div>\n\n <div class=\"d-flex justify-content-between\">\n <div class=\"d-flex justify-content-end align-self-center\">\n <div>\n @if (tag.presentOrEdit) {\n <button (click)=\"tag.presentOrEdit = false\" mat-icon-button>\n <mat-icon>edit</mat-icon>\n </button>\n }\n @if (!tag.presentOrEdit) {\n <button (click)=\"save()\" mat-icon-button>\n <mat-icon>save</mat-icon>\n </button>\n }\n <button (click)=\"deleteItem()\" mat-icon-button color=\"warn\">\n <mat-icon>delete</mat-icon>\n </button>\n </div>\n </div>\n\n </div>\n</div>\n" }]
1374
+ }], propDecorators: { tag: [{
1281
1375
  type: Input
1282
1376
  }], onTagSaved: [{
1283
1377
  type: Output
@@ -1285,6 +1379,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImpor
1285
1379
  type: Output
1286
1380
  }] } });
1287
1381
 
1382
+ const defaultLinkYouTube = "https://youtu.be/jzBneaWSswY";
1383
+ const defaultLinkVk = "https://vk.com/video_ext.php?oid=-22822305&id=456241864&hd=2";
1288
1384
  class VisualEditorComponent {
1289
1385
  isHtmlSet() {
1290
1386
  return this.html.startsWith("<body>");
@@ -1310,6 +1406,8 @@ class VisualEditorComponent {
1310
1406
  this.alignmentOptions = AlignmentsData;
1311
1407
  this.showMarkUp = true;
1312
1408
  this.tags = [];
1409
+ this.videoPlayers = ExternalVideoPlayers;
1410
+ this.ExternalVideoTagDataConsts = ExternalVideoTagDataConsts;
1313
1411
  this.useHtmlRaw = false;
1314
1412
  this.html = "";
1315
1413
  this.onHtmlChanged = new EventEmitter();
@@ -1328,13 +1426,13 @@ class VisualEditorComponent {
1328
1426
  .find(x => x.tag === this.selectedValue);
1329
1427
  let attrs = {};
1330
1428
  let innerHtml = "";
1331
- if (TextMethods.textTags.includes(tagDescription.tag)) {
1429
+ if (TextTags.allTextTags.includes(tagDescription.tag)) {
1332
1430
  attrs["h-align"] = EAlignments.Left;
1333
1431
  innerHtml = "Введите ваш текст";
1334
1432
  }
1335
1433
  else if (tagDescription.tag == ExternalVideoTagDataConsts.TagName) {
1336
- attrs[ExternalVideoTagDataConsts.VideoTypeAttrName] = ExternalVideoSupportedTypes.Youtube;
1337
- attrs[ExternalVideoTagDataConsts.LinkAttrName] = null;
1434
+ attrs[ExternalVideoTagDataConsts.VideoTypeAttrName] = this.selectedVideoPlayer;
1435
+ attrs[ExternalVideoTagDataConsts.LinkAttrName] = this.selectedVideoPlayer === ExternalVideoSupportedTypes.VkVideo ? defaultLinkVk : defaultLinkYouTube;
1338
1436
  }
1339
1437
  else {
1340
1438
  attrs[FileImageTagDataConsts.FileIdAttrName] = null;
@@ -1424,13 +1522,14 @@ class VisualEditorComponent {
1424
1522
  this.recalculateBodyTags();
1425
1523
  this.tags = DefaultTags.getTags(this.useHtmlRaw);
1426
1524
  this.selectedValue = this.tags[0].tag;
1525
+ this.selectedVideoPlayer = this.videoPlayers[0].type;
1427
1526
  }
1428
1527
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: VisualEditorComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: CrocoHtmlOptionsToken }], target: i0.ɵɵFactoryTarget.Component }); }
1429
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.4", type: VisualEditorComponent, selector: "croco-visual-editor", inputs: { showMarkUp: "showMarkUp", useHtmlRaw: "useHtmlRaw", html: "html" }, outputs: { html: "html", onHtmlChanged: "onHtmlChanged", rendered: "rendered" }, viewQueries: [{ propertyName: "textArea", first: true, predicate: ["textArea"], descendants: true }], ngImport: i0, template: "<div *ngIf=\"isLoading\">\r\n <div>\r\n <mat-spinner style=\"margin:0 auto;\"></mat-spinner>\r\n <div style=\"text-align: center;\">{{loadingText}}</div>\r\n </div>\r\n <div style=\"height: 10px;\"></div>\r\n</div>\r\n<div [hidden]=\"isLoading\">\r\n <mat-card style=\"margin: 2px;\" class=\"mat-card\">\r\n <mat-card-content>\r\n <div class=\"row d-flex align-items-center\">\r\n <div class=\"col-12\">\r\n <button (click)=\"addText()\" class=\"w-100\" mat-stroked-button *ngIf=\"!isActiveAddText\">\r\n \u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0442\u0435\u043A\u0441\u0442\r\n </button>\r\n <ng-container *ngIf=\"isActiveAddText\">\r\n <mat-form-field class=\"w-100\" >\r\n <textarea\r\n #autosize=\"cdkTextareaAutosize\"\r\n matInput\r\n cdkTextareaAutosize\r\n cdkAutosizeMinRows=\"1\"\r\n cdkAutosizeMaxRows=\"5\"\r\n placeholder=\"\u0422\u0435\u043A\u0441\u0442\"\r\n #textArea\r\n [(ngModel)]=\"text\"\r\n (ngModelChange)=\"modelChanged()\"\r\n ></textarea>\r\n </mat-form-field>\r\n <mat-form-field appearance=\"outline\" class=\"w-100\">\r\n <mat-label>\u0422\u0435\u0433 \u0434\u043B\u044F \u0442\u0435\u043A\u0441\u0442\u0430</mat-label>\r\n <mat-select [(ngModel)]=\"textTag\" (ngModelChange)=\"modelChanged()\">\r\n <mat-option *ngFor=\"let option of textTagOptions\" value=\"{{ option.tag }}\">\r\n {{ option.displayValue }}\r\n </mat-option>\r\n </mat-select>\r\n </mat-form-field>\r\n\r\n <mat-form-field appearance=\"outline\" class=\"w-100\">\r\n <mat-label>\u0413\u043E\u0440\u0438\u0437\u043E\u043D\u0442\u0430\u043B\u044C\u043D\u043E\u0435 \u0432\u044B\u0440\u0430\u0432\u043D\u0438\u0432\u0430\u043D\u0438\u0435</mat-label>\r\n <mat-select [(ngModel)]=\"alignment\" (ngModelChange)=\"modelChanged()\">\r\n <mat-option *ngFor=\"let option of alignmentOptions\" value=\"{{ option.value }}\">\r\n {{ option.text }}\r\n </mat-option>\r\n </mat-select>\r\n </mat-form-field>\r\n </ng-container>\r\n <div class=\"d-flex flex-nowrap justify-content-end w-100\">\r\n <button (click)=\"addText()\" class=\"w-20\" style=\"margin-right: 10px\" mat-flat-button color=\"primary\" *ngIf=\"isActiveAddText\">\r\n \u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C\r\n </button>\r\n <button (click)=\"closeText()\" class=\"w-20\" mat-flat-button color=\"warn\" *ngIf=\"isActiveAddText\">\r\n \u041E\u0442\u043C\u0435\u043D\u0438\u0442\u044C\r\n </button>\r\n </div>\r\n\r\n </div>\r\n </div>\r\n </mat-card-content>\r\n </mat-card>\r\n\r\n <div style=\"height: 10px;\">\r\n </div>\r\n</div>\r\n<div [hidden]=\"isLoading\">\r\n <mat-card style=\"margin: 2px;\" class=\"mat-card\">\r\n <mat-card-content>\r\n <div class=\"row d-flex align-items-center\">\r\n <div class=\"col-12\">\r\n <mat-form-field class=\"w-100\" appearance=\"outline\">\r\n <mat-label>\u0412\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u0442\u0435\u0433</mat-label>\r\n <mat-select [(ngModel)]=\"selectedValue\">\r\n <mat-option *ngFor=\"let tag of tags\" [value]=\"tag.tag\">\r\n {{tag.displayValue}}\r\n </mat-option>\r\n </mat-select>\r\n </mat-form-field>\r\n </div>\r\n <div class=\"col-12\">\r\n <button (click)=\"addTag()\" class=\"w-100\" mat-stroked-button>\r\n \u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0442\u0435\u0433\r\n </button>\r\n </div>\r\n </div>\r\n </mat-card-content>\r\n </mat-card>\r\n\r\n <div style=\"height: 10px;\">\r\n </div>\r\n</div>\r\n<div [hidden]=\"isLoading\">\r\n <mat-card style=\"margin: 2px;\" class=\"mat-card\">\r\n <mat-card-content>\r\n <div class=\"row d-flex align-items-center\">\r\n <div class=\"col-12\">\r\n <croco-html-add-files-btn (filesTagsReady)=\"filesTagsReadyHandler($event)\"\r\n (postFilesStarted)=\"postFilesStartedEventHandler($event)\" class=\"w-100\">\r\n </croco-html-add-files-btn>\r\n </div>\r\n </div>\r\n </mat-card-content>\r\n </mat-card>\r\n\r\n <div style=\"height: 10px;\">\r\n </div>\r\n</div>\r\n<div [hidden]=\"isLoading\">\r\n <div cdkDropList (cdkDropListDropped)=\"drop($event)\">\r\n <div *ngFor=\"let tag of bodyTags; let i = index\" cdkDrag>\r\n <mat-card style=\"margin: 2px;\" class=\"mat-card\">\r\n <mat-card-content>\r\n <div class=\"d-flex justify-content-between\">\r\n <div class=\"example-handle\" cdkDragHandle>\r\n <svg width=\"24px\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path\r\n d=\"M10 9h4V6h3l-5-5-5 5h3v3zm-1 1H6V7l-5 5 5 5v-3h3v-4zm14 2l-5-5v3h-3v4h3v3l5-5zm-9 3h-4v3H7l5 5 5-5h-3v-3z\">\r\n </path>\r\n <path d=\"M0 0h24v24H0z\" fill=\"none\"></path>\r\n </svg>\r\n </div>\r\n <div>\r\n <div class=\"badge\">\r\n {{tag.tagDescription.displayValue}}\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div style=\"height: 15px;\"></div>\r\n\r\n <croco-html-main-editor-block [tag]=\"tag\" (onTagSaved)=\"onTagSavedHandler($event)\"\r\n (onTagRemoved)=\"onTagRemovedHandler(i)\">\r\n </croco-html-main-editor-block>\r\n </mat-card-content>\r\n </mat-card>\r\n\r\n <div style=\"height: 10px;\">\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n\r\n\r\n\r\n\r\n", styles: [".example-list{width:500px;max-width:100%;border:solid 1px #ccc;min-height:60px;display:block;background:#fff;border-radius:4px;overflow:hidden}.example-box{padding:20px 10px;border-bottom:solid 1px #ccc;color:#000000de;display:flex;flex-direction:row;align-items:center;justify-content:space-between;box-sizing:border-box;cursor:move;background:#fff;font-size:14px}.cdk-drag-preview{box-sizing:border-box;border-radius:4px;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}.cdk-drag-placeholder{opacity:0}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.example-box:last-child{border:none}.example-list.cdk-drop-list-dragging .example-box:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}.badge{background-color:#50a450;color:#fff;min-width:55px;height:25px;border-radius:15px;display:flex;align-items:center;justify-content:center;font-weight:400}\n"], dependencies: [{ kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatLabel, selector: "mat-label" }, { kind: "component", type: i4$1.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: i5$2.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i5$2.MatCardContent, selector: "mat-card-content" }, { kind: "component", type: i6$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i7.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i2.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "directive", type: i4.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "directive", type: i5.CdkTextareaAutosize, selector: "textarea[cdkTextareaAutosize]", inputs: ["cdkAutosizeMinRows", "cdkAutosizeMaxRows", "cdkTextareaAutosize", "placeholder"], exportAs: ["cdkTextareaAutosize"] }, { kind: "directive", type: i11.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i11.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i11.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "component", type: MainEditorBlockComponent, selector: "croco-html-main-editor-block", inputs: ["tag"], outputs: ["onTagSaved", "onTagRemoved"] }, { kind: "component", type: AddFilesBtnComponent, selector: "croco-html-add-files-btn", outputs: ["postFilesStarted", "filesTagsReady"] }] }); }
1528
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.4", type: VisualEditorComponent, selector: "croco-visual-editor", inputs: { showMarkUp: "showMarkUp", useHtmlRaw: "useHtmlRaw", html: "html" }, outputs: { html: "html", onHtmlChanged: "onHtmlChanged", rendered: "rendered" }, viewQueries: [{ propertyName: "textArea", first: true, predicate: ["textArea"], descendants: true }], ngImport: i0, template: "@if (isLoading) {\n <div>\n <div>\n <mat-spinner style=\"margin:0 auto;\"></mat-spinner>\n <div style=\"text-align: center;\">{{loadingText}}</div>\n </div>\n <div style=\"height: 10px;\"></div>\n </div>\n}\n<div [hidden]=\"isLoading\">\n <mat-card style=\"margin: 2px;\" class=\"mat-card\">\n <mat-card-content>\n <div class=\"row d-flex align-items-center\">\n <div class=\"col-12\">\n @if (!isActiveAddText) {\n <button (click)=\"addText()\" class=\"w-100\" mat-stroked-button>\n \u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0442\u0435\u043A\u0441\u0442\n </button>\n }\n @if (isActiveAddText) {\n <mat-form-field class=\"w-100\" >\n <textarea\n #autosize=\"cdkTextareaAutosize\"\n matInput\n cdkTextareaAutosize\n cdkAutosizeMinRows=\"1\"\n cdkAutosizeMaxRows=\"5\"\n placeholder=\"\u0422\u0435\u043A\u0441\u0442\"\n #textArea\n [(ngModel)]=\"text\"\n (ngModelChange)=\"modelChanged()\"\n ></textarea>\n </mat-form-field>\n <mat-form-field appearance=\"outline\" class=\"w-100\">\n <mat-label>\u0422\u0435\u0433 \u0434\u043B\u044F \u0442\u0435\u043A\u0441\u0442\u0430</mat-label>\n <mat-select [(ngModel)]=\"textTag\" (ngModelChange)=\"modelChanged()\">\n @for (option of textTagOptions; track option) {\n <mat-option value=\"{{ option.tag }}\">\n {{ option.displayValue }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\" class=\"w-100\">\n <mat-label>\u0413\u043E\u0440\u0438\u0437\u043E\u043D\u0442\u0430\u043B\u044C\u043D\u043E\u0435 \u0432\u044B\u0440\u0430\u0432\u043D\u0438\u0432\u0430\u043D\u0438\u0435</mat-label>\n <mat-select [(ngModel)]=\"alignment\" (ngModelChange)=\"modelChanged()\">\n @for (option of alignmentOptions; track option) {\n <mat-option value=\"{{ option.value }}\">\n {{ option.text }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n }\n <div class=\"d-flex flex-nowrap justify-content-end w-100\">\n @if (isActiveAddText) {\n <button (click)=\"addText()\" class=\"w-20\" style=\"margin-right: 10px\" mat-flat-button color=\"primary\">\n \u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C\n </button>\n }\n @if (isActiveAddText) {\n <button (click)=\"closeText()\" class=\"w-20\" mat-flat-button color=\"warn\" >\n \u041E\u0442\u043C\u0435\u043D\u0438\u0442\u044C\n </button>\n }\n </div>\n\n </div>\n </div>\n </mat-card-content>\n </mat-card>\n\n <div style=\"height: 10px;\">\n </div>\n</div>\n<div [hidden]=\"isLoading\">\n <mat-card style=\"margin: 2px;\" class=\"mat-card\">\n <mat-card-content>\n <div class=\"row d-flex align-items-center\">\n <div class=\"col-12\">\n <mat-form-field class=\"w-100\" appearance=\"outline\">\n <mat-label>\u0412\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u0442\u0435\u0433</mat-label>\n <mat-select [(ngModel)]=\"selectedValue\">\n @for (tag of tags; track tag) {\n <mat-option [value]=\"tag.tag\">\n {{tag.displayValue}}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n </div>\n @if (selectedValue === ExternalVideoTagDataConsts.TagName) {\n <div class=\"col-12\">\n <mat-form-field class=\"w-100\" appearance=\"outline\">\n <mat-label>\u0412\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u0432\u0438\u0434\u0435\u043E\u043F\u043B\u0435\u0435\u0440</mat-label>\n <mat-select [(ngModel)]=\"selectedVideoPlayer\">\n @for (videoPlayer of videoPlayers; track videoPlayer.type) {\n <mat-option [value]=\"videoPlayer.type\">\n {{videoPlayer.displayValue}}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n </div>\n }\n <div class=\"col-12\">\n <button (click)=\"addTag()\" class=\"w-100\" mat-stroked-button>\n \u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0442\u0435\u0433\n </button>\n </div>\n </div>\n </mat-card-content>\n </mat-card>\n\n <div style=\"height: 10px;\">\n </div>\n</div>\n<div [hidden]=\"isLoading\">\n <mat-card style=\"margin: 2px;\" class=\"mat-card\">\n <mat-card-content>\n <div class=\"row d-flex align-items-center\">\n <div class=\"col-12\">\n <croco-html-add-files-btn (filesTagsReady)=\"filesTagsReadyHandler($event)\"\n (postFilesStarted)=\"postFilesStartedEventHandler($event)\" class=\"w-100\">\n </croco-html-add-files-btn>\n </div>\n </div>\n </mat-card-content>\n </mat-card>\n\n <div style=\"height: 10px;\">\n </div>\n</div>\n<div [hidden]=\"isLoading\">\n <div cdkDropList (cdkDropListDropped)=\"drop($event)\">\n @for (tag of bodyTags; track tag; let i = $index) {\n <div cdkDrag>\n <mat-card style=\"margin: 2px;\" class=\"mat-card\">\n <mat-card-content>\n <div class=\"d-flex justify-content-between\">\n <div class=\"example-handle\" cdkDragHandle>\n <svg width=\"24px\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n d=\"M10 9h4V6h3l-5-5-5 5h3v3zm-1 1H6V7l-5 5 5 5v-3h3v-4zm14 2l-5-5v3h-3v4h3v3l5-5zm-9 3h-4v3H7l5 5 5-5h-3v-3z\">\n </path>\n <path d=\"M0 0h24v24H0z\" fill=\"none\"></path>\n </svg>\n </div>\n <div>\n <div class=\"badge\">\n {{tag.tagDescription.displayValue}}\n </div>\n </div>\n </div>\n <div style=\"height: 15px;\"></div>\n <croco-html-main-editor-block [tag]=\"tag\" (onTagSaved)=\"onTagSavedHandler($event)\"\n (onTagRemoved)=\"onTagRemovedHandler(i)\">\n </croco-html-main-editor-block>\n </mat-card-content>\n </mat-card>\n <div style=\"height: 10px;\">\n </div>\n </div>\n }\n </div>\n</div>\n\n\n\n\n\n", styles: [".example-list{width:500px;max-width:100%;border:solid 1px #ccc;min-height:60px;display:block;background:#fff;border-radius:4px;overflow:hidden}.example-box{padding:20px 10px;border-bottom:solid 1px #ccc;color:#000000de;display:flex;flex-direction:row;align-items:center;justify-content:space-between;box-sizing:border-box;cursor:move;background:#fff;font-size:14px}.cdk-drag-preview{box-sizing:border-box;border-radius:4px;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}.cdk-drag-placeholder{opacity:0}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.example-box:last-child{border:none}.example-list.cdk-drop-list-dragging .example-box:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}.badge{background-color:#50a450;color:#fff;min-width:55px;height:25px;border-radius:15px;display:flex;align-items:center;justify-content:center;font-weight:400}\n"], dependencies: [{ kind: "directive", type: i1$4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i2.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2.MatLabel, selector: "mat-label" }, { kind: "component", type: i3$2.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: i4$2.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i4$2.MatCardContent, selector: "mat-card-content" }, { kind: "component", type: i5$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i6.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i1$1.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "directive", type: i3.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "directive", type: i4.CdkTextareaAutosize, selector: "textarea[cdkTextareaAutosize]", inputs: ["cdkAutosizeMinRows", "cdkAutosizeMaxRows", "cdkTextareaAutosize", "placeholder"], exportAs: ["cdkTextareaAutosize"] }, { kind: "directive", type: i10.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i10.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i10.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "component", type: MainEditorBlockComponent, selector: "croco-html-main-editor-block", inputs: ["tag"], outputs: ["onTagSaved", "onTagRemoved"] }, { kind: "component", type: AddFilesBtnComponent, selector: "croco-html-add-files-btn", outputs: ["postFilesStarted", "filesTagsReady"] }] }); }
1430
1529
  }
1431
1530
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: VisualEditorComponent, decorators: [{
1432
1531
  type: Component,
1433
- args: [{ selector: 'croco-visual-editor', template: "<div *ngIf=\"isLoading\">\r\n <div>\r\n <mat-spinner style=\"margin:0 auto;\"></mat-spinner>\r\n <div style=\"text-align: center;\">{{loadingText}}</div>\r\n </div>\r\n <div style=\"height: 10px;\"></div>\r\n</div>\r\n<div [hidden]=\"isLoading\">\r\n <mat-card style=\"margin: 2px;\" class=\"mat-card\">\r\n <mat-card-content>\r\n <div class=\"row d-flex align-items-center\">\r\n <div class=\"col-12\">\r\n <button (click)=\"addText()\" class=\"w-100\" mat-stroked-button *ngIf=\"!isActiveAddText\">\r\n \u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0442\u0435\u043A\u0441\u0442\r\n </button>\r\n <ng-container *ngIf=\"isActiveAddText\">\r\n <mat-form-field class=\"w-100\" >\r\n <textarea\r\n #autosize=\"cdkTextareaAutosize\"\r\n matInput\r\n cdkTextareaAutosize\r\n cdkAutosizeMinRows=\"1\"\r\n cdkAutosizeMaxRows=\"5\"\r\n placeholder=\"\u0422\u0435\u043A\u0441\u0442\"\r\n #textArea\r\n [(ngModel)]=\"text\"\r\n (ngModelChange)=\"modelChanged()\"\r\n ></textarea>\r\n </mat-form-field>\r\n <mat-form-field appearance=\"outline\" class=\"w-100\">\r\n <mat-label>\u0422\u0435\u0433 \u0434\u043B\u044F \u0442\u0435\u043A\u0441\u0442\u0430</mat-label>\r\n <mat-select [(ngModel)]=\"textTag\" (ngModelChange)=\"modelChanged()\">\r\n <mat-option *ngFor=\"let option of textTagOptions\" value=\"{{ option.tag }}\">\r\n {{ option.displayValue }}\r\n </mat-option>\r\n </mat-select>\r\n </mat-form-field>\r\n\r\n <mat-form-field appearance=\"outline\" class=\"w-100\">\r\n <mat-label>\u0413\u043E\u0440\u0438\u0437\u043E\u043D\u0442\u0430\u043B\u044C\u043D\u043E\u0435 \u0432\u044B\u0440\u0430\u0432\u043D\u0438\u0432\u0430\u043D\u0438\u0435</mat-label>\r\n <mat-select [(ngModel)]=\"alignment\" (ngModelChange)=\"modelChanged()\">\r\n <mat-option *ngFor=\"let option of alignmentOptions\" value=\"{{ option.value }}\">\r\n {{ option.text }}\r\n </mat-option>\r\n </mat-select>\r\n </mat-form-field>\r\n </ng-container>\r\n <div class=\"d-flex flex-nowrap justify-content-end w-100\">\r\n <button (click)=\"addText()\" class=\"w-20\" style=\"margin-right: 10px\" mat-flat-button color=\"primary\" *ngIf=\"isActiveAddText\">\r\n \u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C\r\n </button>\r\n <button (click)=\"closeText()\" class=\"w-20\" mat-flat-button color=\"warn\" *ngIf=\"isActiveAddText\">\r\n \u041E\u0442\u043C\u0435\u043D\u0438\u0442\u044C\r\n </button>\r\n </div>\r\n\r\n </div>\r\n </div>\r\n </mat-card-content>\r\n </mat-card>\r\n\r\n <div style=\"height: 10px;\">\r\n </div>\r\n</div>\r\n<div [hidden]=\"isLoading\">\r\n <mat-card style=\"margin: 2px;\" class=\"mat-card\">\r\n <mat-card-content>\r\n <div class=\"row d-flex align-items-center\">\r\n <div class=\"col-12\">\r\n <mat-form-field class=\"w-100\" appearance=\"outline\">\r\n <mat-label>\u0412\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u0442\u0435\u0433</mat-label>\r\n <mat-select [(ngModel)]=\"selectedValue\">\r\n <mat-option *ngFor=\"let tag of tags\" [value]=\"tag.tag\">\r\n {{tag.displayValue}}\r\n </mat-option>\r\n </mat-select>\r\n </mat-form-field>\r\n </div>\r\n <div class=\"col-12\">\r\n <button (click)=\"addTag()\" class=\"w-100\" mat-stroked-button>\r\n \u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0442\u0435\u0433\r\n </button>\r\n </div>\r\n </div>\r\n </mat-card-content>\r\n </mat-card>\r\n\r\n <div style=\"height: 10px;\">\r\n </div>\r\n</div>\r\n<div [hidden]=\"isLoading\">\r\n <mat-card style=\"margin: 2px;\" class=\"mat-card\">\r\n <mat-card-content>\r\n <div class=\"row d-flex align-items-center\">\r\n <div class=\"col-12\">\r\n <croco-html-add-files-btn (filesTagsReady)=\"filesTagsReadyHandler($event)\"\r\n (postFilesStarted)=\"postFilesStartedEventHandler($event)\" class=\"w-100\">\r\n </croco-html-add-files-btn>\r\n </div>\r\n </div>\r\n </mat-card-content>\r\n </mat-card>\r\n\r\n <div style=\"height: 10px;\">\r\n </div>\r\n</div>\r\n<div [hidden]=\"isLoading\">\r\n <div cdkDropList (cdkDropListDropped)=\"drop($event)\">\r\n <div *ngFor=\"let tag of bodyTags; let i = index\" cdkDrag>\r\n <mat-card style=\"margin: 2px;\" class=\"mat-card\">\r\n <mat-card-content>\r\n <div class=\"d-flex justify-content-between\">\r\n <div class=\"example-handle\" cdkDragHandle>\r\n <svg width=\"24px\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path\r\n d=\"M10 9h4V6h3l-5-5-5 5h3v3zm-1 1H6V7l-5 5 5 5v-3h3v-4zm14 2l-5-5v3h-3v4h3v3l5-5zm-9 3h-4v3H7l5 5 5-5h-3v-3z\">\r\n </path>\r\n <path d=\"M0 0h24v24H0z\" fill=\"none\"></path>\r\n </svg>\r\n </div>\r\n <div>\r\n <div class=\"badge\">\r\n {{tag.tagDescription.displayValue}}\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div style=\"height: 15px;\"></div>\r\n\r\n <croco-html-main-editor-block [tag]=\"tag\" (onTagSaved)=\"onTagSavedHandler($event)\"\r\n (onTagRemoved)=\"onTagRemovedHandler(i)\">\r\n </croco-html-main-editor-block>\r\n </mat-card-content>\r\n </mat-card>\r\n\r\n <div style=\"height: 10px;\">\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n\r\n\r\n\r\n\r\n", styles: [".example-list{width:500px;max-width:100%;border:solid 1px #ccc;min-height:60px;display:block;background:#fff;border-radius:4px;overflow:hidden}.example-box{padding:20px 10px;border-bottom:solid 1px #ccc;color:#000000de;display:flex;flex-direction:row;align-items:center;justify-content:space-between;box-sizing:border-box;cursor:move;background:#fff;font-size:14px}.cdk-drag-preview{box-sizing:border-box;border-radius:4px;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}.cdk-drag-placeholder{opacity:0}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.example-box:last-child{border:none}.example-list.cdk-drop-list-dragging .example-box:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}.badge{background-color:#50a450;color:#fff;min-width:55px;height:25px;border-radius:15px;display:flex;align-items:center;justify-content:center;font-weight:400}\n"] }]
1532
+ args: [{ selector: 'croco-visual-editor', template: "@if (isLoading) {\n <div>\n <div>\n <mat-spinner style=\"margin:0 auto;\"></mat-spinner>\n <div style=\"text-align: center;\">{{loadingText}}</div>\n </div>\n <div style=\"height: 10px;\"></div>\n </div>\n}\n<div [hidden]=\"isLoading\">\n <mat-card style=\"margin: 2px;\" class=\"mat-card\">\n <mat-card-content>\n <div class=\"row d-flex align-items-center\">\n <div class=\"col-12\">\n @if (!isActiveAddText) {\n <button (click)=\"addText()\" class=\"w-100\" mat-stroked-button>\n \u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0442\u0435\u043A\u0441\u0442\n </button>\n }\n @if (isActiveAddText) {\n <mat-form-field class=\"w-100\" >\n <textarea\n #autosize=\"cdkTextareaAutosize\"\n matInput\n cdkTextareaAutosize\n cdkAutosizeMinRows=\"1\"\n cdkAutosizeMaxRows=\"5\"\n placeholder=\"\u0422\u0435\u043A\u0441\u0442\"\n #textArea\n [(ngModel)]=\"text\"\n (ngModelChange)=\"modelChanged()\"\n ></textarea>\n </mat-form-field>\n <mat-form-field appearance=\"outline\" class=\"w-100\">\n <mat-label>\u0422\u0435\u0433 \u0434\u043B\u044F \u0442\u0435\u043A\u0441\u0442\u0430</mat-label>\n <mat-select [(ngModel)]=\"textTag\" (ngModelChange)=\"modelChanged()\">\n @for (option of textTagOptions; track option) {\n <mat-option value=\"{{ option.tag }}\">\n {{ option.displayValue }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\" class=\"w-100\">\n <mat-label>\u0413\u043E\u0440\u0438\u0437\u043E\u043D\u0442\u0430\u043B\u044C\u043D\u043E\u0435 \u0432\u044B\u0440\u0430\u0432\u043D\u0438\u0432\u0430\u043D\u0438\u0435</mat-label>\n <mat-select [(ngModel)]=\"alignment\" (ngModelChange)=\"modelChanged()\">\n @for (option of alignmentOptions; track option) {\n <mat-option value=\"{{ option.value }}\">\n {{ option.text }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n }\n <div class=\"d-flex flex-nowrap justify-content-end w-100\">\n @if (isActiveAddText) {\n <button (click)=\"addText()\" class=\"w-20\" style=\"margin-right: 10px\" mat-flat-button color=\"primary\">\n \u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C\n </button>\n }\n @if (isActiveAddText) {\n <button (click)=\"closeText()\" class=\"w-20\" mat-flat-button color=\"warn\" >\n \u041E\u0442\u043C\u0435\u043D\u0438\u0442\u044C\n </button>\n }\n </div>\n\n </div>\n </div>\n </mat-card-content>\n </mat-card>\n\n <div style=\"height: 10px;\">\n </div>\n</div>\n<div [hidden]=\"isLoading\">\n <mat-card style=\"margin: 2px;\" class=\"mat-card\">\n <mat-card-content>\n <div class=\"row d-flex align-items-center\">\n <div class=\"col-12\">\n <mat-form-field class=\"w-100\" appearance=\"outline\">\n <mat-label>\u0412\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u0442\u0435\u0433</mat-label>\n <mat-select [(ngModel)]=\"selectedValue\">\n @for (tag of tags; track tag) {\n <mat-option [value]=\"tag.tag\">\n {{tag.displayValue}}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n </div>\n @if (selectedValue === ExternalVideoTagDataConsts.TagName) {\n <div class=\"col-12\">\n <mat-form-field class=\"w-100\" appearance=\"outline\">\n <mat-label>\u0412\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u0432\u0438\u0434\u0435\u043E\u043F\u043B\u0435\u0435\u0440</mat-label>\n <mat-select [(ngModel)]=\"selectedVideoPlayer\">\n @for (videoPlayer of videoPlayers; track videoPlayer.type) {\n <mat-option [value]=\"videoPlayer.type\">\n {{videoPlayer.displayValue}}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n </div>\n }\n <div class=\"col-12\">\n <button (click)=\"addTag()\" class=\"w-100\" mat-stroked-button>\n \u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0442\u0435\u0433\n </button>\n </div>\n </div>\n </mat-card-content>\n </mat-card>\n\n <div style=\"height: 10px;\">\n </div>\n</div>\n<div [hidden]=\"isLoading\">\n <mat-card style=\"margin: 2px;\" class=\"mat-card\">\n <mat-card-content>\n <div class=\"row d-flex align-items-center\">\n <div class=\"col-12\">\n <croco-html-add-files-btn (filesTagsReady)=\"filesTagsReadyHandler($event)\"\n (postFilesStarted)=\"postFilesStartedEventHandler($event)\" class=\"w-100\">\n </croco-html-add-files-btn>\n </div>\n </div>\n </mat-card-content>\n </mat-card>\n\n <div style=\"height: 10px;\">\n </div>\n</div>\n<div [hidden]=\"isLoading\">\n <div cdkDropList (cdkDropListDropped)=\"drop($event)\">\n @for (tag of bodyTags; track tag; let i = $index) {\n <div cdkDrag>\n <mat-card style=\"margin: 2px;\" class=\"mat-card\">\n <mat-card-content>\n <div class=\"d-flex justify-content-between\">\n <div class=\"example-handle\" cdkDragHandle>\n <svg width=\"24px\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n d=\"M10 9h4V6h3l-5-5-5 5h3v3zm-1 1H6V7l-5 5 5 5v-3h3v-4zm14 2l-5-5v3h-3v4h3v3l5-5zm-9 3h-4v3H7l5 5 5-5h-3v-3z\">\n </path>\n <path d=\"M0 0h24v24H0z\" fill=\"none\"></path>\n </svg>\n </div>\n <div>\n <div class=\"badge\">\n {{tag.tagDescription.displayValue}}\n </div>\n </div>\n </div>\n <div style=\"height: 15px;\"></div>\n <croco-html-main-editor-block [tag]=\"tag\" (onTagSaved)=\"onTagSavedHandler($event)\"\n (onTagRemoved)=\"onTagRemovedHandler(i)\">\n </croco-html-main-editor-block>\n </mat-card-content>\n </mat-card>\n <div style=\"height: 10px;\">\n </div>\n </div>\n }\n </div>\n</div>\n\n\n\n\n\n", styles: [".example-list{width:500px;max-width:100%;border:solid 1px #ccc;min-height:60px;display:block;background:#fff;border-radius:4px;overflow:hidden}.example-box{padding:20px 10px;border-bottom:solid 1px #ccc;color:#000000de;display:flex;flex-direction:row;align-items:center;justify-content:space-between;box-sizing:border-box;cursor:move;background:#fff;font-size:14px}.cdk-drag-preview{box-sizing:border-box;border-radius:4px;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}.cdk-drag-placeholder{opacity:0}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.example-box:last-child{border:none}.example-list.cdk-drop-list-dragging .example-box:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}.badge{background-color:#50a450;color:#fff;min-width:55px;height:25px;border-radius:15px;display:flex;align-items:center;justify-content:center;font-weight:400}\n"] }]
1434
1533
  }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: undefined, decorators: [{
1435
1534
  type: Inject,
1436
1535
  args: [CrocoHtmlOptionsToken]
@@ -1511,13 +1610,13 @@ class MainEditorComponent {
1511
1610
  ngOnInit() {
1512
1611
  this.visualEditor.recalculateBodyTags();
1513
1612
  }
1514
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: MainEditorComponent, deps: [{ token: i1$3.ClipboardService }, { token: i2$3.MatSnackBar }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
1515
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.4", type: MainEditorComponent, selector: "croco-html-main-editor", inputs: { showMarkUp: "showMarkUp", useHtmlRaw: "useHtmlRaw", html: "html" }, outputs: { html: "html", onHtmlChanged: "onHtmlChanged" }, viewQueries: [{ propertyName: "visualEditor", first: true, predicate: ["visualEditor"], descendants: true, static: true }], ngImport: i0, template: "<mat-tab-group>\r\n <mat-tab label=\"\u0412\u0438\u0437\u0443\u0430\u043B\u044C\u043D\u044B\u0439 \u0440\u0435\u0434\u0430\u043A\u0442\u043E\u0440\">\r\n\r\n <div style=\"height: 20px;\"></div>\r\n\r\n <croco-visual-editor #visualEditor\r\n [useHtmlRaw]=\"useHtmlRaw\"\r\n [html]=\"html\"\r\n (onHtmlChanged)=\"onHtmlChangedHandler($event)\"\r\n (rendered)=\"visualEditorRenderedHandler()\">\r\n </croco-visual-editor>\r\n\r\n <div style=\"height: 20px;\"></div>\r\n\r\n </mat-tab>\r\n\r\n <mat-tab label=\"\u0420\u0430\u0437\u043C\u0435\u0442\u043A\u0430\">\r\n <div style=\"height: 10px;\"></div>\r\n <div *ngIf=\"visualEditorRendered\">\r\n <mat-form-field class=\"w-100\">\r\n <textarea matInput cdkTextareaAutosize #autosize=\"cdkTextareaAutosize\"\r\n cdkAutosizeMinRows=\"1\"\r\n placeholder=\"\u0418\u0441\u0445\u043E\u0434\u043D\u044B\u0439 \u043A\u043E\u0434\" [(ngModel)]=\"html\"\r\n (ngModelChange)=\"textAreaModelChangedHandler()\"></textarea>\r\n </mat-form-field>\r\n </div>\r\n\r\n <button (click)=\"copyMarkUp()\"\r\n mat-raised-button color=\"primary\">\r\n \u041A\u043E\u043F\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u0440\u0430\u0437\u043C\u0435\u0442\u043A\u0443\r\n </button>\r\n </mat-tab>\r\n <mat-tab label=\"\u0420\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\">\r\n <mat-card style=\"padding: 2px;\" class=\"mat-card\">\r\n <mat-card-content>\r\n <croco-html-xml-tag-view [data]=\"html | topreview\">\r\n </croco-html-xml-tag-view>\r\n </mat-card-content>\r\n </mat-card>\r\n </mat-tab>\r\n</mat-tab-group>\r\n", styles: [".example-list{width:500px;max-width:100%;border:solid 1px #ccc;min-height:60px;display:block;background:#fff;border-radius:4px;overflow:hidden}.example-box{padding:20px 10px;border-bottom:solid 1px #ccc;color:#000000de;display:flex;flex-direction:row;align-items:center;justify-content:space-between;box-sizing:border-box;cursor:move;background:#fff;font-size:14px}.cdk-drag-preview{box-sizing:border-box;border-radius:4px;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}.cdk-drag-placeholder{opacity:0}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.example-box:last-child{border:none}.example-list.cdk-drop-list-dragging .example-box:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}\n"], dependencies: [{ kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "component", type: i6$2.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass"], exportAs: ["matTab"] }, { kind: "component", type: i6$2.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "component", type: i5$2.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i5$2.MatCardContent, selector: "mat-card-content" }, { kind: "component", type: i2.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "directive", type: i4.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "directive", type: i5.CdkTextareaAutosize, selector: "textarea[cdkTextareaAutosize]", inputs: ["cdkAutosizeMinRows", "cdkAutosizeMaxRows", "cdkTextareaAutosize", "placeholder"], exportAs: ["cdkTextareaAutosize"] }, { kind: "component", type: XmlTagViewComponent, selector: "croco-html-xml-tag-view", inputs: ["data"] }, { kind: "component", type: VisualEditorComponent, selector: "croco-visual-editor", inputs: ["showMarkUp", "useHtmlRaw", "html"], outputs: ["html", "onHtmlChanged", "rendered"] }, { kind: "pipe", type: ToPreviewPipe, name: "topreview" }] }); }
1613
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: MainEditorComponent, deps: [{ token: i1$5.ClipboardService }, { token: i2$1.MatSnackBar }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
1614
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.4", type: MainEditorComponent, selector: "croco-html-main-editor", inputs: { showMarkUp: "showMarkUp", useHtmlRaw: "useHtmlRaw", html: "html" }, outputs: { html: "html", onHtmlChanged: "onHtmlChanged" }, viewQueries: [{ propertyName: "visualEditor", first: true, predicate: ["visualEditor"], descendants: true, static: true }], ngImport: i0, template: "<mat-tab-group>\n <mat-tab label=\"\u0412\u0438\u0437\u0443\u0430\u043B\u044C\u043D\u044B\u0439 \u0440\u0435\u0434\u0430\u043A\u0442\u043E\u0440\">\n\n <div style=\"height: 20px;\"></div>\n\n <croco-visual-editor #visualEditor\n [useHtmlRaw]=\"useHtmlRaw\"\n [html]=\"html\"\n (onHtmlChanged)=\"onHtmlChangedHandler($event)\"\n (rendered)=\"visualEditorRenderedHandler()\">\n </croco-visual-editor>\n\n <div style=\"height: 20px;\"></div>\n\n </mat-tab>\n\n <mat-tab label=\"\u0420\u0430\u0437\u043C\u0435\u0442\u043A\u0430\">\n <div style=\"height: 10px;\"></div>\n @if (visualEditorRendered) {\n <div>\n <mat-form-field class=\"w-100\">\n <textarea matInput cdkTextareaAutosize #autosize=\"cdkTextareaAutosize\"\n cdkAutosizeMinRows=\"1\"\n placeholder=\"\u0418\u0441\u0445\u043E\u0434\u043D\u044B\u0439 \u043A\u043E\u0434\" [(ngModel)]=\"html\"\n (ngModelChange)=\"textAreaModelChangedHandler()\"></textarea>\n </mat-form-field>\n </div>\n }\n\n <button (click)=\"copyMarkUp()\"\n mat-raised-button color=\"primary\">\n \u041A\u043E\u043F\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u0440\u0430\u0437\u043C\u0435\u0442\u043A\u0443\n </button>\n </mat-tab>\n <mat-tab label=\"\u0420\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\">\n <mat-card style=\"padding: 2px;\" class=\"mat-card\">\n <mat-card-content>\n <croco-html-xml-tag-view [data]=\"html | topreview\">\n </croco-html-xml-tag-view>\n </mat-card-content>\n </mat-card>\n </mat-tab>\n</mat-tab-group>\n", styles: [".example-list{width:500px;max-width:100%;border:solid 1px #ccc;min-height:60px;display:block;background:#fff;border-radius:4px;overflow:hidden}.example-box{padding:20px 10px;border-bottom:solid 1px #ccc;color:#000000de;display:flex;flex-direction:row;align-items:center;justify-content:space-between;box-sizing:border-box;cursor:move;background:#fff;font-size:14px}.cdk-drag-preview{box-sizing:border-box;border-radius:4px;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}.cdk-drag-placeholder{opacity:0}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.example-box:last-child{border:none}.example-list.cdk-drop-list-dragging .example-box:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}\n"], dependencies: [{ kind: "directive", type: i1$4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i2.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "component", type: i5$2.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass"], exportAs: ["matTab"] }, { kind: "component", type: i5$2.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "component", type: i4$2.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i4$2.MatCardContent, selector: "mat-card-content" }, { kind: "component", type: i1$1.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "directive", type: i3.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "directive", type: i4.CdkTextareaAutosize, selector: "textarea[cdkTextareaAutosize]", inputs: ["cdkAutosizeMinRows", "cdkAutosizeMaxRows", "cdkTextareaAutosize", "placeholder"], exportAs: ["cdkTextareaAutosize"] }, { kind: "component", type: XmlTagViewComponent, selector: "croco-html-xml-tag-view", inputs: ["data"] }, { kind: "component", type: VisualEditorComponent, selector: "croco-visual-editor", inputs: ["showMarkUp", "useHtmlRaw", "html"], outputs: ["html", "onHtmlChanged", "rendered"] }, { kind: "pipe", type: ToPreviewPipe, name: "topreview" }] }); }
1516
1615
  }
1517
1616
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: MainEditorComponent, decorators: [{
1518
1617
  type: Component,
1519
- args: [{ selector: 'croco-html-main-editor', template: "<mat-tab-group>\r\n <mat-tab label=\"\u0412\u0438\u0437\u0443\u0430\u043B\u044C\u043D\u044B\u0439 \u0440\u0435\u0434\u0430\u043A\u0442\u043E\u0440\">\r\n\r\n <div style=\"height: 20px;\"></div>\r\n\r\n <croco-visual-editor #visualEditor\r\n [useHtmlRaw]=\"useHtmlRaw\"\r\n [html]=\"html\"\r\n (onHtmlChanged)=\"onHtmlChangedHandler($event)\"\r\n (rendered)=\"visualEditorRenderedHandler()\">\r\n </croco-visual-editor>\r\n\r\n <div style=\"height: 20px;\"></div>\r\n\r\n </mat-tab>\r\n\r\n <mat-tab label=\"\u0420\u0430\u0437\u043C\u0435\u0442\u043A\u0430\">\r\n <div style=\"height: 10px;\"></div>\r\n <div *ngIf=\"visualEditorRendered\">\r\n <mat-form-field class=\"w-100\">\r\n <textarea matInput cdkTextareaAutosize #autosize=\"cdkTextareaAutosize\"\r\n cdkAutosizeMinRows=\"1\"\r\n placeholder=\"\u0418\u0441\u0445\u043E\u0434\u043D\u044B\u0439 \u043A\u043E\u0434\" [(ngModel)]=\"html\"\r\n (ngModelChange)=\"textAreaModelChangedHandler()\"></textarea>\r\n </mat-form-field>\r\n </div>\r\n\r\n <button (click)=\"copyMarkUp()\"\r\n mat-raised-button color=\"primary\">\r\n \u041A\u043E\u043F\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u0440\u0430\u0437\u043C\u0435\u0442\u043A\u0443\r\n </button>\r\n </mat-tab>\r\n <mat-tab label=\"\u0420\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\">\r\n <mat-card style=\"padding: 2px;\" class=\"mat-card\">\r\n <mat-card-content>\r\n <croco-html-xml-tag-view [data]=\"html | topreview\">\r\n </croco-html-xml-tag-view>\r\n </mat-card-content>\r\n </mat-card>\r\n </mat-tab>\r\n</mat-tab-group>\r\n", styles: [".example-list{width:500px;max-width:100%;border:solid 1px #ccc;min-height:60px;display:block;background:#fff;border-radius:4px;overflow:hidden}.example-box{padding:20px 10px;border-bottom:solid 1px #ccc;color:#000000de;display:flex;flex-direction:row;align-items:center;justify-content:space-between;box-sizing:border-box;cursor:move;background:#fff;font-size:14px}.cdk-drag-preview{box-sizing:border-box;border-radius:4px;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}.cdk-drag-placeholder{opacity:0}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.example-box:last-child{border:none}.example-list.cdk-drop-list-dragging .example-box:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}\n"] }]
1520
- }], ctorParameters: () => [{ type: i1$3.ClipboardService }, { type: i2$3.MatSnackBar }, { type: i0.ChangeDetectorRef }], propDecorators: { visualEditor: [{
1618
+ args: [{ selector: 'croco-html-main-editor', template: "<mat-tab-group>\n <mat-tab label=\"\u0412\u0438\u0437\u0443\u0430\u043B\u044C\u043D\u044B\u0439 \u0440\u0435\u0434\u0430\u043A\u0442\u043E\u0440\">\n\n <div style=\"height: 20px;\"></div>\n\n <croco-visual-editor #visualEditor\n [useHtmlRaw]=\"useHtmlRaw\"\n [html]=\"html\"\n (onHtmlChanged)=\"onHtmlChangedHandler($event)\"\n (rendered)=\"visualEditorRenderedHandler()\">\n </croco-visual-editor>\n\n <div style=\"height: 20px;\"></div>\n\n </mat-tab>\n\n <mat-tab label=\"\u0420\u0430\u0437\u043C\u0435\u0442\u043A\u0430\">\n <div style=\"height: 10px;\"></div>\n @if (visualEditorRendered) {\n <div>\n <mat-form-field class=\"w-100\">\n <textarea matInput cdkTextareaAutosize #autosize=\"cdkTextareaAutosize\"\n cdkAutosizeMinRows=\"1\"\n placeholder=\"\u0418\u0441\u0445\u043E\u0434\u043D\u044B\u0439 \u043A\u043E\u0434\" [(ngModel)]=\"html\"\n (ngModelChange)=\"textAreaModelChangedHandler()\"></textarea>\n </mat-form-field>\n </div>\n }\n\n <button (click)=\"copyMarkUp()\"\n mat-raised-button color=\"primary\">\n \u041A\u043E\u043F\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u0440\u0430\u0437\u043C\u0435\u0442\u043A\u0443\n </button>\n </mat-tab>\n <mat-tab label=\"\u0420\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\">\n <mat-card style=\"padding: 2px;\" class=\"mat-card\">\n <mat-card-content>\n <croco-html-xml-tag-view [data]=\"html | topreview\">\n </croco-html-xml-tag-view>\n </mat-card-content>\n </mat-card>\n </mat-tab>\n</mat-tab-group>\n", styles: [".example-list{width:500px;max-width:100%;border:solid 1px #ccc;min-height:60px;display:block;background:#fff;border-radius:4px;overflow:hidden}.example-box{padding:20px 10px;border-bottom:solid 1px #ccc;color:#000000de;display:flex;flex-direction:row;align-items:center;justify-content:space-between;box-sizing:border-box;cursor:move;background:#fff;font-size:14px}.cdk-drag-preview{box-sizing:border-box;border-radius:4px;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}.cdk-drag-placeholder{opacity:0}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.example-box:last-child{border:none}.example-list.cdk-drop-list-dragging .example-box:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}\n"] }]
1619
+ }], ctorParameters: () => [{ type: i1$5.ClipboardService }, { type: i2$1.MatSnackBar }, { type: i0.ChangeDetectorRef }], propDecorators: { visualEditor: [{
1521
1620
  type: ViewChild,
1522
1621
  args: ["visualEditor", { static: true }]
1523
1622
  }], showMarkUp: [{
@@ -1563,11 +1662,11 @@ class XmlTagRichTextViewComponent {
1563
1662
  ngOnInit() {
1564
1663
  }
1565
1664
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: XmlTagRichTextViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1566
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.4", type: XmlTagRichTextViewComponent, selector: "croco-html-xml-tag-rich-text-view", inputs: { richTextData: "richTextData" }, ngImport: i0, template: "<div *ngIf=\"richTextData\" [innerHtml]=\"richTextData | richTextToHtml\">\r\n</div>", styles: [""], dependencies: [{ kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: RichTextToHtmlPipe, name: "richTextToHtml" }] }); }
1665
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.4", type: XmlTagRichTextViewComponent, selector: "croco-html-xml-tag-rich-text-view", inputs: { richTextData: "richTextData" }, ngImport: i0, template: "@if (richTextData) {\n <div [innerHtml]=\"richTextData | richTextToHtml\">\n </div>\n}", styles: [""], dependencies: [{ kind: "pipe", type: RichTextToHtmlPipe, name: "richTextToHtml" }] }); }
1567
1666
  }
1568
1667
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: XmlTagRichTextViewComponent, decorators: [{
1569
1668
  type: Component,
1570
- args: [{ selector: 'croco-html-xml-tag-rich-text-view', template: "<div *ngIf=\"richTextData\" [innerHtml]=\"richTextData | richTextToHtml\">\r\n</div>" }]
1669
+ args: [{ selector: 'croco-html-xml-tag-rich-text-view', template: "@if (richTextData) {\n <div [innerHtml]=\"richTextData | richTextToHtml\">\n </div>\n}" }]
1571
1670
  }], ctorParameters: () => [], propDecorators: { richTextData: [{
1572
1671
  type: Input
1573
1672
  }] } });
@@ -1577,11 +1676,11 @@ class XmlTagTableViewComponent {
1577
1676
  this.displayedColumns = [];
1578
1677
  }
1579
1678
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: XmlTagTableViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1580
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.4", type: XmlTagTableViewComponent, selector: "croco-html-xml-tag-table-view", inputs: { displayedColumns: "displayedColumns", data: "data" }, ngImport: i0, template: "<table mat-table [dataSource]=\"data\" class=\"mat-elevation-z8 w-100 example-container\">\r\n <ng-container [matColumnDef]=\"column\" *ngFor=\"let column of displayedColumns\">\r\n <th mat-header-cell *matHeaderCellDef> {{column}} </th>\r\n <td mat-cell *matCellDef=\"let element\"> {{element[column]}} </td>\r\n </ng-container>\r\n\r\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\r\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\"></tr>\r\n</table>", styles: [""], dependencies: [{ kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: i2$4.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i2$4.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i2$4.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i2$4.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i2$4.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i2$4.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i2$4.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i2$4.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i2$4.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i2$4.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }] }); }
1679
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.4", type: XmlTagTableViewComponent, selector: "croco-html-xml-tag-table-view", inputs: { displayedColumns: "displayedColumns", data: "data" }, ngImport: i0, template: "<table mat-table [dataSource]=\"data\" class=\"mat-elevation-z8 w-100 example-container\">\n @for (column of displayedColumns; track column) {\n <ng-container [matColumnDef]=\"column\">\n <th mat-header-cell *matHeaderCellDef> {{column}} </th>\n <td mat-cell *matCellDef=\"let element\"> {{element[column]}} </td>\n </ng-container>\n }\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\"></tr>\n</table>", styles: [""], dependencies: [{ kind: "component", type: i1$6.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i1$6.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i1$6.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i1$6.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i1$6.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i1$6.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i1$6.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i1$6.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i1$6.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i1$6.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }] }); }
1581
1680
  }
1582
1681
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: XmlTagTableViewComponent, decorators: [{
1583
1682
  type: Component,
1584
- args: [{ selector: 'croco-html-xml-tag-table-view', template: "<table mat-table [dataSource]=\"data\" class=\"mat-elevation-z8 w-100 example-container\">\r\n <ng-container [matColumnDef]=\"column\" *ngFor=\"let column of displayedColumns\">\r\n <th mat-header-cell *matHeaderCellDef> {{column}} </th>\r\n <td mat-cell *matCellDef=\"let element\"> {{element[column]}} </td>\r\n </ng-container>\r\n\r\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\r\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\"></tr>\r\n</table>" }]
1683
+ args: [{ selector: 'croco-html-xml-tag-table-view', template: "<table mat-table [dataSource]=\"data\" class=\"mat-elevation-z8 w-100 example-container\">\n @for (column of displayedColumns; track column) {\n <ng-container [matColumnDef]=\"column\">\n <th mat-header-cell *matHeaderCellDef> {{column}} </th>\n <td mat-cell *matCellDef=\"let element\"> {{element[column]}} </td>\n </ng-container>\n }\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\"></tr>\n</table>" }]
1585
1684
  }], propDecorators: { displayedColumns: [{
1586
1685
  type: Input
1587
1686
  }], data: [{
@@ -1656,40 +1755,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImpor
1656
1755
  args: [CrocoHtmlOptionsToken]
1657
1756
  }] }] });
1658
1757
 
1659
- class TableBuilder {
1660
- static getTableMarkUp(rows, cols, generateHeaders) {
1661
- rows = +rows;
1662
- cols = +cols;
1663
- let result = "<table>";
1664
- if (generateHeaders) {
1665
- result += TableBuilder.getTableHeaderMarkUp(cols);
1666
- }
1667
- result += TableBuilder.getTableBodyMarkUp(cols, rows);
1668
- result += "</table>";
1669
- return XmlExtensions.formatXml(result);
1670
- }
1671
- static getTableHeaderMarkUp(cols) {
1672
- let result = "<thead><tr>";
1673
- for (let i = 0; i < cols; i++) {
1674
- result += `<th>Колонка #${i + 1}</th>`;
1675
- }
1676
- result += "</tr></thead>";
1677
- return result;
1678
- }
1679
- static getTableBodyMarkUp(cols, rows) {
1680
- let result = "<tbody>";
1681
- for (let row = 0; row < rows; row++) {
1682
- result += "<tr>";
1683
- for (let i = 0; i < cols; i++) {
1684
- result += `<td>Ряд№${row + 1} Колонка #${i + 1}</td>`;
1685
- }
1686
- result += "</tr>";
1687
- }
1688
- result += "</tbody>";
1689
- return result;
1690
- }
1691
- }
1692
-
1693
1758
  const EditorComponents = [
1694
1759
  MainEditorComponent,
1695
1760
  FileIdSelectComponent,
@@ -1765,7 +1830,8 @@ class CrocoHtmlModule {
1765
1830
  static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.3.4", ngImport: i0, type: CrocoHtmlModule, declarations: [UploadFilesBtnComponent, HtmlViewComponent, XmlTagTableViewComponent, XmlTagViewComponent, XmlTagRichTextViewComponent, XmlTagHtmlViewComponent, XmlTagTextViewComponent, XmlTagHeaderTextViewComponent, XmlTagHeaderInnerTextViewComponent, XmlTagExternalVideoComponent, HtmlRawViewComponent, FileImageTagViewComponent, HtmlViewComponent, MainEditorComponent, FileIdSelectComponent, TextEditorComponent, ExternalVideoBlockComponent, ImageEditorComponent, MainEditorBlockComponent, VisualEditorComponent, AddFilesBtnComponent, HtmlRawEditorComponent, RichTextToHtmlPipe, TagToSpanPipe, ToPreviewPipe, ToHtmlBodyTagsPipe, ToPreviewHtmlPipe], imports: [CommonModule,
1766
1831
  FormsModule,
1767
1832
  ReactiveFormsModule,
1768
- NgSelectModule, i27.MatBadgeModule, i2$4.MatTableModule, i29.MatExpansionModule, i3.MatFormFieldModule, i2$3.MatSnackBarModule, i32.MatProgressBarModule, i4$1.MatProgressSpinnerModule, i6$2.MatTabsModule, i35.MatMenuModule, i5$2.MatCardModule, i6$1.MatSelectModule, i38.MatTooltipModule, i39.MatCheckboxModule, i40.MatChipsModule, i41.MatListModule, i2.MatButtonModule, i4.MatInputModule, i44.MatDialogModule, i45.MatPaginatorModule, i46.MatDatepickerModule, i47.MatGridListModule, i48.MatSlideToggleModule, i49.MatTreeModule, i7.MatNativeDateModule, i51.MatAutocompleteModule, i52.MatSidenavModule, i5$1.MatIconModule, i11.DragDropModule, i6.MatButtonToggleModule, YouTubePlayerModule], exports: [UploadFilesBtnComponent, HtmlViewComponent, XmlTagTableViewComponent, XmlTagViewComponent, XmlTagRichTextViewComponent, XmlTagHtmlViewComponent, XmlTagTextViewComponent, XmlTagHeaderTextViewComponent, XmlTagHeaderInnerTextViewComponent, XmlTagExternalVideoComponent, HtmlRawViewComponent, FileImageTagViewComponent, HtmlViewComponent, MainEditorComponent, FileIdSelectComponent, TextEditorComponent, ExternalVideoBlockComponent, ImageEditorComponent, MainEditorBlockComponent, VisualEditorComponent, AddFilesBtnComponent, HtmlRawEditorComponent, RichTextToHtmlPipe, TagToSpanPipe, ToPreviewPipe, ToHtmlBodyTagsPipe, ToPreviewHtmlPipe] }); }
1833
+ NgSelectModule, i27.MatBadgeModule, i1$6.MatTableModule, i29.MatExpansionModule, i2.MatFormFieldModule, i2$1.MatSnackBarModule, i32.MatProgressBarModule, i3$2.MatProgressSpinnerModule, i5$2.MatTabsModule, i35.MatMenuModule, i4$2.MatCardModule, i5$1.MatSelectModule, i38.MatTooltipModule, i39.MatCheckboxModule, i40.MatChipsModule, i41.MatListModule, i1$1.MatButtonModule, i3.MatInputModule, i44.MatDialogModule, i45.MatPaginatorModule, i46.MatDatepickerModule, i47.MatGridListModule, i48.MatSlideToggleModule, i49.MatTreeModule, i6.MatNativeDateModule, i51.MatAutocompleteModule, i52.MatSidenavModule, i4$1.MatIconModule, i10.DragDropModule, i5.MatButtonToggleModule, YouTubePlayerModule,
1834
+ VkVideoPlayerComponent], exports: [UploadFilesBtnComponent, HtmlViewComponent, XmlTagTableViewComponent, XmlTagViewComponent, XmlTagRichTextViewComponent, XmlTagHtmlViewComponent, XmlTagTextViewComponent, XmlTagHeaderTextViewComponent, XmlTagHeaderInnerTextViewComponent, XmlTagExternalVideoComponent, HtmlRawViewComponent, FileImageTagViewComponent, HtmlViewComponent, MainEditorComponent, FileIdSelectComponent, TextEditorComponent, ExternalVideoBlockComponent, ImageEditorComponent, MainEditorBlockComponent, VisualEditorComponent, AddFilesBtnComponent, HtmlRawEditorComponent, RichTextToHtmlPipe, TagToSpanPipe, ToPreviewPipe, ToHtmlBodyTagsPipe, ToPreviewHtmlPipe] }); }
1769
1835
  static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: CrocoHtmlModule, imports: [CommonModule,
1770
1836
  FormsModule,
1771
1837
  ReactiveFormsModule,
@@ -1786,7 +1852,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImpor
1786
1852
  ReactiveFormsModule,
1787
1853
  NgSelectModule,
1788
1854
  ...MaterialModules,
1789
- YouTubePlayerModule
1855
+ YouTubePlayerModule,
1856
+ VkVideoPlayerComponent
1790
1857
  ]
1791
1858
  }]
1792
1859
  }] });
@@ -1799,5 +1866,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImpor
1799
1866
  * Generated bundle index. Do not edit.
1800
1867
  */
1801
1868
 
1802
- export { AddFilesBtnComponent, AngularMaterialTableMethods, BodyTagsExtensions, BootstrapTableMethods, CrocoHtmlModule, CrocoHtmlOptionsToken, ExternalVideoBlockComponent, ExternalVideoSupportedTypes, ExternalVideoTagDataConsts, FileIdSelectComponent, FileImageTagDataConsts, FileImageTagViewComponent, HtmlRawEditorComponent, HtmlRawViewComponent, HtmlViewComponent, ImageEditorComponent, ImageMethods, MainEditorBlockComponent, MainEditorComponent, RichTextToHtmlPipe, TableBuilder, TableMethods, TableTypes, TagToSpanPipe, TextEditorComponent, TextMethods, TextSimpleMethods, TextTag, ToHtmlBodyTagsPipe, ToPreviewHtmlPipe, ToPreviewPipe, UploadFilesBtnComponent, VideoMethods, VisualEditorComponent, XmlExtensions, XmlTagExternalVideoComponent, XmlTagHeaderInnerTextViewComponent, XmlTagHeaderTextViewComponent, XmlTagHtmlViewComponent, XmlTagRichTextViewComponent, XmlTagTableViewComponent, XmlTagTextViewComponent, XmlTagViewComponent };
1869
+ export { AddFilesBtnComponent, AngularMaterialTableMethods, BodyTagsExtensions, BootstrapTableMethods, CrocoHtmlModule, CrocoHtmlOptionsToken, ExternalVideoBlockComponent, ExternalVideoPlayers, ExternalVideoSupportedTypes, ExternalVideoTagDataConsts, FileIdSelectComponent, FileImageTagDataConsts, FileImageTagViewComponent, HtmlRawEditorComponent, HtmlRawViewComponent, HtmlViewComponent, ImageEditorComponent, ImageMethods, MainEditorBlockComponent, MainEditorComponent, RichTextToHtmlPipe, TableBuilder, TableMethods, TableTypes, TagToSpanPipe, TextEditorComponent, TextMethods, TextSimpleMethods, TextTag, TextTags, ToHtmlBodyTagsPipe, ToPreviewHtmlPipe, ToPreviewPipe, UploadFilesBtnComponent, VideoMethods, VisualEditorComponent, XmlExtensions, XmlTagExternalVideoComponent, XmlTagHeaderInnerTextViewComponent, XmlTagHeaderTextViewComponent, XmlTagHtmlViewComponent, XmlTagRichTextViewComponent, XmlTagTableViewComponent, XmlTagTextViewComponent, XmlTagViewComponent, defaultLinkVk, defaultLinkYouTube };
1803
1870
  //# sourceMappingURL=croco-html.mjs.map