croco-html 2.3.1 → 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 (69) 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 +6 -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 +14 -4
  54. package/esm2022/public-api.mjs +1 -1
  55. package/fesm2022/croco-html.mjs +967 -888
  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 +2 -2
  68. package/lib/services/files-query.service.d.ts +12 -1
  69. 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,930 +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
- class FilesQueryService {
417
- constructor(_httpClient, baseUrl) {
418
- this._httpClient = _httpClient;
419
- 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;
420
458
  }
421
- getFilesWithRelations(model) {
422
- 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;
423
465
  }
424
- getFiles(model) {
425
- 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
+ }
426
486
  }
427
- 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 }); }
428
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: FilesQueryService, providedIn: 'root' }); }
429
487
  }
430
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: FilesQueryService, decorators: [{
431
- type: Injectable,
432
- args: [{
433
- providedIn: 'root'
434
- }]
435
- }], ctorParameters: () => [{ type: i1.HttpClient }, { type: undefined, decorators: [{
436
- type: Inject,
437
- args: ['BASE_URL']
438
- }] }] });
439
488
 
440
- class FileIdSelectComponent {
441
- constructor(_fileService, _options) {
442
- this._fileService = _fileService;
443
- this._options = _options;
444
- this.labelText = "Поиск файлов";
445
- this.loading = false;
446
- this.files = [];
447
- 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
+ };
448
523
  }
449
- onModelChanged(fileId) {
450
- 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
+ };
451
543
  }
452
- getSrc(fileId) {
453
- 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
+ };
454
559
  }
455
- ngOnInit() {
456
- 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;
457
590
  }
458
- loadFiles() {
459
- this.loading = true;
460
- this._fileService.getFiles({
461
- count: 10,
462
- offSet: 0,
463
- fileName: null,
464
- q: this.q
465
- }).subscribe(data => {
466
- this.files = [...data.list];
467
- this.loading = false;
468
- });
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
+ };
469
628
  }
470
- onSearchChanged(q) {
471
- this.q = q.term;
472
- 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',
473
648
  }
474
- ngOnChanges(changes) {
475
- 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
+ };
476
659
  }
477
- 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 }); }
478
- 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]" }] }); }
479
660
  }
480
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: FileIdSelectComponent, decorators: [{
481
- type: Component,
482
- 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" }]
483
- }], ctorParameters: () => [{ type: FilesQueryService }, { type: undefined, decorators: [{
484
- type: Inject,
485
- args: [CrocoHtmlOptionsToken]
486
- }] }], propDecorators: { labelText: [{
487
- type: Input
488
- }], fileId: [{
489
- type: Input
490
- }, {
491
- type: Output
492
- }], onFileIdChanged: [{
493
- type: Output
494
- }] } });
495
661
 
496
- class ImageEditorComponent {
497
- onErrorHandler() {
498
- this.hasImageError = true;
499
- }
500
- constructor(_options) {
501
- this._options = _options;
502
- this.hasImageError = false;
503
- this.searchOrEdit = "search";
504
- this.onTagUpdated = new EventEmitter();
505
- }
506
- getSrc() {
507
- return ImageMethods.buildUrl(this.tag.attributes[FileImageTagDataConsts.FileIdAttrName], "Medium", this._options);
508
- }
509
- hasFileId() {
510
- return this.tag.attributes.hasOwnProperty(FileImageTagDataConsts.FileIdAttrName) && !isNaN(this.tag.attributes[FileImageTagDataConsts.FileIdAttrName]);
511
- }
512
- onFileIdChanged(fileId) {
513
- this.tag.attributes[FileImageTagDataConsts.FileIdAttrName] = fileId;
514
- this.removeImageError();
515
- }
516
- removeImageError() {
517
- this.hasImageError = false;
518
- }
519
- ngOnInit() {
662
+ class HtmlExtractionMethods {
663
+ static ExtractHeaderTag(elem, tagName) {
664
+ var data = TextSimpleMethods.ExtractTextTag(elem);
665
+ data.type = tagName;
666
+ return data;
520
667
  }
521
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: ImageEditorComponent, deps: [{ token: CrocoHtmlOptionsToken }], target: i0.ɵɵFactoryTarget.Component }); }
522
- 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"] }] }); }
523
- }
524
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: ImageEditorComponent, decorators: [{
525
- type: Component,
526
- 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"] }]
527
- }], ctorParameters: () => [{ type: undefined, decorators: [{
528
- type: Inject,
529
- args: [CrocoHtmlOptionsToken]
530
- }] }], propDecorators: { tag: [{
531
- type: Input
532
- }], onTagUpdated: [{
533
- type: Output
534
- }] } });
535
-
536
- class XmlTagHtmlViewComponent {
537
- constructor() {
538
- 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;
539
706
  }
540
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: XmlTagHtmlViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
541
- 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: [""] }); }
542
- }
543
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: XmlTagHtmlViewComponent, decorators: [{
544
- type: Component,
545
- args: [{ selector: 'croco-html-xml-tag-html-view', template: "<div class=\"col\" [innerHTML]=\"html\">\r\n</div>" }]
546
- }], ctorParameters: () => [], propDecorators: { html: [{
547
- type: Input
548
- }] } });
549
-
550
- class XmlTagTextViewComponent {
551
- constructor() { }
552
- 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);
553
717
  }
554
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: XmlTagTextViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
555
- 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"] }] }); }
556
718
  }
557
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: XmlTagTextViewComponent, decorators: [{
558
- type: Component,
559
- 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>" }]
560
- }], ctorParameters: () => [], propDecorators: { item: [{
561
- type: Input
562
- }] } });
563
719
 
564
- class XmlTagHeaderInnerTextViewComponent {
565
- constructor() { }
566
- ngOnInit() {
567
- }
568
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: XmlTagHeaderInnerTextViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
569
- 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"; }
570
722
  }
571
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: XmlTagHeaderInnerTextViewComponent, decorators: [{
572
- type: Component,
573
- 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>" }]
574
- }], ctorParameters: () => [], propDecorators: { item: [{
575
- type: Input
576
- }] } });
577
723
 
578
- class XmlTagHeaderTextViewComponent {
579
- constructor() { }
580
- ngOnInit() {
581
- }
582
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: XmlTagHeaderTextViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
583
- 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'; }
584
738
  }
585
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: XmlTagHeaderTextViewComponent, decorators: [{
586
- type: Component,
587
- 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>" }]
588
- }], ctorParameters: () => [], propDecorators: { item: [{
589
- type: Input
590
- }] } });
591
739
 
592
- class HtmlRawViewComponent {
593
- constructor(_sanitizer) {
594
- this._sanitizer = _sanitizer;
595
- this.rawHtml = "";
596
- this.isInitialized = false;
597
- }
598
- ngOnInit() {
599
- 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];
600
755
  }
601
- 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 }); }
602
- 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: [""] }); }
603
- }
604
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: HtmlRawViewComponent, decorators: [{
605
- type: Component,
606
- args: [{ selector: 'croco-html-raw-view', template: "<div [innerHTML]=\"safeHtml\">\n</div>" }]
607
- }], ctorParameters: () => [{ type: i1$2.DomSanitizer }], propDecorators: { rawHtml: [{
608
- type: Input
609
- }] } });
610
-
611
- class FileImageTagViewComponent {
612
- constructor() {
613
- 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;
614
775
  }
615
- ngOnInit() {
616
- let data = this.item.data;
617
- 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}>`;
618
783
  }
619
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: FileImageTagViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
620
- 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: [""] }); }
621
- }
622
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: FileImageTagViewComponent, decorators: [{
623
- type: Component,
624
- 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\"/>" }]
625
- }], propDecorators: { item: [{
626
- type: Input
627
- }] } });
628
-
629
- class XmlTagViewComponent {
630
- constructor() {
631
- this.data = [];
784
+ static getBodyTags(html, options) {
785
+ let result = HtmlExtractionMethods.transformHtmlStringToBlocks(html, options);
786
+ return result.map(x => BodyTagsExtensions.toBodyTag(x));
632
787
  }
633
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: XmlTagViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
634
- 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 }); }
635
- }
636
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: XmlTagViewComponent, decorators: [{
637
- type: Component,
638
- 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"] }]
639
- }], ctorParameters: () => [], propDecorators: { data: [{
640
- type: Input
641
- }] } });
642
-
643
- class AngularMaterialTableMethods {
644
- static getAngularMaterialTableData(columns, rows) {
645
- let data = [];
646
- for (let rowIndex = 0; rowIndex < rows.length; rowIndex++) {
647
- const row = rows[rowIndex];
648
- var elem = {};
649
- for (let columnIndex = 0; columnIndex < columns.length; columnIndex++) {
650
- const column = columns[columnIndex];
651
- elem[column] = row.columns[columnIndex].data.text;
652
- }
653
- data.push(elem);
654
- }
655
- return {
656
- displayedColumns: columns,
657
- data: data,
658
- };
788
+ static sanitizeInnerHtml(html) {
789
+ return html.trim().replace('\n\t', '');
659
790
  }
660
- static checkHeaders(tableData) {
661
- if (tableData.header === null) {
791
+ static toBodyTag(data) {
792
+ if (TextTags.allTextTags.includes(data.type)) {
793
+ let textTagData = data.data;
662
794
  return {
663
- isSucceeded: false,
664
- 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)
665
802
  };
666
803
  }
667
- let columns = tableData.header.columns;
668
- var uniqueDislayedColumns = columns.filter((v, i, a) => a.indexOf(v) === i);
669
- if (uniqueDislayedColumns.length !== columns.length) {
804
+ if (data.type === FileImageTagDataConsts.TagName) {
805
+ let fileData = data.data;
806
+ let attrs = {};
807
+ if (fileData.fileId) {
808
+ attrs[FileImageTagDataConsts.FileIdAttrName] = fileData.fileId;
809
+ }
670
810
  return {
671
- isSucceeded: false,
672
- message: "Ошибка при обработке разметки таблицы. Обнаружены дубликаты заголовков."
811
+ presentOrEdit: true,
812
+ tagDescription: {
813
+ tag: FileImageTagDataConsts.TagName,
814
+ displayValue: BodyTagsExtensions.getDescription(data.type)
815
+ },
816
+ attributes: attrs,
817
+ innerHtml: ""
673
818
  };
674
819
  }
675
- return {
676
- isSucceeded: true,
677
- message: "Ok"
678
- };
679
- }
680
- static checkAngularMaterialTableData(tableData, checkHeaders = true) {
681
- if (checkHeaders) {
682
- var checkHeadersResult = this.checkHeaders(tableData);
683
- if (!checkHeadersResult.isSucceeded) {
684
- return checkHeadersResult;
685
- }
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
+ };
686
831
  }
687
- let rows = tableData.rows;
688
- let columns = tableData.header.columns;
689
- for (let i = 0; i < rows.length; i++) {
690
- const row = rows[i];
691
- if (row.columns.length !== columns.length) {
692
- return {
693
- isSucceeded: false,
694
- message: `Ошибка при обработке разметки таблицы. `
695
- + `Количество колонок в каждой строке таблицы должно соотвествовать количеству колонок указанных в заголовке. `
696
- + `В строке таблицы №${i + 1} количество колонок = ${row.columns.length}, а должно быть ${columns.length}.`
697
- };
698
- }
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
+ };
699
842
  }
700
843
  return {
701
- isSucceeded: true,
702
- message: "Ok"
844
+ presentOrEdit: true,
845
+ tagDescription: {
846
+ tag: Tags.UnsupportedTag,
847
+ displayValue: "Неподдерживаемый тег"
848
+ },
849
+ attributes: {},
850
+ innerHtml: JSON.stringify(data)
703
851
  };
704
852
  }
705
853
  }
706
854
 
707
- var EAlignments;
708
- (function (EAlignments) {
709
- EAlignments["Left"] = "left";
710
- EAlignments["Center"] = "center";
711
- EAlignments["Right"] = "right";
712
- })(EAlignments || (EAlignments = {}));
713
- const AlignmentsData = [
714
- { value: EAlignments.Left, text: 'Слева' },
715
- { value: EAlignments.Center, text: 'По центру' },
716
- { value: EAlignments.Right, text: 'Справа' },
717
- ];
718
-
719
- const TextTag = "text";
720
- class TextSimpleMethods {
721
- static { this.supportedTags = ["sup", "sub", "strong", "b", "i", "u"]; }
722
- static ExtractTextTag(elem) {
723
- var hAlignValue = elem.getAttribute("h-align") ?? EAlignments.Left;
724
- var data = {
725
- textTagName: elem.tagName.toLowerCase(),
726
- text: elem.innerText.trim().replace('\n\t', ''),
727
- html: elem.innerHTML.trim().replace('\n\t', ''),
728
- horizontalAlignment: hAlignValue,
729
- validationResult: {
730
- isSucceeded: true,
731
- message: "Ok"
732
- }
733
- };
734
- let result = {
735
- type: TextTag,
736
- data: data
737
- };
738
- if (result.data.text === '\n') {
739
- result.data.text = '';
740
- }
741
- if (result.data.html === '\n') {
742
- result.data.html = '';
743
- }
744
- var alignmentVals = [EAlignments.Left, EAlignments.Right, EAlignments.Center];
745
- if (alignmentVals.indexOf(hAlignValue) < 0) {
746
- result.data.validationResult = {
747
- isSucceeded: false,
748
- message: `Недопустимое значение атрибута h-align. Допустимые значения: ${alignmentVals.join(', ')}. `
749
- + 'Данный тег можно не указывать, по-умолчанию будет применено выравнивание слева.'
750
- };
751
- }
752
- var html = result.data.html;
753
- var htmlValidation = this.ValidateTextHtml(html);
754
- if (!htmlValidation.isSucceeded) {
755
- result.data.validationResult = htmlValidation;
756
- }
757
- 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);
758
867
  }
759
- static ValidateTextHtml(html) {
760
- var p = document.createElement("p");
761
- p.innerHTML = html;
762
- for (let i = 0; i < p.children.length; i++) {
763
- const element = p.children.item(i);
764
- var validationResult = this.ValidateTag(element);
765
- if (!validationResult.isSucceeded) {
766
- return validationResult;
767
- }
768
- }
769
- return {
770
- isSucceeded: true,
771
- message: `Ok`
772
- };
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;
773
873
  }
774
- static ValidateTag(element) {
775
- let lowerTag = element.tagName.toLowerCase();
776
- if (!this.supportedTags.includes(lowerTag)) {
777
- return {
778
- isSucceeded: false,
779
- message: `Тег <${lowerTag}> не поддерживается внутри тега <text>`
780
- };
781
- }
782
- for (let i = 0; i < element.children.length; i++) {
783
- const nElement = element.children.item(i);
784
- var innerValidationResult = this.ValidateTag(nElement);
785
- if (!innerValidationResult.isSucceeded) {
786
- return innerValidationResult;
787
- }
788
- }
789
- return {
790
- isSucceeded: true,
791
- message: "Ok"
792
- };
874
+ static replaceTagToLower(xml, tag) {
875
+ return xml
876
+ .replace(new RegExp(`<${tag}`, 'g'), `<${tag.toLowerCase()}`)
877
+ .replace(new RegExp(`</${tag}>`, 'g'), `</${tag.toLowerCase()}>`);
793
878
  }
794
879
  }
795
880
 
796
- class BootstrapTableMethods {
797
- static BuildTable(data) {
798
- let result = `<table class="table table-bordered">`;
799
- result += this.BuildHeader(data.header);
800
- 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);
801
890
  result += "</table>";
802
- return result;
891
+ return XmlExtensions.formatXml(result);
803
892
  }
804
- static BuildHeader(data) {
805
- if (data === null) {
806
- return "";
807
- }
808
- let result = "<thead>";
809
- result += "<tr>";
810
- for (let index = 0; index < data.columns.length; index++) {
811
- 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>`;
812
897
  }
813
- result += "</tr>";
814
- result += "</thead>";
898
+ result += "</tr></thead>";
815
899
  return result;
816
900
  }
817
- static BuildBody(rows) {
901
+ static getTableBodyMarkUp(cols, rows) {
818
902
  let result = "<tbody>";
819
- for (let i = 0; i < rows.length; i++) {
820
- const row = rows[i];
903
+ for (let row = 0; row < rows; row++) {
821
904
  result += "<tr>";
822
- for (let j = 0; j < row.columns.length; j++) {
823
- const col = row.columns[j];
824
- 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>`;
825
907
  }
826
908
  result += "</tr>";
827
909
  }
828
910
  result += "</tbody>";
829
911
  return result;
830
912
  }
831
- static BuildInnerTags(tags) {
832
- let result = "";
833
- for (let i = 0; i < tags.length; i++) {
834
- result += this.BuildInnerTag(tags[i]);
835
- }
836
- return result;
913
+ }
914
+
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);
923
+ };
924
+ });
925
+ }
926
+
927
+ class VkVideoPlayerComponent {
928
+ set link(link) {
929
+ this.safeUrl = this.sanitizer.bypassSecurityTrustResourceUrl(link);
837
930
  }
838
- static BuildInnerTag(data) {
839
- if (data.type === FileImageTagDataConsts.TagName) {
840
- let fileImageTag = data;
841
- return `<img src=${fileImageTag.data.src} class="mx-auto d-block img-fluid" />`;
842
- }
843
- else if (data.type === TextTag) {
844
- let simpleTextTag = data;
845
- var map = {
846
- ["left"]: "text-start",
847
- ["center"]: "text-center",
848
- ["right"]: "text-end"
849
- };
850
- if (!simpleTextTag.data.validationResult.isSucceeded) {
851
- return `<span>Ошибка в тексте ${simpleTextTag.data.validationResult.message}</span>`;
852
- }
853
- return `<div class="${map[simpleTextTag.data.horizontalAlignment]}"><span>${simpleTextTag.data.html}</span></div>`;
854
- }
855
- else {
856
- return `<p>Тег ${data.type} не поддерживается</p>`;
857
- }
931
+ constructor(sanitizer) {
932
+ this.sanitizer = sanitizer;
858
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"] }); }
859
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
+ }] } });
860
943
 
861
- class TableTypes {
862
- static { this.TableRowColumnData = "table-row-column-data"; }
863
- static { this.Table = "table"; }
864
- static { this.TableRowColumn = "table-row-column"; }
865
- }
866
- class TableMethods {
867
- static getTableFromHtmlTag(tableTag, options) {
868
- let tableData = {
869
- header: TableMethods.getHeader(tableTag),
870
- rows: TableMethods.getTableRows(tableTag, options)
871
- };
872
- var result = {
873
- type: TableTypes.Table,
874
- data: tableData,
875
- validationResult: this.checkTable(tableData),
876
- bootstrapHtml: ""
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
877
953
  };
878
- if (!result.validationResult) {
879
- return result;
880
- }
881
- result.bootstrapHtml = BootstrapTableMethods.BuildTable(result.data);
882
- var angularMaterialTableDataCheck = AngularMaterialTableMethods.checkAngularMaterialTableData(tableData);
883
- if (!angularMaterialTableDataCheck.isSucceeded) {
884
- return {
885
- ...result,
886
- angularMaterialTableDataCheck
887
- };
954
+ if (this._block.type === ExternalVideoSupportedTypes.VkVideo) {
955
+ return;
888
956
  }
889
- return {
890
- ...result,
891
- angularMaterialTableDataCheck,
892
- html: tableTag.outerHTML,
893
- angularMaterialTableData: AngularMaterialTableMethods.getAngularMaterialTableData(tableData.header.columns, tableData.rows),
894
- };
957
+ this.videoId = this.getYouTubeId(this._block.link);
895
958
  }
896
- static checkTable(tableData) {
897
- let rows = tableData.rows;
898
- let prevRowCount = -1;
899
- for (let i = 0; i < rows.length; i++) {
900
- const row = rows[i];
901
- if (row.columns.length !== prevRowCount && prevRowCount != -1) {
902
- return {
903
- isSucceeded: false,
904
- message: `Ошибка при обработке разметки таблицы. `
905
- + `Количество колонок в каждой строке таблицы должно соотвествовать друг другу. `
906
- + `В строке таблицы №${i + 1} количество колонок = ${row.columns.length}, а в строке выше ${prevRowCount}.`
907
- };
908
- }
909
- prevRowCount = row.columns.length;
910
- }
911
- return {
912
- isSucceeded: true,
913
- message: "Ok"
959
+ ;
960
+ constructor(destroyRef) {
961
+ this.destroyRef = destroyRef;
962
+ this._block = {
963
+ type: '',
964
+ link: ''
914
965
  };
966
+ this.playerWidth = signal(NaN);
967
+ this.playerHeight = signal(NaN);
968
+ this.ExternalVideoSupportedTypes = ExternalVideoSupportedTypes;
915
969
  }
916
- static getHeader(tableTag) {
917
- let header = tableTag.tHead;
918
- if (header === null) {
919
- return null;
970
+ ngOnInit() {
971
+ if (this._block.type === ExternalVideoSupportedTypes.VkVideo) {
972
+ return;
920
973
  }
921
- let tr = header.children.item(0);
922
- let headerColumns = [];
923
- for (let j = 0; j < tr.children.length; j++) {
924
- const jElement = tr.children.item(j);
925
- 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);
926
981
  }
927
- return {
928
- type: "table-header",
929
- columns: headerColumns
930
- };
931
- }
932
- static getTableRows(tableTag, options) {
933
- let tBody = tableTag.tBodies.item(0);
934
- let rows = [];
935
- for (let i = 0; i < tBody.children.length; i++) {
936
- const iElement = tBody.children.item(i);
937
- let rowColumns = [];
938
- for (let j = 0; j < iElement.children.length; j++) {
939
- const jElement = iElement.children.item(j);
940
- let children = HtmlExtractionMethods.transformHtmlElementToBlocks(jElement, options);
941
- if (children.length === 0) {
942
- var textTag = document.createElement("p");
943
- textTag.innerHTML = jElement.innerHTML;
944
- var textElem = TextSimpleMethods.ExtractTextTag(textTag);
945
- children.push(textElem);
946
- }
947
- var result = {
948
- type: TableTypes.TableRowColumnData,
949
- data: {
950
- text: jElement.innerHTML,
951
- children
952
- }
953
- };
954
- rowColumns.push(result);
955
- }
956
- rows.push({
957
- type: TableTypes.TableRowColumn,
958
- 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);
959
988
  });
960
989
  }
961
- return rows;
962
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 }); }
963
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
+ }] } });
964
1015
 
965
- class TextMethods {
966
- static { this.textTags = ["text", "h1", "h2", "h3", "h4", "h5", "h6"]; }
967
- static ExtractRichTextData(elem) {
968
- let children = [];
969
- for (let i = 0; i < elem.children.length; i++) {
970
- const child = elem.children.item(i);
971
- if (child.tagName === "text-block".toUpperCase()) {
972
- children.push({
973
- type: "text-block",
974
- data: {
975
- text: child.innerHTML
976
- }
977
- });
978
- }
979
- else if (child.tagName === "line-break".toUpperCase()) {
980
- children.push({
981
- type: "line-break"
982
- });
983
- }
984
- }
985
- return {
986
- type: "rich-text",
987
- data: {
988
- children
989
- }
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
990
1025
  };
991
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"] }] }); }
992
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
+ }] } });
993
1042
 
994
- class HtmlExtractionMethods {
995
- static ExtractHeaderTag(elem, tagName) {
996
- var data = TextSimpleMethods.ExtractTextTag(elem);
997
- data.type = tagName;
998
- return data;
1043
+ class HtmlRawEditorComponent {
1044
+ constructor() {
1045
+ this.onTagUpdated = new EventEmitter();
999
1046
  }
1000
- static { this.Extractors = {
1001
- ["TEXT"]: (elem, options) => TextSimpleMethods.ExtractTextTag(elem),
1002
- ["FILE-IMAGE"]: (elem, options) => ImageMethods.ExtractImage(elem, options),
1003
- ["TABLE"]: (elem, options) => TableMethods.getTableFromHtmlTag(elem, options),
1004
- ["RICH-TEXT"]: (elem, options) => TextMethods.ExtractRichTextData(elem),
1005
- ["HTML-RAW"]: (elem, options) => ({
1006
- type: "html-raw",
1007
- data: {
1008
- innerHTML: elem.innerHTML
1009
- }
1010
- }),
1011
- ["H1"]: (elem, options) => HtmlExtractionMethods.ExtractHeaderTag(elem, "h1"),
1012
- ["H2"]: (elem, options) => HtmlExtractionMethods.ExtractHeaderTag(elem, "h2"),
1013
- ["H3"]: (elem, options) => HtmlExtractionMethods.ExtractHeaderTag(elem, "h3"),
1014
- ["H4"]: (elem, options) => HtmlExtractionMethods.ExtractHeaderTag(elem, "h4"),
1015
- ["H5"]: (elem, options) => HtmlExtractionMethods.ExtractHeaderTag(elem, "h5"),
1016
- ["H6"]: (elem, options) => HtmlExtractionMethods.ExtractHeaderTag(elem, "h6"),
1017
- [ExternalVideoTagDataConsts.TagName.toUpperCase()]: (elem, options) => VideoMethods.ExtractExternalVideoTag(elem)
1018
- }; }
1019
- static transformHtmlElementToBlocks(element, options) {
1020
- var data = [];
1021
- for (let i = 0; i < element.children.length; i++) {
1022
- var elem = element.children.item(i);
1023
- if (!HtmlExtractionMethods.Extractors.hasOwnProperty(elem.tagName)) {
1024
- data.push({
1025
- type: "unsupported-tag",
1026
- data: {
1027
- tagString: elem.outerHTML
1028
- }
1029
- });
1030
- }
1031
- else {
1032
- var extractor = HtmlExtractionMethods.Extractors[elem.tagName];
1033
- var result = extractor(elem, options);
1034
- data.push(result);
1035
- }
1036
- }
1037
- return data;
1047
+ ngOnInit() {
1038
1048
  }
1039
- static transformHtmlStringToBlocks(value, options) {
1040
- if (value === undefined || value === null) {
1041
- return [];
1042
- }
1043
- value = value
1044
- .replace('\n', '')
1045
- .replace('\t', '');
1046
- var div = document.createElement("div");
1047
- div.innerHTML = value;
1048
- 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() {
1049
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"] }] }); }
1050
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
+ }] } });
1051
1194
 
1052
- class HtmlRawTagDataConsts {
1053
- 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: [""] }); }
1054
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
+ }] } });
1055
1208
 
1056
- class BodyTagsExtensions {
1057
- static getDescription(tagName) {
1058
- var descriptions = {
1059
- "text": "Текст",
1060
- "h1": "Заголовок 1 уровня",
1061
- "h2": "Заголовок 2 уровня",
1062
- "h3": "Заголовок 3 уровня",
1063
- "h4": "Заголовок 4 уровня",
1064
- "h5": "Заголовок 5 уровня",
1065
- "h6": "Заголовок 6 уровня",
1066
- [FileImageTagDataConsts.TagName]: "Изображение",
1067
- [ExternalVideoTagDataConsts.TagName]: "Внешнее видео YouTube",
1068
- [HtmlRawTagDataConsts.TagName]: "Html разметка"
1069
- };
1070
- return descriptions[tagName];
1071
- }
1072
- static toHtml(bodyTags) {
1073
- let htmls = bodyTags.map(x => {
1074
- if (TextMethods.textTags.includes(x.tagDescription.tag)) {
1075
- return `<${x.tagDescription.tag} h-align="${x.attributes['h-align']}">${x.innerHtml}</${x.tagDescription.tag}>`;
1076
- }
1077
- if (x.tagDescription.tag === ExternalVideoTagDataConsts.TagName) {
1078
- return `<${x.tagDescription.tag} type="${x.attributes['type']}" link="${x.attributes['link']}">${x.innerHtml}</${x.tagDescription.tag}>`;
1079
- }
1080
- if (x.tagDescription.tag === "html-raw") {
1081
- return `<${x.tagDescription.tag}>${x.innerHtml}</${x.tagDescription.tag}>`;
1082
- }
1083
- return BodyTagsExtensions.imageTagToHtml(x);
1084
- });
1085
- let result = "";
1086
- for (let index = 0; index < htmls.length; index++) {
1087
- const element = htmls[index];
1088
- result += element;
1089
- }
1090
- return result;
1209
+ class XmlTagTextViewComponent {
1210
+ constructor() { }
1211
+ ngOnInit() {
1091
1212
  }
1092
- static imageTagToHtml(imageTag) {
1093
- var attrStr = "";
1094
- var attrValue = imageTag.attributes[FileImageTagDataConsts.FileIdAttrName];
1095
- if (imageTag.attributes.hasOwnProperty(FileImageTagDataConsts.FileIdAttrName) && attrValue) {
1096
- attrStr = `${FileImageTagDataConsts.FileIdAttrName}="${attrValue}"`;
1097
- }
1098
- 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() {
1099
1226
  }
1100
- static getBodyTags(html, options) {
1101
- let result = HtmlExtractionMethods.transformHtmlStringToBlocks(html, options);
1102
- 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() {
1103
1240
  }
1104
- static sanitizeInnerHtml(html) {
1105
- 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;
1106
1256
  }
1107
- static toBodyTag(data) {
1108
- if (TextMethods.textTags.includes(data.type)) {
1109
- let textTagData = data.data;
1110
- return {
1111
- presentOrEdit: true,
1112
- tagDescription: {
1113
- tag: textTagData.textTagName,
1114
- displayValue: BodyTagsExtensions.getDescription(data.type)
1115
- },
1116
- attributes: { "h-align": textTagData.horizontalAlignment },
1117
- innerHtml: BodyTagsExtensions.sanitizeInnerHtml(textTagData.html)
1118
- };
1119
- }
1120
- if (data.type === FileImageTagDataConsts.TagName) {
1121
- let fileData = data.data;
1122
- let attrs = {};
1123
- if (fileData.fileId) {
1124
- attrs[FileImageTagDataConsts.FileIdAttrName] = fileData.fileId;
1125
- }
1126
- return {
1127
- presentOrEdit: true,
1128
- tagDescription: {
1129
- tag: FileImageTagDataConsts.TagName,
1130
- displayValue: BodyTagsExtensions.getDescription(data.type)
1131
- },
1132
- attributes: attrs,
1133
- innerHtml: ""
1134
- };
1135
- }
1136
- if (data.type === ExternalVideoTagDataConsts.TagName) {
1137
- let fileData = data.data;
1138
- return {
1139
- presentOrEdit: true,
1140
- tagDescription: {
1141
- tag: ExternalVideoTagDataConsts.TagName,
1142
- displayValue: BodyTagsExtensions.getDescription(data.type)
1143
- },
1144
- attributes: fileData,
1145
- innerHtml: ""
1146
- };
1147
- }
1148
- if (data.type === HtmlRawTagDataConsts.TagName) {
1149
- return {
1150
- presentOrEdit: true,
1151
- tagDescription: {
1152
- tag: HtmlRawTagDataConsts.TagName,
1153
- displayValue: BodyTagsExtensions.getDescription(data.type)
1154
- },
1155
- attributes: {},
1156
- innerHtml: BodyTagsExtensions.sanitizeInnerHtml(data.data["innerHTML"])
1157
- };
1158
- }
1159
- return {
1160
- presentOrEdit: true,
1161
- tagDescription: {
1162
- tag: "unsupported-tag",
1163
- displayValue: "Неподдерживаемый тег"
1164
- },
1165
- attributes: {},
1166
- innerHtml: JSON.stringify(data)
1167
- };
1257
+ ngOnInit() {
1258
+ this.safeHtml = this._sanitizer.bypassSecurityTrustHtml(this.rawHtml);
1168
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: [""] }); }
1169
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
+ }] } });
1170
1269
 
1171
- class XmlExtensions {
1172
- static formatXml(xml, tab = '\t') {
1173
- var formatted = '', indent = '';
1174
- tab = tab || '\t';
1175
- xml.split(/>\s*</).forEach(function (node) {
1176
- if (node.match(/^\/\w/))
1177
- indent = indent.substring(tab.length); // decrease indent by one 'tab'
1178
- formatted += indent + '<' + node + '>\r\n';
1179
- if (node.match(/^<?\w[^>]*[^\/]$/))
1180
- indent += tab; // increase indent
1181
- });
1182
- return formatted.substring(1, formatted.length - 3);
1270
+ class FileImageTagViewComponent {
1271
+ constructor() {
1272
+ this.imageSrc = "";
1183
1273
  }
1184
- static tagsToLower(xml) {
1185
- xml = this.replaceTagToLower(xml, "Body");
1186
- xml = this.replaceTagToLower(xml, "Image");
1187
- xml = this.replaceTagToLower(xml, "Text");
1188
- return xml;
1274
+ ngOnInit() {
1275
+ let data = this.item.data;
1276
+ this.imageSrc = data.src;
1189
1277
  }
1190
- static replaceTagToLower(xml, tag) {
1191
- return xml
1192
- .replace(new RegExp(`<${tag}`, 'g'), `<${tag.toLowerCase()}`)
1193
- .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;
1194
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 }); }
1195
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
+ }] } });
1196
1302
 
1197
1303
  class DefaultTags {
1198
1304
  static { this.textTags = [
@@ -1206,7 +1312,7 @@ class DefaultTags {
1206
1312
  ]; }
1207
1313
  static { this.tags = [
1208
1314
  { tag: FileImageTagDataConsts.TagName, displayValue: 'Изображение' },
1209
- { tag: ExternalVideoTagDataConsts.TagName, displayValue: 'Внешнее видео Youtube' },
1315
+ { tag: ExternalVideoTagDataConsts.TagName, displayValue: 'Внешнее видео' },
1210
1316
  ...DefaultTags.textTags
1211
1317
  ]; }
1212
1318
  static { this.htmlRawTag = {
@@ -1231,11 +1337,11 @@ class TextEditorComponent {
1231
1337
  return `<${this.tag.tagDescription.tag}>${this.tag.innerHtml}<${this.tag.tagDescription.tag}/>`;
1232
1338
  }
1233
1339
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: TextEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1234
- 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"] }] }); }
1235
1341
  }
1236
1342
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: TextEditorComponent, decorators: [{
1237
1343
  type: Component,
1238
- 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}" }]
1239
1345
  }], ctorParameters: () => [], propDecorators: { tag: [{
1240
1346
  type: Input
1241
1347
  }], onTagUpdated: [{
@@ -1244,7 +1350,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImpor
1244
1350
 
1245
1351
  class MainEditorBlockComponent {
1246
1352
  constructor() {
1247
- this.textTags = TextMethods.textTags;
1353
+ this.textTags = TextTags.allTextTags;
1248
1354
  this.onTagSaved = new EventEmitter();
1249
1355
  this.onTagRemoved = new EventEmitter();
1250
1356
  }
@@ -1260,12 +1366,12 @@ class MainEditorBlockComponent {
1260
1366
  ngOnInit() {
1261
1367
  }
1262
1368
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: MainEditorBlockComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1263
- 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"] }] }); }
1264
1370
  }
1265
1371
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: MainEditorBlockComponent, decorators: [{
1266
1372
  type: Component,
1267
- 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>" }]
1268
- }], 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: [{
1269
1375
  type: Input
1270
1376
  }], onTagSaved: [{
1271
1377
  type: Output
@@ -1273,6 +1379,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImpor
1273
1379
  type: Output
1274
1380
  }] } });
1275
1381
 
1382
+ const defaultLinkYouTube = "https://youtu.be/jzBneaWSswY";
1383
+ const defaultLinkVk = "https://vk.com/video_ext.php?oid=-22822305&id=456241864&hd=2";
1276
1384
  class VisualEditorComponent {
1277
1385
  isHtmlSet() {
1278
1386
  return this.html.startsWith("<body>");
@@ -1298,6 +1406,8 @@ class VisualEditorComponent {
1298
1406
  this.alignmentOptions = AlignmentsData;
1299
1407
  this.showMarkUp = true;
1300
1408
  this.tags = [];
1409
+ this.videoPlayers = ExternalVideoPlayers;
1410
+ this.ExternalVideoTagDataConsts = ExternalVideoTagDataConsts;
1301
1411
  this.useHtmlRaw = false;
1302
1412
  this.html = "";
1303
1413
  this.onHtmlChanged = new EventEmitter();
@@ -1316,13 +1426,13 @@ class VisualEditorComponent {
1316
1426
  .find(x => x.tag === this.selectedValue);
1317
1427
  let attrs = {};
1318
1428
  let innerHtml = "";
1319
- if (TextMethods.textTags.includes(tagDescription.tag)) {
1429
+ if (TextTags.allTextTags.includes(tagDescription.tag)) {
1320
1430
  attrs["h-align"] = EAlignments.Left;
1321
1431
  innerHtml = "Введите ваш текст";
1322
1432
  }
1323
1433
  else if (tagDescription.tag == ExternalVideoTagDataConsts.TagName) {
1324
- attrs[ExternalVideoTagDataConsts.VideoTypeAttrName] = ExternalVideoSupportedTypes.Youtube;
1325
- attrs[ExternalVideoTagDataConsts.LinkAttrName] = null;
1434
+ attrs[ExternalVideoTagDataConsts.VideoTypeAttrName] = this.selectedVideoPlayer;
1435
+ attrs[ExternalVideoTagDataConsts.LinkAttrName] = this.selectedVideoPlayer === ExternalVideoSupportedTypes.VkVideo ? defaultLinkVk : defaultLinkYouTube;
1326
1436
  }
1327
1437
  else {
1328
1438
  attrs[FileImageTagDataConsts.FileIdAttrName] = null;
@@ -1412,13 +1522,14 @@ class VisualEditorComponent {
1412
1522
  this.recalculateBodyTags();
1413
1523
  this.tags = DefaultTags.getTags(this.useHtmlRaw);
1414
1524
  this.selectedValue = this.tags[0].tag;
1525
+ this.selectedVideoPlayer = this.videoPlayers[0].type;
1415
1526
  }
1416
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 }); }
1417
- 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"] }] }); }
1418
1529
  }
1419
1530
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: VisualEditorComponent, decorators: [{
1420
1531
  type: Component,
1421
- 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"] }]
1422
1533
  }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: undefined, decorators: [{
1423
1534
  type: Inject,
1424
1535
  args: [CrocoHtmlOptionsToken]
@@ -1499,13 +1610,13 @@ class MainEditorComponent {
1499
1610
  ngOnInit() {
1500
1611
  this.visualEditor.recalculateBodyTags();
1501
1612
  }
1502
- 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 }); }
1503
- 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" }] }); }
1504
1615
  }
1505
1616
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: MainEditorComponent, decorators: [{
1506
1617
  type: Component,
1507
- 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"] }]
1508
- }], 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: [{
1509
1620
  type: ViewChild,
1510
1621
  args: ["visualEditor", { static: true }]
1511
1622
  }], showMarkUp: [{
@@ -1551,11 +1662,11 @@ class XmlTagRichTextViewComponent {
1551
1662
  ngOnInit() {
1552
1663
  }
1553
1664
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: XmlTagRichTextViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1554
- 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" }] }); }
1555
1666
  }
1556
1667
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: XmlTagRichTextViewComponent, decorators: [{
1557
1668
  type: Component,
1558
- 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}" }]
1559
1670
  }], ctorParameters: () => [], propDecorators: { richTextData: [{
1560
1671
  type: Input
1561
1672
  }] } });
@@ -1565,11 +1676,11 @@ class XmlTagTableViewComponent {
1565
1676
  this.displayedColumns = [];
1566
1677
  }
1567
1678
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: XmlTagTableViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1568
- 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"] }] }); }
1569
1680
  }
1570
1681
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: XmlTagTableViewComponent, decorators: [{
1571
1682
  type: Component,
1572
- 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>" }]
1573
1684
  }], propDecorators: { displayedColumns: [{
1574
1685
  type: Input
1575
1686
  }], data: [{
@@ -1644,40 +1755,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImpor
1644
1755
  args: [CrocoHtmlOptionsToken]
1645
1756
  }] }] });
1646
1757
 
1647
- class TableBuilder {
1648
- static getTableMarkUp(rows, cols, generateHeaders) {
1649
- rows = +rows;
1650
- cols = +cols;
1651
- let result = "<table>";
1652
- if (generateHeaders) {
1653
- result += TableBuilder.getTableHeaderMarkUp(cols);
1654
- }
1655
- result += TableBuilder.getTableBodyMarkUp(cols, rows);
1656
- result += "</table>";
1657
- return XmlExtensions.formatXml(result);
1658
- }
1659
- static getTableHeaderMarkUp(cols) {
1660
- let result = "<thead><tr>";
1661
- for (let i = 0; i < cols; i++) {
1662
- result += `<th>Колонка #${i + 1}</th>`;
1663
- }
1664
- result += "</tr></thead>";
1665
- return result;
1666
- }
1667
- static getTableBodyMarkUp(cols, rows) {
1668
- let result = "<tbody>";
1669
- for (let row = 0; row < rows; row++) {
1670
- result += "<tr>";
1671
- for (let i = 0; i < cols; i++) {
1672
- result += `<td>Ряд№${row + 1} Колонка #${i + 1}</td>`;
1673
- }
1674
- result += "</tr>";
1675
- }
1676
- result += "</tbody>";
1677
- return result;
1678
- }
1679
- }
1680
-
1681
1758
  const EditorComponents = [
1682
1759
  MainEditorComponent,
1683
1760
  FileIdSelectComponent,
@@ -1753,7 +1830,8 @@ class CrocoHtmlModule {
1753
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,
1754
1831
  FormsModule,
1755
1832
  ReactiveFormsModule,
1756
- 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] }); }
1757
1835
  static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: CrocoHtmlModule, imports: [CommonModule,
1758
1836
  FormsModule,
1759
1837
  ReactiveFormsModule,
@@ -1774,7 +1852,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImpor
1774
1852
  ReactiveFormsModule,
1775
1853
  NgSelectModule,
1776
1854
  ...MaterialModules,
1777
- YouTubePlayerModule
1855
+ YouTubePlayerModule,
1856
+ VkVideoPlayerComponent
1778
1857
  ]
1779
1858
  }]
1780
1859
  }] });
@@ -1787,5 +1866,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImpor
1787
1866
  * Generated bundle index. Do not edit.
1788
1867
  */
1789
1868
 
1790
- 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 };
1791
1870
  //# sourceMappingURL=croco-html.mjs.map