croco-html 4.1.0 → 4.2.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 (28) hide show
  1. package/fesm2022/croco-html.mjs +681 -608
  2. package/fesm2022/croco-html.mjs.map +1 -1
  3. package/lib/components/editor/image-editor/image-editor.component.d.ts +2 -2
  4. package/lib/components/editor/text-editor/text-editor.component.d.ts +2 -4
  5. package/lib/components/editor/visual-editor/DefaultAligments.d.ts +2 -6
  6. package/lib/components/editor/visual-editor/visual-editor.component.d.ts +3 -6
  7. package/lib/components/html-view/html-view.component.d.ts +1 -1
  8. package/lib/components/upload-files-btn/upload-files-btn.component.d.ts +4 -4
  9. package/lib/components/xml-tags/file-image-tag-view/file-image-tag-view.component.d.ts +3 -3
  10. package/lib/components/xml-tags/index.d.ts +0 -1
  11. package/lib/components/xml-tags/xml-tag-view/xml-tag-view.component.d.ts +4 -0
  12. package/lib/croco-html.module.d.ts +23 -24
  13. package/lib/extensions/ImageMethods.d.ts +5 -5
  14. package/lib/extensions/InterfaceBlock.d.ts +1 -1
  15. package/lib/extensions/TextSimpleMethods.d.ts +1 -4
  16. package/lib/index.d.ts +2 -3
  17. package/lib/models/image-models.d.ts +2 -2
  18. package/lib/options/index.d.ts +23 -10
  19. package/lib/tag-services/ButtonTagService.d.ts +2 -1
  20. package/lib/tag-services/CustomWidgetTagService.d.ts +2 -1
  21. package/lib/tag-services/DownloadButtonTagService.d.ts +2 -1
  22. package/lib/tag-services/ExternalVideoTagService.d.ts +2 -1
  23. package/lib/tag-services/FileImageTagService.d.ts +1 -0
  24. package/lib/tag-services/HtmlRawTagService.d.ts +2 -1
  25. package/lib/tag-services/IMarkUpTagService.d.ts +9 -0
  26. package/lib/tag-services/TextTagHtmlMarkupTagService.d.ts +10 -1
  27. package/package.json +1 -1
  28. package/lib/components/xml-tags/xml-tag-table-view/xml-tag-table-view.component.d.ts +0 -7
@@ -8,8 +8,6 @@ import { MatFormFieldModule, MatFormField, MatLabel } from '@angular/material/fo
8
8
  import * as i1$4 from '@angular/forms';
9
9
  import { FormsModule, ReactiveFormsModule } from '@angular/forms';
10
10
  import * as i1$1 from '@angular/platform-browser';
11
- import * as i2$4 from '@angular/material/table';
12
- import { MatTable, MatColumnDef, MatHeaderCellDef, MatHeaderCell, MatCellDef, MatCell, MatHeaderRowDef, MatHeaderRow, MatRowDef, MatRow, MatTableModule } from '@angular/material/table';
13
11
  import * as i27 from '@angular/material/icon';
14
12
  import { MatIcon, MatIconModule } from '@angular/material/icon';
15
13
  import * as i1$2 from '@angular/material/card';
@@ -65,6 +63,8 @@ import * as i6 from '@angular/material/progress-bar';
65
63
  import { MatProgressBarModule } from '@angular/material/progress-bar';
66
64
  import * as i26 from '@angular/material/sidenav';
67
65
  import { MatSidenavModule } from '@angular/material/sidenav';
66
+ import * as i2$4 from '@angular/material/table';
67
+ import { MatTableModule } from '@angular/material/table';
68
68
  import * as i23 from '@angular/material/tree';
69
69
  import { MatTreeModule } from '@angular/material/tree';
70
70
  import * as i1$6 from '@angular/material/badge';
@@ -150,8 +150,8 @@ class ImageMethods {
150
150
  return null;
151
151
  }
152
152
  const format = ImageMethods.isPrivateFileId(fileId)
153
- ? options.publicImageResizedUrlFormat
154
- : options.privateImageResizedUrlFormat;
153
+ ? options.imageOptions.publicImageResizedUrlFormat
154
+ : options.imageOptions.privateImageResizedUrlFormat;
155
155
  return format
156
156
  .replace("{sizeType}", sizeType)
157
157
  .replace("{fileId}", fileId);
@@ -223,314 +223,338 @@ class ImageMethods {
223
223
  }
224
224
  }
225
225
 
226
- var EAlignments;
227
- (function (EAlignments) {
228
- EAlignments["Left"] = "left";
229
- EAlignments["Center"] = "center";
230
- EAlignments["Right"] = "right";
231
- })(EAlignments || (EAlignments = {}));
232
- const AlignmentsData = [
233
- { value: EAlignments.Left, text: 'Слева' },
234
- { value: EAlignments.Center, text: 'По центру' },
235
- { value: EAlignments.Right, text: 'Справа' },
236
- ];
237
-
238
- class TextTagDataConsts {
239
- static { this.HAlign = "h-align"; }
240
- }
241
- const TextTag = "text";
242
- class TextSimpleMethods {
243
- static { this.supportedTags = ["sup", "sub", "strong", "b", "i", "u"]; }
244
- static ExtractTextTag(elem) {
245
- var hAlignValue = elem.getAttribute("h-align") ?? EAlignments.Left;
246
- var data = {
247
- textTagName: elem.tagName.toLowerCase(),
248
- text: elem.innerText.trim().replace('\n\t', ''),
249
- html: elem.innerHTML.trim().replace('\n\t', ''),
250
- horizontalAlignment: hAlignValue,
251
- validationResult: {
252
- isSucceeded: true,
253
- message: "Ok"
254
- }
255
- };
256
- let result = {
257
- type: data.textTagName,
258
- data: data
259
- };
260
- if (result.data.text === '\n') {
261
- result.data.text = '';
262
- }
263
- if (result.data.html === '\n') {
264
- result.data.html = '';
265
- }
266
- var alignmentVals = [EAlignments.Left, EAlignments.Right, EAlignments.Center];
267
- if (alignmentVals.indexOf(hAlignValue) < 0) {
268
- result.data.validationResult = {
269
- isSucceeded: false,
270
- message: `Недопустимое значение атрибута h-align. Допустимые значения: ${alignmentVals.join(', ')}. `
271
- + 'Данный тег можно не указывать, по-умолчанию будет применено выравнивание слева.'
272
- };
226
+ class FileImageTagService {
227
+ constructor() {
228
+ this.tagName = FileImageTagDataConsts.TagName;
229
+ this.shortDescription = "Изображение";
230
+ }
231
+ bodyTagToHtmlStringConverter(bodyTag) {
232
+ let fileIdAttr = "";
233
+ let screenMediaRequestAttr = "";
234
+ if (bodyTag.attributes.hasOwnProperty(FileImageTagDataConsts.FileIdAttrName) && bodyTag.attributes[FileImageTagDataConsts.FileIdAttrName]) {
235
+ fileIdAttr = `${FileImageTagDataConsts.FileIdAttrName}="${bodyTag.attributes[FileImageTagDataConsts.FileIdAttrName]}"`;
273
236
  }
274
- var html = result.data.html;
275
- var htmlValidation = this.ValidateTextHtml(html);
276
- if (!htmlValidation.isSucceeded) {
277
- result.data.validationResult = htmlValidation;
237
+ if (bodyTag.attributes.hasOwnProperty(FileImageTagDataConsts.ScreenMediaRequest) && bodyTag.attributes[FileImageTagDataConsts.ScreenMediaRequest]) {
238
+ screenMediaRequestAttr = `${FileImageTagDataConsts.ScreenMediaRequest}="${bodyTag.attributes[FileImageTagDataConsts.ScreenMediaRequest]}"`;
278
239
  }
279
- return result;
240
+ return `<${FileImageTagDataConsts.TagName} ${fileIdAttr} ${screenMediaRequestAttr}></${FileImageTagDataConsts.TagName}>`;
280
241
  }
281
- static ValidateTextHtml(html) {
282
- var p = document.createElement("p");
283
- p.innerHTML = html;
284
- for (let i = 0; i < p.children.length; i++) {
285
- const element = p.children.item(i);
286
- var validationResult = this.ValidateTag(element);
287
- if (!validationResult.isSucceeded) {
288
- return validationResult;
289
- }
290
- }
242
+ extractBlockFromHtmlElement(elem, options) {
243
+ let fileId = elem.getAttribute(FileImageTagDataConsts.FileIdAttrName);
244
+ let src = ImageMethods.buildMediumUrl(fileId, options);
291
245
  return {
292
- isSucceeded: true,
293
- message: `Ok`
246
+ tagName: FileImageTagDataConsts.TagName,
247
+ data: {
248
+ src,
249
+ fileId: fileId,
250
+ screenMediaRequest: elem.getAttribute(FileImageTagDataConsts.ScreenMediaRequest)
251
+ }
294
252
  };
295
253
  }
296
- static ValidateTag(element) {
297
- let lowerTag = element.tagName.toLowerCase();
298
- if (!this.supportedTags.includes(lowerTag)) {
299
- return {
300
- isSucceeded: false,
301
- message: `Тег <${lowerTag}> не поддерживается внутри тега <text>`
302
- };
254
+ toBodyTag(data) {
255
+ let fileData = data.data;
256
+ let attrs = {};
257
+ if (fileData.fileId) {
258
+ attrs[FileImageTagDataConsts.FileIdAttrName] = fileData.fileId;
303
259
  }
304
- for (let i = 0; i < element.children.length; i++) {
305
- const nElement = element.children.item(i);
306
- var innerValidationResult = this.ValidateTag(nElement);
307
- if (!innerValidationResult.isSucceeded) {
308
- return innerValidationResult;
309
- }
260
+ if (fileData.screenMediaRequest) {
261
+ attrs[FileImageTagDataConsts.ScreenMediaRequest] = fileData.screenMediaRequest;
310
262
  }
311
263
  return {
312
- isSucceeded: true,
313
- message: "Ok"
264
+ presentOrEdit: true,
265
+ tagDescription: {
266
+ tag: FileImageTagDataConsts.TagName,
267
+ displayValue: this.shortDescription,
268
+ isCustom: false
269
+ },
270
+ attributes: attrs,
271
+ innerHtml: ""
272
+ };
273
+ }
274
+ getDefaultValue() {
275
+ return {
276
+ tagDescription: {
277
+ tag: this.tagName,
278
+ displayValue: this.shortDescription,
279
+ isCustom: false
280
+ },
281
+ attributes: {
282
+ [FileImageTagDataConsts.FileIdAttrName]: null,
283
+ [FileImageTagDataConsts.ScreenMediaRequest]: FileImageTagDataConsts.DefaultValueForFileImage
284
+ },
285
+ presentOrEdit: false,
286
+ innerHtml: "",
314
287
  };
315
288
  }
316
289
  }
317
290
 
318
- class BootstrapTableMethods {
319
- static BuildTable(data) {
320
- let result = `<table class="table table-bordered">`;
321
- result += this.BuildHeader(data.header);
322
- result += this.BuildBody(data.rows);
323
- result += "</table>";
324
- return result;
291
+ var TextAlignment;
292
+ (function (TextAlignment) {
293
+ TextAlignment["Left"] = "left";
294
+ TextAlignment["Center"] = "center";
295
+ TextAlignment["Right"] = "right";
296
+ })(TextAlignment || (TextAlignment = {}));
297
+ class TextTagDataConsts {
298
+ static { this.HAlign = "h-align"; }
299
+ }
300
+ class TextTagHtmlMarkupTagService {
301
+ constructor(tagName, shortDescription) {
302
+ this.tagName = "text";
303
+ this.shortDescription = "T";
304
+ this.tagName = tagName;
305
+ this.shortDescription = shortDescription;
325
306
  }
326
- static BuildHeader(data) {
327
- if (data === null) {
328
- return "";
329
- }
330
- let result = "<thead>";
331
- result += "<tr>";
332
- for (let index = 0; index < data.columns.length; index++) {
333
- result += `<th>${data.columns[index]}</th>`;
334
- }
335
- result += "</tr>";
336
- result += "</thead>";
337
- return result;
307
+ bodyTagToHtmlStringConverter(bodyTag) {
308
+ return `<${this.tagName} h-align="${bodyTag.attributes[TextTagDataConsts.HAlign]}">${bodyTag.innerHtml}</${this.tagName}>`;
338
309
  }
339
- static BuildBody(rows) {
340
- let result = "<tbody>";
341
- for (let i = 0; i < rows.length; i++) {
342
- const row = rows[i];
343
- result += "<tr>";
344
- for (let j = 0; j < row.columns.length; j++) {
345
- const col = row.columns[j];
346
- result += `<td class="align-middle">${this.BuildInnerTags(col.data.children)}</td>`;
347
- }
348
- result += "</tr>";
349
- }
350
- result += "</tbody>";
351
- return result;
310
+ extractBlockFromHtmlElement(elem, options) {
311
+ return TextSimpleMethods.ExtractTextTag(elem);
352
312
  }
353
- static BuildInnerTags(tags) {
354
- let result = "";
355
- for (let i = 0; i < tags.length; i++) {
356
- result += this.BuildInnerTag(tags[i]);
357
- }
358
- return result;
313
+ toBodyTag(data) {
314
+ let textTagData = data.data;
315
+ return {
316
+ presentOrEdit: true,
317
+ tagDescription: {
318
+ tag: this.tagName,
319
+ displayValue: this.shortDescription,
320
+ isCustom: false
321
+ },
322
+ attributes: { [TextTagDataConsts.HAlign]: textTagData.horizontalAlignment },
323
+ innerHtml: BodyTagsExtensions.sanitizeInnerHtml(textTagData.html)
324
+ };
359
325
  }
360
- static BuildInnerTag(data) {
361
- if (data.type === FileImageTagDataConsts.TagName) {
362
- let fileImageTag = data;
363
- return `<img src=${fileImageTag.data.src} class="mx-auto d-block img-fluid" />`;
364
- }
365
- else if (data.type === TextTag) {
366
- let simpleTextTag = data;
367
- var map = {
368
- ["left"]: "text-start",
369
- ["center"]: "text-center",
370
- ["right"]: "text-end"
371
- };
372
- if (!simpleTextTag.data.validationResult.isSucceeded) {
373
- return `<span>Ошибка в тексте ${simpleTextTag.data.validationResult.message}</span>`;
374
- }
375
- return `<div class="${map[simpleTextTag.data.horizontalAlignment]}"><span>${simpleTextTag.data.html}</span></div>`;
376
- }
377
- else {
378
- return `<p>Тег ${data.type} не поддерживается</p>`;
379
- }
326
+ getDefaultValue(props) {
327
+ return {
328
+ tagDescription: {
329
+ tag: this.tagName,
330
+ displayValue: this.shortDescription,
331
+ isCustom: false
332
+ },
333
+ attributes: {
334
+ [TextTagDataConsts.HAlign]: TextAlignment.Left
335
+ },
336
+ presentOrEdit: false,
337
+ innerHtml: "",
338
+ };
380
339
  }
381
340
  }
382
341
 
383
- class TableTypes {
384
- static { this.TableRowColumnData = "table-row-column-data"; }
385
- static { this.Table = "table"; }
386
- static { this.TableRowColumn = "table-row-column"; }
387
- }
388
- class TableMethods {
389
- static getTableFromHtmlTag(tableTag, options) {
390
- let tableData = {
391
- header: TableMethods.getHeader(tableTag),
392
- rows: TableMethods.getTableRows(tableTag, options)
393
- };
394
- var result = {
395
- type: TableTypes.Table,
396
- data: tableData,
397
- validationResult: this.checkTable(tableData),
398
- bootstrapHtml: ""
399
- };
400
- if (!result.validationResult) {
401
- return result;
402
- }
403
- result.bootstrapHtml = BootstrapTableMethods.BuildTable(result.data);
404
- var angularMaterialTableDataCheck = AngularMaterialTableMethods.checkAngularMaterialTableData(tableData);
405
- if (!angularMaterialTableDataCheck.isSucceeded) {
406
- return {
407
- ...result,
408
- angularMaterialTableDataCheck
409
- };
342
+ const defaultLinkYouTube = "https://www.youtube.com/embed/4CtSAnJDfsI?si=scyBNJa0Hs2t5aLE";
343
+ const defaultLinkVk = "https://vk.com/video_ext.php?oid=-22822305&id=456241864&hd=2";
344
+ class ExternalVideoTagService {
345
+ constructor() {
346
+ this.tagName = ExternalVideoTagDataConsts.TagName;
347
+ this.shortDescription = "Видео";
348
+ }
349
+ bodyTagToHtmlStringConverter(bodyTag) {
350
+ let useResponsiveWrapperAttr = '';
351
+ if (bodyTag.attributes[ExternalVideoTagDataConsts.VideoTypeAttrName] === ExternalVideoSupportedTypes.Code) {
352
+ useResponsiveWrapperAttr = `${ExternalVideoTagDataConsts.UseResponsiveWrapperAttrName}="${bodyTag.attributes[ExternalVideoTagDataConsts.UseResponsiveWrapperAttrName] || false}"`;
410
353
  }
354
+ return `<${bodyTag.tagDescription.tag} ${useResponsiveWrapperAttr} type="${bodyTag.attributes[ExternalVideoTagDataConsts.VideoTypeAttrName]}" link="${bodyTag.attributes[ExternalVideoTagDataConsts.LinkAttrName]}">${bodyTag.innerHtml}</${bodyTag.tagDescription.tag}>`;
355
+ }
356
+ extractBlockFromHtmlElement(elem, options) {
411
357
  return {
412
- ...result,
413
- angularMaterialTableDataCheck,
414
- html: tableTag.outerHTML,
415
- angularMaterialTableData: AngularMaterialTableMethods.getAngularMaterialTableData(tableData.header.columns, tableData.rows),
358
+ tagName: ExternalVideoTagDataConsts.TagName,
359
+ data: {
360
+ type: elem.getAttribute(ExternalVideoTagDataConsts.VideoTypeAttrName),
361
+ link: elem.getAttribute(ExternalVideoTagDataConsts.LinkAttrName),
362
+ useResponsiveWrapper: elem.getAttribute(ExternalVideoTagDataConsts.UseResponsiveWrapperAttrName) !== 'false',
363
+ innerHtml: elem.innerHTML
364
+ }
416
365
  };
417
366
  }
418
- static checkTable(tableData) {
419
- let rows = tableData.rows;
420
- let prevRowCount = -1;
421
- for (let i = 0; i < rows.length; i++) {
422
- const row = rows[i];
423
- if (row.columns.length !== prevRowCount && prevRowCount != -1) {
424
- return {
425
- isSucceeded: false,
426
- message: `Ошибка при обработке разметки таблицы. `
427
- + `Количество колонок в каждой строке таблицы должно соотвествовать друг другу. `
428
- + `В строке таблицы №${i + 1} количество колонок = ${row.columns.length}, а в строке выше ${prevRowCount}.`
429
- };
430
- }
431
- prevRowCount = row.columns.length;
432
- }
367
+ toBodyTag(data) {
368
+ let fileData = data.data;
433
369
  return {
434
- isSucceeded: true,
435
- message: "Ok"
370
+ presentOrEdit: true,
371
+ tagDescription: {
372
+ tag: data.tagName,
373
+ displayValue: this.shortDescription,
374
+ isCustom: false
375
+ },
376
+ attributes: fileData,
377
+ innerHtml: ""
436
378
  };
437
379
  }
438
- static getHeader(tableTag) {
439
- let header = tableTag.tHead;
440
- if (header === null) {
441
- return null;
442
- }
443
- let tr = header.children.item(0);
444
- let headerColumns = [];
445
- for (let j = 0; j < tr.children.length; j++) {
446
- const jElement = tr.children.item(j);
447
- headerColumns.push(jElement.innerHTML);
380
+ getDefaultValue(props) {
381
+ let attrs = {};
382
+ let innerHtml = "";
383
+ attrs[ExternalVideoTagDataConsts.VideoTypeAttrName] = props.selectedVideoPlayer;
384
+ attrs[ExternalVideoTagDataConsts.UseResponsiveWrapperAttrName] = false;
385
+ attrs[ExternalVideoTagDataConsts.LinkAttrName] = props.selectedVideoPlayer === ExternalVideoSupportedTypes.Code ? '' :
386
+ props.selectedVideoPlayer === ExternalVideoSupportedTypes.VkVideo
387
+ ? defaultLinkVk
388
+ : defaultLinkYouTube;
389
+ if (props.selectedVideoPlayer === ExternalVideoSupportedTypes.Code) {
390
+ innerHtml = props.htmlRaw;
448
391
  }
449
392
  return {
450
- type: "table-header",
451
- columns: headerColumns
393
+ tagDescription: {
394
+ tag: this.tagName,
395
+ displayValue: this.shortDescription,
396
+ isCustom: false
397
+ },
398
+ attributes: attrs,
399
+ presentOrEdit: false,
400
+ innerHtml: "",
452
401
  };
453
402
  }
454
- static getTableRows(tableTag, options) {
455
- let tBody = tableTag.tBodies.item(0);
456
- let rows = [];
457
- for (let i = 0; i < tBody.children.length; i++) {
458
- const iElement = tBody.children.item(i);
459
- let rowColumns = [];
460
- for (let j = 0; j < iElement.children.length; j++) {
461
- const jElement = iElement.children.item(j);
462
- let children = HtmlExtractionMethods.transformHtmlElementToBlocks(jElement, options);
463
- if (children.length === 0) {
464
- var textTag = document.createElement("p");
465
- textTag.innerHTML = jElement.innerHTML;
466
- var textElem = TextSimpleMethods.ExtractTextTag(textTag);
467
- children.push(textElem);
468
- }
469
- var result = {
470
- type: TableTypes.TableRowColumnData,
471
- data: {
472
- text: jElement.innerHTML,
473
- children
474
- }
475
- };
476
- rowColumns.push(result);
403
+ }
404
+
405
+ class HtmlRawTagDataConsts {
406
+ static { this.TagName = "html-raw"; }
407
+ }
408
+
409
+ class HtmlRawTagService {
410
+ constructor() {
411
+ this.tagName = HtmlRawTagDataConsts.TagName;
412
+ this.shortDescription = "Разметка";
413
+ }
414
+ bodyTagToHtmlStringConverter(bodyTag) {
415
+ return `<${this.tagName}>${bodyTag.innerHtml}</${this.tagName}>`;
416
+ }
417
+ extractBlockFromHtmlElement(elem, options) {
418
+ return {
419
+ tagName: HtmlRawTagDataConsts.TagName,
420
+ data: {
421
+ innerHTML: elem.innerHTML
477
422
  }
478
- rows.push({
479
- type: TableTypes.TableRowColumn,
480
- columns: rowColumns
481
- });
482
- }
483
- return rows;
423
+ };
424
+ }
425
+ toBodyTag(data) {
426
+ return {
427
+ presentOrEdit: true,
428
+ tagDescription: {
429
+ tag: HtmlRawTagDataConsts.TagName,
430
+ displayValue: this.shortDescription,
431
+ isCustom: false
432
+ },
433
+ attributes: {},
434
+ innerHtml: BodyTagsExtensions.sanitizeInnerHtml(data.data["innerHTML"])
435
+ };
436
+ }
437
+ getDefaultValue(props) {
438
+ return {
439
+ tagDescription: {
440
+ tag: this.tagName,
441
+ displayValue: this.shortDescription,
442
+ isCustom: false
443
+ },
444
+ attributes: {},
445
+ presentOrEdit: false,
446
+ innerHtml: props.htmlRaw,
447
+ };
484
448
  }
485
449
  }
486
450
 
487
- class HtmlExtractionMethods {
488
- // TODO удалить в пользу BodyTagsExtensions
489
- static { this.Extractors = {
490
- [TableTypes.Table]: (elem, options) => TableMethods.getTableFromHtmlTag(elem, options),
491
- }; }
492
- static transformHtmlElementToBlocks(element, options) {
493
- var data = [];
494
- for (let i = 0; i < element.children.length; i++) {
495
- var elem = element.children.item(i);
496
- var loweredTagName = elem.tagName.toLowerCase();
497
- if (BodyTagsExtensions.tagServices.hasOwnProperty(loweredTagName)) {
498
- var tagService = BodyTagsExtensions.tagServices[loweredTagName];
499
- var resultBlock = tagService.extractBlockFromHtmlElement(elem, options);
500
- data.push(resultBlock);
501
- continue;
502
- }
503
- if (!HtmlExtractionMethods.Extractors.hasOwnProperty(loweredTagName)) {
504
- data.push({
505
- type: "unsupported-tag",
506
- data: {
507
- tagString: elem.outerHTML
508
- }
509
- });
510
- }
511
- else {
512
- var extractor = HtmlExtractionMethods.Extractors[loweredTagName];
513
- var result = extractor(elem, options);
514
- data.push(result);
451
+ const defaultLinkForDownload = "https://storage.yandexcloud.net/mega-academy/presentation.pdf";
452
+ class DownloadButtonTagDataConsts {
453
+ static { this.TagName = "download-file-button"; }
454
+ static { this.TitleAttrName = "title"; }
455
+ static { this.LinkAttrName = "link"; }
456
+ }
457
+ class DownloadButtonTagService {
458
+ constructor() {
459
+ this.tagName = DownloadButtonTagDataConsts.TagName;
460
+ this.shortDescription = "Кнопка для скачивания";
461
+ }
462
+ bodyTagToHtmlStringConverter(bodyTag) {
463
+ return `<${this.tagName} title="${bodyTag.attributes[DownloadButtonTagDataConsts.TitleAttrName]}" link="${bodyTag.attributes[DownloadButtonTagDataConsts.LinkAttrName]}"></${this.tagName}>`;
464
+ }
465
+ extractBlockFromHtmlElement(elem, options) {
466
+ return {
467
+ tagName: DownloadButtonTagDataConsts.TagName,
468
+ data: {
469
+ title: elem.getAttribute(DownloadButtonTagDataConsts.TitleAttrName),
470
+ link: elem.getAttribute(DownloadButtonTagDataConsts.LinkAttrName)
515
471
  }
516
- }
517
- return data;
472
+ };
518
473
  }
519
- static transformHtmlStringToBlocks(value, options) {
520
- if (value === undefined || value === null) {
521
- return [];
522
- }
523
- value = value
524
- .replace('\n', '')
525
- .replace('\t', '');
526
- var div = document.createElement("div");
527
- div.innerHTML = value;
528
- return this.transformHtmlElementToBlocks(div, options);
474
+ toBodyTag(data) {
475
+ let fileData = data.data;
476
+ return {
477
+ presentOrEdit: true,
478
+ tagDescription: {
479
+ tag: data.tagName,
480
+ displayValue: this.shortDescription,
481
+ isCustom: false
482
+ },
483
+ attributes: fileData,
484
+ innerHtml: ""
485
+ };
486
+ }
487
+ getDefaultValue(props) {
488
+ return {
489
+ tagDescription: {
490
+ tag: this.tagName,
491
+ displayValue: this.shortDescription,
492
+ isCustom: false
493
+ },
494
+ attributes: {
495
+ [DownloadButtonTagDataConsts.LinkAttrName]: defaultLinkForDownload,
496
+ [DownloadButtonTagDataConsts.TitleAttrName]: 'Скачать'
497
+ },
498
+ presentOrEdit: false,
499
+ innerHtml: props.htmlRaw,
500
+ };
529
501
  }
530
502
  }
531
503
 
532
- class HtmlRawTagDataConsts {
533
- static { this.TagName = "html-raw"; }
504
+ class ButtonTagDataConsts {
505
+ static { this.TagName = "button"; }
506
+ static { this.TextAttrName = "text"; }
507
+ static { this.TypeAttrName = "type"; }
508
+ static { this.ClickAttrName = "click"; }
509
+ }
510
+ class ButtonTagService {
511
+ constructor() {
512
+ this.tagName = ButtonTagDataConsts.TagName;
513
+ this.shortDescription = "Кнопка";
514
+ }
515
+ bodyTagToHtmlStringConverter(bodyTag) {
516
+ let atts = bodyTag.attributes;
517
+ return `<${this.tagName} text="${atts[ButtonTagDataConsts.TextAttrName]}" type="${atts[ButtonTagDataConsts.TypeAttrName]}" click="${atts[ButtonTagDataConsts.ClickAttrName]}"></${this.tagName}>`;
518
+ }
519
+ extractBlockFromHtmlElement(elem, options) {
520
+ return {
521
+ tagName: ButtonTagDataConsts.TagName,
522
+ data: {
523
+ text: elem.getAttribute(ButtonTagDataConsts.TextAttrName),
524
+ type: elem.getAttribute(ButtonTagDataConsts.TypeAttrName),
525
+ click: elem.getAttribute(ButtonTagDataConsts.ClickAttrName)
526
+ }
527
+ };
528
+ }
529
+ toBodyTag(data) {
530
+ let fileData = data.data;
531
+ return {
532
+ presentOrEdit: true,
533
+ tagDescription: {
534
+ tag: data.tagName,
535
+ displayValue: this.shortDescription,
536
+ isCustom: false
537
+ },
538
+ attributes: fileData,
539
+ innerHtml: ""
540
+ };
541
+ }
542
+ getDefaultValue(props) {
543
+ return {
544
+ tagDescription: {
545
+ tag: this.tagName,
546
+ displayValue: this.shortDescription,
547
+ isCustom: false
548
+ },
549
+ attributes: {
550
+ [ButtonTagDataConsts.ClickAttrName]: '',
551
+ [ButtonTagDataConsts.TypeAttrName]: 'button',
552
+ [ButtonTagDataConsts.TextAttrName]: 'Кнопка'
553
+ },
554
+ presentOrEdit: false,
555
+ innerHtml: props.htmlRaw,
556
+ };
557
+ }
534
558
  }
535
559
 
536
560
  class CustomWidgetTagDataConsts {
@@ -550,7 +574,7 @@ class CustomWidgetTagService {
550
574
  }
551
575
  extractBlockFromHtmlElement(elem, options) {
552
576
  return {
553
- type: CustomWidgetTagDataConsts.TagName,
577
+ tagName: CustomWidgetTagDataConsts.TagName,
554
578
  data: {
555
579
  type: elem.getAttribute(CustomWidgetTagDataConsts.TypeAttrName),
556
580
  dataId: elem.getAttribute(CustomWidgetTagDataConsts.DataIdAttrName),
@@ -563,7 +587,7 @@ class CustomWidgetTagService {
563
587
  return {
564
588
  presentOrEdit: true,
565
589
  tagDescription: {
566
- tag: data.type,
590
+ tag: data.tagName,
567
591
  displayValue: this.shortDescription,
568
592
  isCustom: false
569
593
  },
@@ -571,6 +595,22 @@ class CustomWidgetTagService {
571
595
  innerHtml: ""
572
596
  };
573
597
  }
598
+ getDefaultValue(props) {
599
+ return {
600
+ tagDescription: {
601
+ tag: this.tagName,
602
+ displayValue: this.shortDescription,
603
+ isCustom: false
604
+ },
605
+ attributes: {
606
+ [CustomWidgetTagDataConsts.TypeAttrName]: 'example-type',
607
+ [CustomWidgetTagDataConsts.DataIdAttrName]: 'example-data-id',
608
+ [CustomWidgetTagDataConsts.WidgetIdAttrName]: 'example-widget-id'
609
+ },
610
+ presentOrEdit: false,
611
+ innerHtml: props.htmlRaw,
612
+ };
613
+ }
574
614
  static ExtractCustomWidgetTagData(attributes) {
575
615
  return {
576
616
  type: attributes[CustomWidgetTagDataConsts.TypeAttrName],
@@ -587,283 +627,351 @@ class CustomWidgetTagService {
587
627
  }
588
628
  }
589
629
 
590
- class TextTags {
591
- static { this.text = "text"; }
592
- static { this.h1 = "h1"; }
593
- static { this.h2 = "h2"; }
594
- static { this.h3 = "h3"; }
595
- static { this.h4 = "h4"; }
596
- static { this.h5 = "h5"; }
597
- static { this.h6 = "h6"; }
598
- static { this.headerTextTags = [TextTags.h1, TextTags.h2, TextTags.h3, TextTags.h4, TextTags.h5, TextTags.h6]; }
599
- static { this.allTextTags = [TextTags.text, ...TextTags.headerTextTags]; }
600
- }
601
-
602
- class ExternalVideoTagDataConsts {
603
- static { this.TagName = "external-video"; }
604
- static { this.VideoTypeAttrName = "type"; }
605
- static { this.LinkAttrName = "link"; }
606
- static { this.UseResponsiveWrapperAttrName = "use-responsive-wrapper"; }
607
- static { this.IframeAttrName = "iframe"; }
608
- }
609
- class ExternalVideoSupportedTypes {
610
- static { this.Youtube = "youtube"; }
611
- static { this.VkVideo = "vk-video"; }
612
- static { this.Code = "code"; }
613
- }
614
- const ExternalVideoPlayers = [
615
- {
616
- type: ExternalVideoSupportedTypes.Code,
617
- displayValue: 'Встраиваемое Видео',
618
- },
619
- {
620
- type: ExternalVideoSupportedTypes.Youtube,
621
- displayValue: 'Youtube',
622
- },
623
- {
624
- type: ExternalVideoSupportedTypes.VkVideo,
625
- displayValue: 'Vk Video',
626
- }
627
- ];
628
-
629
- class Tags {
630
- static { this.Text = TextTags.text; }
631
- static { this.H1 = TextTags.h1; }
632
- static { this.H2 = TextTags.h2; }
633
- static { this.H3 = TextTags.h3; }
634
- static { this.H4 = TextTags.h4; }
635
- static { this.H5 = TextTags.h5; }
636
- static { this.H6 = TextTags.h6; }
637
- static { this.HtmlRaw = HtmlRawTagDataConsts.TagName; }
638
- static { this.FileImage = FileImageTagDataConsts.TagName; }
639
- static { this.Table = 'table'; }
640
- static { this.RichText = 'rich-text'; }
641
- static { this.ExternalVideo = ExternalVideoTagDataConsts.TagName; }
642
- static { this.UnsupportedTag = 'unsupported-tag'; }
643
- static { this.CustomWidget = CustomWidgetTagDataConsts.TagName; }
644
- }
645
-
646
- class FileImageTagService {
647
- constructor() {
648
- this.tagName = FileImageTagDataConsts.TagName;
649
- this.shortDescription = "Изображение";
650
- }
651
- bodyTagToHtmlStringConverter(bodyTag) {
652
- let fileIdAttr = "";
653
- let screenMediaRequestAttr = "";
654
- if (bodyTag.attributes.hasOwnProperty(FileImageTagDataConsts.FileIdAttrName) && bodyTag.attributes[FileImageTagDataConsts.FileIdAttrName]) {
655
- fileIdAttr = `${FileImageTagDataConsts.FileIdAttrName}="${bodyTag.attributes[FileImageTagDataConsts.FileIdAttrName]}"`;
630
+ const TextTag = "text";
631
+ class TextSimpleMethods {
632
+ static { this.supportedTags = ["sup", "sub", "strong", "b", "i", "u"]; }
633
+ static ExtractTextTag(elem) {
634
+ var hAlignValue = elem.getAttribute("h-align") ?? TextAlignment.Left;
635
+ var data = {
636
+ textTagName: elem.tagName.toLowerCase(),
637
+ text: elem.innerText.trim().replace('\n\t', ''),
638
+ html: elem.innerHTML.trim().replace('\n\t', ''),
639
+ horizontalAlignment: hAlignValue,
640
+ validationResult: {
641
+ isSucceeded: true,
642
+ message: "Ok"
643
+ }
644
+ };
645
+ let result = {
646
+ tagName: data.textTagName,
647
+ data: data
648
+ };
649
+ if (result.data.text === '\n') {
650
+ result.data.text = '';
656
651
  }
657
- if (bodyTag.attributes.hasOwnProperty(FileImageTagDataConsts.ScreenMediaRequest) && bodyTag.attributes[FileImageTagDataConsts.ScreenMediaRequest]) {
658
- screenMediaRequestAttr = `${FileImageTagDataConsts.ScreenMediaRequest}="${bodyTag.attributes[FileImageTagDataConsts.ScreenMediaRequest]}"`;
652
+ if (result.data.html === '\n') {
653
+ result.data.html = '';
659
654
  }
660
- return `<${FileImageTagDataConsts.TagName} ${fileIdAttr} ${screenMediaRequestAttr}></${FileImageTagDataConsts.TagName}>`;
655
+ var alignmentVals = [TextAlignment.Left, TextAlignment.Right, TextAlignment.Center];
656
+ if (alignmentVals.indexOf(hAlignValue) < 0) {
657
+ result.data.validationResult = {
658
+ isSucceeded: false,
659
+ message: `Недопустимое значение атрибута h-align. Допустимые значения: ${alignmentVals.join(', ')}. `
660
+ + 'Данный тег можно не указывать, по-умолчанию будет применено выравнивание слева.'
661
+ };
662
+ }
663
+ var html = result.data.html;
664
+ var htmlValidation = this.ValidateTextHtml(html);
665
+ if (!htmlValidation.isSucceeded) {
666
+ result.data.validationResult = htmlValidation;
667
+ }
668
+ return result;
661
669
  }
662
- extractBlockFromHtmlElement(elem, options) {
663
- let fileId = elem.getAttribute(FileImageTagDataConsts.FileIdAttrName);
664
- let src = ImageMethods.buildMediumUrl(fileId, options);
665
- return {
666
- type: FileImageTagDataConsts.TagName,
667
- data: {
668
- src,
669
- fileId: fileId,
670
- screenMediaRequest: elem.getAttribute(FileImageTagDataConsts.ScreenMediaRequest)
670
+ static ValidateTextHtml(html) {
671
+ var p = document.createElement("p");
672
+ p.innerHTML = html;
673
+ for (let i = 0; i < p.children.length; i++) {
674
+ const element = p.children.item(i);
675
+ var validationResult = this.ValidateTag(element);
676
+ if (!validationResult.isSucceeded) {
677
+ return validationResult;
671
678
  }
679
+ }
680
+ return {
681
+ isSucceeded: true,
682
+ message: `Ok`
672
683
  };
673
684
  }
674
- toBodyTag(data) {
675
- let fileData = data.data;
676
- let attrs = {};
677
- if (fileData.fileId) {
678
- attrs[FileImageTagDataConsts.FileIdAttrName] = fileData.fileId;
685
+ static ValidateTag(element) {
686
+ let lowerTag = element.tagName.toLowerCase();
687
+ if (!this.supportedTags.includes(lowerTag)) {
688
+ return {
689
+ isSucceeded: false,
690
+ message: `Тег <${lowerTag}> не поддерживается внутри тега <text>`
691
+ };
679
692
  }
680
- if (fileData.screenMediaRequest) {
681
- attrs[FileImageTagDataConsts.ScreenMediaRequest] = fileData.screenMediaRequest;
693
+ for (let i = 0; i < element.children.length; i++) {
694
+ const nElement = element.children.item(i);
695
+ var innerValidationResult = this.ValidateTag(nElement);
696
+ if (!innerValidationResult.isSucceeded) {
697
+ return innerValidationResult;
698
+ }
682
699
  }
683
700
  return {
684
- presentOrEdit: true,
685
- tagDescription: {
686
- tag: FileImageTagDataConsts.TagName,
687
- displayValue: this.shortDescription,
688
- isCustom: false
689
- },
690
- attributes: attrs,
691
- innerHtml: ""
701
+ isSucceeded: true,
702
+ message: "Ok"
692
703
  };
693
704
  }
694
705
  }
695
706
 
696
- class TextTagHtmlMarkupTagService {
697
- constructor(tagName, shortDescription) {
698
- this.tagName = "text";
699
- this.shortDescription = "T";
700
- this.tagName = tagName;
701
- this.shortDescription = shortDescription;
702
- }
703
- bodyTagToHtmlStringConverter(bodyTag) {
704
- return `<${this.tagName} h-align="${bodyTag.attributes[TextTagDataConsts.HAlign]}">${bodyTag.innerHtml}</${this.tagName}>`;
705
- }
706
- extractBlockFromHtmlElement(elem, options) {
707
- return TextSimpleMethods.ExtractTextTag(elem);
707
+ class BootstrapTableMethods {
708
+ static BuildTable(data) {
709
+ let result = `<table class="table table-bordered">`;
710
+ result += this.BuildHeader(data.header);
711
+ result += this.BuildBody(data.rows);
712
+ result += "</table>";
713
+ return result;
708
714
  }
709
- toBodyTag(data) {
710
- let textTagData = data.data;
711
- return {
712
- presentOrEdit: true,
713
- tagDescription: {
714
- tag: this.tagName,
715
- displayValue: this.shortDescription,
716
- isCustom: false
717
- },
718
- attributes: { "h-align": textTagData.horizontalAlignment },
719
- innerHtml: BodyTagsExtensions.sanitizeInnerHtml(textTagData.html)
720
- };
715
+ static BuildHeader(data) {
716
+ if (data === null) {
717
+ return "";
718
+ }
719
+ let result = "<thead>";
720
+ result += "<tr>";
721
+ for (let index = 0; index < data.columns.length; index++) {
722
+ result += `<th>${data.columns[index]}</th>`;
723
+ }
724
+ result += "</tr>";
725
+ result += "</thead>";
726
+ return result;
721
727
  }
722
- }
723
-
724
- class ExternalVideoTagService {
725
- constructor() {
726
- this.tagName = ExternalVideoTagDataConsts.TagName;
727
- this.shortDescription = "Видео";
728
+ static BuildBody(rows) {
729
+ let result = "<tbody>";
730
+ for (let i = 0; i < rows.length; i++) {
731
+ const row = rows[i];
732
+ result += "<tr>";
733
+ for (let j = 0; j < row.columns.length; j++) {
734
+ const col = row.columns[j];
735
+ result += `<td class="align-middle">${this.BuildInnerTags(col.data.children)}</td>`;
736
+ }
737
+ result += "</tr>";
738
+ }
739
+ result += "</tbody>";
740
+ return result;
728
741
  }
729
- bodyTagToHtmlStringConverter(bodyTag) {
730
- let useResponsiveWrapperAttr = '';
731
- if (bodyTag.attributes[ExternalVideoTagDataConsts.VideoTypeAttrName] === ExternalVideoSupportedTypes.Code) {
732
- useResponsiveWrapperAttr = `${ExternalVideoTagDataConsts.UseResponsiveWrapperAttrName}="${bodyTag.attributes[ExternalVideoTagDataConsts.UseResponsiveWrapperAttrName] || false}"`;
742
+ static BuildInnerTags(tags) {
743
+ let result = "";
744
+ for (let i = 0; i < tags.length; i++) {
745
+ result += this.BuildInnerTag(tags[i]);
733
746
  }
734
- return `<${bodyTag.tagDescription.tag} ${useResponsiveWrapperAttr} type="${bodyTag.attributes[ExternalVideoTagDataConsts.VideoTypeAttrName]}" link="${bodyTag.attributes[ExternalVideoTagDataConsts.LinkAttrName]}">${bodyTag.innerHtml}</${bodyTag.tagDescription.tag}>`;
747
+ return result;
735
748
  }
736
- extractBlockFromHtmlElement(elem, options) {
737
- return {
738
- type: ExternalVideoTagDataConsts.TagName,
739
- data: {
740
- type: elem.getAttribute(ExternalVideoTagDataConsts.VideoTypeAttrName),
741
- link: elem.getAttribute(ExternalVideoTagDataConsts.LinkAttrName),
742
- useResponsiveWrapper: elem.getAttribute(ExternalVideoTagDataConsts.UseResponsiveWrapperAttrName) !== 'false',
743
- innerHtml: elem.innerHTML
749
+ static BuildInnerTag(data) {
750
+ if (data.tagName === FileImageTagDataConsts.TagName) {
751
+ let fileImageTag = data;
752
+ return `<img src=${fileImageTag.data.src} class="mx-auto d-block img-fluid" />`;
753
+ }
754
+ else if (data.tagName === TextTag) {
755
+ let simpleTextTag = data;
756
+ var map = {
757
+ ["left"]: "text-start",
758
+ ["center"]: "text-center",
759
+ ["right"]: "text-end"
760
+ };
761
+ if (!simpleTextTag.data.validationResult.isSucceeded) {
762
+ return `<span>Ошибка в тексте ${simpleTextTag.data.validationResult.message}</span>`;
744
763
  }
745
- };
746
- }
747
- toBodyTag(data) {
748
- let fileData = data.data;
749
- return {
750
- presentOrEdit: true,
751
- tagDescription: {
752
- tag: data.type,
753
- displayValue: this.shortDescription,
754
- isCustom: false
755
- },
756
- attributes: fileData,
757
- innerHtml: ""
758
- };
764
+ return `<div class="${map[simpleTextTag.data.horizontalAlignment]}"><span>${simpleTextTag.data.html}</span></div>`;
765
+ }
766
+ else {
767
+ return `<p>Тег ${data.tagName} не поддерживается</p>`;
768
+ }
759
769
  }
760
770
  }
761
771
 
762
- class HtmlRawTagService {
763
- constructor() {
764
- this.tagName = HtmlRawTagDataConsts.TagName;
765
- this.shortDescription = "Разметка";
766
- }
767
- bodyTagToHtmlStringConverter(bodyTag) {
768
- return `<${this.tagName}>${bodyTag.innerHtml}</${this.tagName}>`;
769
- }
770
- extractBlockFromHtmlElement(elem, options) {
772
+ class TableTypes {
773
+ static { this.TableRowColumnData = "table-row-column-data"; }
774
+ static { this.Table = "table"; }
775
+ static { this.TableRowColumn = "table-row-column"; }
776
+ }
777
+ class TableMethods {
778
+ static getTableFromHtmlTag(tableTag, options) {
779
+ let tableData = {
780
+ header: TableMethods.getHeader(tableTag),
781
+ rows: TableMethods.getTableRows(tableTag, options)
782
+ };
783
+ var result = {
784
+ type: TableTypes.Table,
785
+ data: tableData,
786
+ validationResult: this.checkTable(tableData),
787
+ bootstrapHtml: ""
788
+ };
789
+ if (!result.validationResult) {
790
+ return result;
791
+ }
792
+ result.bootstrapHtml = BootstrapTableMethods.BuildTable(result.data);
793
+ var angularMaterialTableDataCheck = AngularMaterialTableMethods.checkAngularMaterialTableData(tableData);
794
+ if (!angularMaterialTableDataCheck.isSucceeded) {
795
+ return {
796
+ ...result,
797
+ angularMaterialTableDataCheck
798
+ };
799
+ }
771
800
  return {
772
- type: HtmlRawTagDataConsts.TagName,
773
- data: {
774
- innerHTML: elem.innerHTML
801
+ ...result,
802
+ angularMaterialTableDataCheck,
803
+ html: tableTag.outerHTML,
804
+ angularMaterialTableData: AngularMaterialTableMethods.getAngularMaterialTableData(tableData.header.columns, tableData.rows),
805
+ };
806
+ }
807
+ static checkTable(tableData) {
808
+ let rows = tableData.rows;
809
+ let prevRowCount = -1;
810
+ for (let i = 0; i < rows.length; i++) {
811
+ const row = rows[i];
812
+ if (row.columns.length !== prevRowCount && prevRowCount != -1) {
813
+ return {
814
+ isSucceeded: false,
815
+ message: `Ошибка при обработке разметки таблицы. `
816
+ + `Количество колонок в каждой строке таблицы должно соотвествовать друг другу. `
817
+ + `В строке таблицы №${i + 1} количество колонок = ${row.columns.length}, а в строке выше ${prevRowCount}.`
818
+ };
775
819
  }
820
+ prevRowCount = row.columns.length;
821
+ }
822
+ return {
823
+ isSucceeded: true,
824
+ message: "Ok"
776
825
  };
777
826
  }
778
- toBodyTag(data) {
827
+ static getHeader(tableTag) {
828
+ let header = tableTag.tHead;
829
+ if (header === null) {
830
+ return null;
831
+ }
832
+ let tr = header.children.item(0);
833
+ let headerColumns = [];
834
+ for (let j = 0; j < tr.children.length; j++) {
835
+ const jElement = tr.children.item(j);
836
+ headerColumns.push(jElement.innerHTML);
837
+ }
779
838
  return {
780
- presentOrEdit: true,
781
- tagDescription: {
782
- tag: HtmlRawTagDataConsts.TagName,
783
- displayValue: this.shortDescription,
784
- isCustom: false
785
- },
786
- attributes: {},
787
- innerHtml: BodyTagsExtensions.sanitizeInnerHtml(data.data["innerHTML"])
839
+ type: "table-header",
840
+ columns: headerColumns
788
841
  };
789
842
  }
843
+ static getTableRows(tableTag, options) {
844
+ let tBody = tableTag.tBodies.item(0);
845
+ let rows = [];
846
+ for (let i = 0; i < tBody.children.length; i++) {
847
+ const iElement = tBody.children.item(i);
848
+ let rowColumns = [];
849
+ for (let j = 0; j < iElement.children.length; j++) {
850
+ const jElement = iElement.children.item(j);
851
+ let children = HtmlExtractionMethods.transformHtmlElementToBlocks(jElement, options);
852
+ if (children.length === 0) {
853
+ var textTag = document.createElement("p");
854
+ textTag.innerHTML = jElement.innerHTML;
855
+ var textElem = TextSimpleMethods.ExtractTextTag(textTag);
856
+ children.push(textElem);
857
+ }
858
+ var result = {
859
+ type: TableTypes.TableRowColumnData,
860
+ data: {
861
+ text: jElement.innerHTML,
862
+ children
863
+ }
864
+ };
865
+ rowColumns.push(result);
866
+ }
867
+ rows.push({
868
+ type: TableTypes.TableRowColumn,
869
+ columns: rowColumns
870
+ });
871
+ }
872
+ return rows;
873
+ }
790
874
  }
791
875
 
792
- class DownloadButtonTagDataConsts {
793
- static { this.TagName = "download-file-button"; }
794
- static { this.TitleAttrName = "title"; }
795
- static { this.LinkAttrName = "link"; }
796
- }
797
- class DownloadButtonTagService {
798
- constructor() {
799
- this.tagName = DownloadButtonTagDataConsts.TagName;
800
- this.shortDescription = "Кнопка для скачивания";
801
- }
802
- bodyTagToHtmlStringConverter(bodyTag) {
803
- return `<${this.tagName} title="${bodyTag.attributes[DownloadButtonTagDataConsts.TitleAttrName]}" link="${bodyTag.attributes[DownloadButtonTagDataConsts.LinkAttrName]}"></${this.tagName}>`;
804
- }
805
- extractBlockFromHtmlElement(elem, options) {
806
- return {
807
- type: DownloadButtonTagDataConsts.TagName,
808
- data: {
809
- title: elem.getAttribute(DownloadButtonTagDataConsts.TitleAttrName),
810
- link: elem.getAttribute(DownloadButtonTagDataConsts.LinkAttrName)
876
+ class HtmlExtractionMethods {
877
+ // TODO удалить в пользу BodyTagsExtensions
878
+ static { this.Extractors = {
879
+ [TableTypes.Table]: (elem, options) => TableMethods.getTableFromHtmlTag(elem, options),
880
+ }; }
881
+ static transformHtmlElementToBlocks(element, options) {
882
+ var data = [];
883
+ for (let i = 0; i < element.children.length; i++) {
884
+ var elem = element.children.item(i);
885
+ var loweredTagName = elem.tagName.toLowerCase();
886
+ if (BodyTagsExtensions.tagServices.hasOwnProperty(loweredTagName)) {
887
+ var tagService = BodyTagsExtensions.tagServices[loweredTagName];
888
+ var resultBlock = tagService.extractBlockFromHtmlElement(elem, options);
889
+ data.push(resultBlock);
890
+ continue;
811
891
  }
812
- };
892
+ if (!HtmlExtractionMethods.Extractors.hasOwnProperty(loweredTagName)) {
893
+ data.push({
894
+ tagName: "unsupported-tag",
895
+ data: {
896
+ tagString: elem.outerHTML
897
+ }
898
+ });
899
+ }
900
+ else {
901
+ var extractor = HtmlExtractionMethods.Extractors[loweredTagName];
902
+ var result = extractor(elem, options);
903
+ data.push(result);
904
+ }
905
+ }
906
+ return data;
813
907
  }
814
- toBodyTag(data) {
815
- let fileData = data.data;
816
- return {
817
- presentOrEdit: true,
818
- tagDescription: {
819
- tag: data.type,
820
- displayValue: this.shortDescription,
821
- isCustom: false
822
- },
823
- attributes: fileData,
824
- innerHtml: ""
825
- };
908
+ static transformHtmlStringToBlocks(value, options) {
909
+ if (value === undefined || value === null) {
910
+ return [];
911
+ }
912
+ value = value
913
+ .replace('\n', '')
914
+ .replace('\t', '');
915
+ var div = document.createElement("div");
916
+ div.innerHTML = value;
917
+ return this.transformHtmlElementToBlocks(div, options);
826
918
  }
827
919
  }
828
920
 
829
- class ButtonTagDataConsts {
830
- static { this.TagName = "button"; }
831
- static { this.TextAttrName = "text"; }
832
- static { this.TypeAttrName = "type"; }
833
- static { this.ClickAttrName = "click"; }
921
+ class TextTags {
922
+ static { this.text = "text"; }
923
+ static { this.h1 = "h1"; }
924
+ static { this.h2 = "h2"; }
925
+ static { this.h3 = "h3"; }
926
+ static { this.h4 = "h4"; }
927
+ static { this.h5 = "h5"; }
928
+ static { this.h6 = "h6"; }
929
+ static { this.headerTextTags = [TextTags.h1, TextTags.h2, TextTags.h3, TextTags.h4, TextTags.h5, TextTags.h6]; }
930
+ static { this.allTextTags = [TextTags.text, ...TextTags.headerTextTags]; }
834
931
  }
835
- class ButtonTagService {
836
- constructor() {
837
- this.tagName = ButtonTagDataConsts.TagName;
838
- this.shortDescription = "Кнопка";
839
- }
840
- bodyTagToHtmlStringConverter(bodyTag) {
841
- let atts = bodyTag.attributes;
842
- return `<${this.tagName} text="${atts[ButtonTagDataConsts.TextAttrName]}" type="${atts[ButtonTagDataConsts.TypeAttrName]}" click="${atts[ButtonTagDataConsts.ClickAttrName]}"></${this.tagName}>`;
843
- }
844
- extractBlockFromHtmlElement(elem, options) {
845
- return {
846
- type: ButtonTagDataConsts.TagName,
847
- data: {
848
- text: elem.getAttribute(ButtonTagDataConsts.TextAttrName),
849
- type: elem.getAttribute(ButtonTagDataConsts.TypeAttrName),
850
- click: elem.getAttribute(ButtonTagDataConsts.ClickAttrName)
851
- }
852
- };
853
- }
854
- toBodyTag(data) {
855
- let fileData = data.data;
856
- return {
857
- presentOrEdit: true,
858
- tagDescription: {
859
- tag: data.type,
860
- displayValue: this.shortDescription,
861
- isCustom: false
862
- },
863
- attributes: fileData,
864
- innerHtml: ""
865
- };
932
+
933
+ class ExternalVideoTagDataConsts {
934
+ static { this.TagName = "external-video"; }
935
+ static { this.VideoTypeAttrName = "type"; }
936
+ static { this.LinkAttrName = "link"; }
937
+ static { this.UseResponsiveWrapperAttrName = "use-responsive-wrapper"; }
938
+ static { this.IframeAttrName = "iframe"; }
939
+ }
940
+ class ExternalVideoSupportedTypes {
941
+ static { this.Youtube = "youtube"; }
942
+ static { this.VkVideo = "vk-video"; }
943
+ static { this.Code = "code"; }
944
+ }
945
+ const ExternalVideoPlayers = [
946
+ {
947
+ type: ExternalVideoSupportedTypes.Code,
948
+ displayValue: 'Встраиваемое Видео',
949
+ },
950
+ {
951
+ type: ExternalVideoSupportedTypes.Youtube,
952
+ displayValue: 'Youtube',
953
+ },
954
+ {
955
+ type: ExternalVideoSupportedTypes.VkVideo,
956
+ displayValue: 'Vk Video',
866
957
  }
958
+ ];
959
+
960
+ class Tags {
961
+ static { this.Text = TextTags.text; }
962
+ static { this.H1 = TextTags.h1; }
963
+ static { this.H2 = TextTags.h2; }
964
+ static { this.H3 = TextTags.h3; }
965
+ static { this.H4 = TextTags.h4; }
966
+ static { this.H5 = TextTags.h5; }
967
+ static { this.H6 = TextTags.h6; }
968
+ static { this.HtmlRaw = HtmlRawTagDataConsts.TagName; }
969
+ static { this.FileImage = FileImageTagDataConsts.TagName; }
970
+ static { this.Table = 'table'; }
971
+ static { this.RichText = 'rich-text'; }
972
+ static { this.ExternalVideo = ExternalVideoTagDataConsts.TagName; }
973
+ static { this.UnsupportedTag = 'unsupported-tag'; }
974
+ static { this.CustomWidget = CustomWidgetTagDataConsts.TagName; }
867
975
  }
868
976
 
869
977
  class BodyTagsExtensions {
@@ -905,8 +1013,8 @@ class BodyTagsExtensions {
905
1013
  return html.trim().replace('\n\t', '');
906
1014
  }
907
1015
  static toBodyTag(data) {
908
- if (this.tagServices.hasOwnProperty(data.type)) {
909
- return this.tagServices[data.type].toBodyTag(data);
1016
+ if (this.tagServices.hasOwnProperty(data.tagName)) {
1017
+ return this.tagServices[data.tagName].toBodyTag(data);
910
1018
  }
911
1019
  return {
912
1020
  presentOrEdit: true,
@@ -1086,10 +1194,14 @@ class UploadFilesBtnComponent {
1086
1194
  this.onPublicFilesUploaded = new EventEmitter();
1087
1195
  this.onPrivateFilesUploaded = new EventEmitter();
1088
1196
  }
1089
- handleFileInput(files) {
1197
+ handleFileInput(e) {
1198
+ const files = e.target["files"];
1090
1199
  this.postFilesStarted.emit({
1091
- filesCount: files.length
1200
+ filesCount: files?.length ?? 0
1092
1201
  });
1202
+ if (files === null || files === undefined) {
1203
+ return;
1204
+ }
1093
1205
  if (this._htmlSettingsService.get().usePrivateFiles) {
1094
1206
  this._privateFileUploadService
1095
1207
  .postFiles(files, this._htmlSettingsService.get().applicationId)
@@ -1109,11 +1221,11 @@ class UploadFilesBtnComponent {
1109
1221
  this.fileInput.nativeElement.click();
1110
1222
  }
1111
1223
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: UploadFilesBtnComponent, deps: [{ token: PublicFileUploadService }, { token: PrivateFileUploadService }, { token: CrocoHtmlFileOptionsService }], target: i0.ɵɵFactoryTarget.Component }); }
1112
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: UploadFilesBtnComponent, isStandalone: true, selector: "croco-app-upload-files-btn", inputs: { extAccepts: "extAccepts", isMultiple: "isMultiple", btnText: "btnText", hidden: "hidden" }, outputs: { postFilesStarted: "postFilesStarted", onPublicFilesUploaded: "onPublicFilesUploaded", onPrivateFilesUploaded: "onPrivateFilesUploaded" }, 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: MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }] }); }
1224
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: UploadFilesBtnComponent, isStandalone: true, selector: "croco-app-upload-files-btn", inputs: { extAccepts: "extAccepts", isMultiple: "isMultiple", btnText: "btnText", hidden: "hidden" }, outputs: { postFilesStarted: "postFilesStarted", onPublicFilesUploaded: "onPublicFilesUploaded", onPrivateFilesUploaded: "onPrivateFilesUploaded" }, 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)\" />", styles: [""], dependencies: [{ kind: "component", type: MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }] }); }
1113
1225
  }
1114
1226
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: UploadFilesBtnComponent, decorators: [{
1115
1227
  type: Component,
1116
- args: [{ selector: 'croco-app-upload-files-btn', standalone: true, imports: [MatButton], 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)\" />" }]
1228
+ args: [{ selector: 'croco-app-upload-files-btn', standalone: true, imports: [MatButton], 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)\" />" }]
1117
1229
  }], ctorParameters: () => [{ type: PublicFileUploadService }, { type: PrivateFileUploadService }, { type: CrocoHtmlFileOptionsService }], propDecorators: { fileInput: [{
1118
1230
  type: ViewChild,
1119
1231
  args: ['filesInput']
@@ -1280,11 +1392,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
1280
1392
 
1281
1393
  class XmlTagHeaderInnerTextViewComponent {
1282
1394
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: XmlTagHeaderInnerTextViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1283
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: XmlTagHeaderInnerTextViewComponent, isStandalone: true, 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}" }); }
1395
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: XmlTagHeaderInnerTextViewComponent, isStandalone: true, selector: "croco-html-xml-tag-header-inner-text-view", inputs: { item: "item" }, ngImport: i0, template: "@if (item.tagName === 'h1') {\n <h1\n [innerHtml]=\"item.data.html\">\n </h1>\n}\n@if (item.tagName === 'h2') {\n <h2\n [innerHtml]=\"item.data.html\">\n </h2>\n}\n@if (item.tagName === 'h3') {\n <h3\n [innerHtml]=\"item.data.html\">\n </h3>\n}\n@if (item.tagName === 'h4') {\n <h4\n [innerHtml]=\"item.data.html\">\n </h4>\n}\n@if (item.tagName === 'h5') {\n <h5\n [innerHtml]=\"item.data.html\">\n </h5>\n}\n@if (item.tagName === 'h6') {\n <h6\n [innerHtml]=\"item.data.html\">\n </h6>\n}" }); }
1284
1396
  }
1285
1397
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: XmlTagHeaderInnerTextViewComponent, decorators: [{
1286
1398
  type: Component,
1287
- args: [{ selector: 'croco-html-xml-tag-header-inner-text-view', standalone: true, 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}" }]
1399
+ args: [{ selector: 'croco-html-xml-tag-header-inner-text-view', standalone: true, template: "@if (item.tagName === 'h1') {\n <h1\n [innerHtml]=\"item.data.html\">\n </h1>\n}\n@if (item.tagName === 'h2') {\n <h2\n [innerHtml]=\"item.data.html\">\n </h2>\n}\n@if (item.tagName === 'h3') {\n <h3\n [innerHtml]=\"item.data.html\">\n </h3>\n}\n@if (item.tagName === 'h4') {\n <h4\n [innerHtml]=\"item.data.html\">\n </h4>\n}\n@if (item.tagName === 'h5') {\n <h5\n [innerHtml]=\"item.data.html\">\n </h5>\n}\n@if (item.tagName === 'h6') {\n <h6\n [innerHtml]=\"item.data.html\">\n </h6>\n}" }]
1288
1400
  }], propDecorators: { item: [{
1289
1401
  type: Input,
1290
1402
  args: [{ required: true }]
@@ -1316,22 +1428,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
1316
1428
  type: Input
1317
1429
  }] } });
1318
1430
 
1319
- class XmlTagTableViewComponent {
1320
- constructor() {
1321
- this.displayedColumns = [];
1322
- }
1323
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: XmlTagTableViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1324
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: XmlTagTableViewComponent, isStandalone: true, 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>", dependencies: [{ kind: "component", type: MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "directive", type: MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "component", type: MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "directive", type: MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "component", type: MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }] }); }
1325
- }
1326
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: XmlTagTableViewComponent, decorators: [{
1327
- type: Component,
1328
- args: [{ selector: 'croco-html-xml-tag-table-view', standalone: true, imports: [MatTable, MatColumnDef, MatHeaderCellDef, MatHeaderCell, MatCellDef, MatCell, MatHeaderRowDef, MatHeaderRow, MatRowDef, MatRow], 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>" }]
1329
- }], propDecorators: { displayedColumns: [{
1330
- type: Input
1331
- }], data: [{
1332
- type: Input
1333
- }] } });
1334
-
1335
1431
  class XmlTagTextViewComponent {
1336
1432
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: XmlTagTextViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1337
1433
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: XmlTagTextViewComponent, isStandalone: true, 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}" }); }
@@ -1464,7 +1560,7 @@ class FileImageTagViewComponent {
1464
1560
  getMediaRequests(screenMediaRequest) {
1465
1561
  let result = ImageMethods.mediaRequestStringToArrayParser(screenMediaRequest);
1466
1562
  if (result.length === 0) {
1467
- return this._options.globalMediaRequests ?? [];
1563
+ return this._options.imageOptions.globalMediaRequests ?? [];
1468
1564
  }
1469
1565
  return result;
1470
1566
  }
@@ -1622,14 +1718,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
1622
1718
  }] } });
1623
1719
 
1624
1720
  class XmlTagViewComponent {
1625
- constructor() {
1721
+ constructor(_options) {
1722
+ this._options = _options;
1626
1723
  this.data = [];
1627
1724
  }
1628
1725
  isHeaderTextTag(item) {
1629
- return TextTags.headerTextTags.includes(item.type);
1726
+ return TextTags.headerTextTags.includes(item.tagName);
1630
1727
  }
1631
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: XmlTagViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1632
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: XmlTagViewComponent, isStandalone: true, 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\n @if (item.type === 'text') {\n <div>\n <croco-html-xml-tag-text-view [item]=\"item\"></croco-html-xml-tag-text-view>\n </div>\n }\n\n @if (item.type === 'html-raw') {\n <div>\n <croco-html-raw-view [rawHtml]=\"item.data.innerHTML\"></croco-html-raw-view>\n </div>\n }\n\n @if (isHeaderTextTag(item)) {\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 === 'custom-widget') {\n <div>\n <croco-html-xml-tag-custom-widget [tagData]=\"item.data\"></croco-html-xml-tag-custom-widget>\n </div>\n }\n\n @if (item.type === 'table' && item.validationResult) {\n\n @if (item.validationResult.isSucceeded){\n <croco-html-xml-tag-html-view [html]=\"item.bootstrapHtml\">\n </croco-html-xml-tag-html-view>\n }\n @else {\n <croco-html-error-banner [message]=\"item.validationResult.message\">\n </croco-html-error-banner>\n }\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 === 'download-file-button') {\n <div>\n <croco-html-xml-tag-download-file-button [data]=\"item\"></croco-html-xml-tag-download-file-button>\n </div>\n }\n\n @if (item.type === 'button') {\n <div>\n <croco-html-xml-tag-button [data]=\"item\"></croco-html-xml-tag-button>\n </div>\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>\n", styles: [".red{background-color:#c94444;color:#fff}\n"], dependencies: [{ kind: "component", type: XmlTagTextViewComponent, selector: "croco-html-xml-tag-text-view", inputs: ["item"] }, { kind: "component", type: HtmlRawViewComponent, selector: "croco-html-raw-view", inputs: ["rawHtml"] }, { kind: "component", type: XmlTagHeaderTextViewComponent, selector: "croco-html-xml-tag-header-text-view", inputs: ["item"] }, { kind: "component", type: FileImageTagViewComponent, selector: "croco-html-file-image-tag-view", inputs: ["item"] }, { kind: "component", type: XmlTagHtmlViewComponent, selector: "croco-html-xml-tag-html-view", inputs: ["html"] }, { kind: "component", type: ErrorBannerComponent, selector: "croco-html-error-banner", inputs: ["message"] }, { kind: "component", type: XmlTagExternalVideoComponent, selector: "croco-html-xml-tag-external-video", inputs: ["data", "tagData"] }, { kind: "component", type: XmlTagDownloadFileButtonComponent, selector: "croco-html-xml-tag-download-file-button", inputs: ["data", "tagData"] }, { kind: "component", type: XmlTagButtonComponent, selector: "croco-html-xml-tag-button", inputs: ["data", "tagData"] }, { kind: "component", type: XmlTagCustomWidgetComponent, selector: "croco-html-xml-tag-custom-widget", inputs: ["tagData"] }], encapsulation: i0.ViewEncapsulation.None }); }
1728
+ isDefinedCustomTag(item) {
1729
+ return this._options.definedCustomTags.includes(item.tagName);
1730
+ }
1731
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: XmlTagViewComponent, deps: [{ token: CrocoHtmlOptionsToken }], target: i0.ɵɵFactoryTarget.Component }); }
1732
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: XmlTagViewComponent, isStandalone: true, 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\n @if (item.tagName === 'text') {\n <div>\n <croco-html-xml-tag-text-view [item]=\"item\"></croco-html-xml-tag-text-view>\n </div>\n }\n\n @if (item.tagName === 'html-raw') {\n <div>\n <croco-html-raw-view [rawHtml]=\"item.data.innerHTML\"></croco-html-raw-view>\n </div>\n }\n\n @if (isHeaderTextTag(item)) {\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.tagName === '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.tagName === 'custom-widget') {\n <div>\n <croco-html-xml-tag-custom-widget [tagData]=\"item.data\"></croco-html-xml-tag-custom-widget>\n </div>\n }\n\n @if (item.tagName === 'table' && item.validationResult) {\n\n @if (item.validationResult.isSucceeded){\n <croco-html-xml-tag-html-view [html]=\"item.bootstrapHtml\">\n </croco-html-xml-tag-html-view>\n }\n @else {\n <croco-html-error-banner [message]=\"item.validationResult.message\">\n </croco-html-error-banner>\n }\n }\n\n @if (item.tagName === '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.tagName === 'download-file-button') {\n <div>\n <croco-html-xml-tag-download-file-button [data]=\"item\"></croco-html-xml-tag-download-file-button>\n </div>\n }\n\n @if (item.tagName === 'button') {\n <div>\n <croco-html-xml-tag-button [data]=\"item\"></croco-html-xml-tag-button>\n </div>\n }\n @if (item.tagName === '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: XmlTagTextViewComponent, selector: "croco-html-xml-tag-text-view", inputs: ["item"] }, { kind: "component", type: HtmlRawViewComponent, selector: "croco-html-raw-view", inputs: ["rawHtml"] }, { kind: "component", type: XmlTagHeaderTextViewComponent, selector: "croco-html-xml-tag-header-text-view", inputs: ["item"] }, { kind: "component", type: FileImageTagViewComponent, selector: "croco-html-file-image-tag-view", inputs: ["item"] }, { kind: "component", type: XmlTagHtmlViewComponent, selector: "croco-html-xml-tag-html-view", inputs: ["html"] }, { kind: "component", type: ErrorBannerComponent, selector: "croco-html-error-banner", inputs: ["message"] }, { kind: "component", type: XmlTagExternalVideoComponent, selector: "croco-html-xml-tag-external-video", inputs: ["data", "tagData"] }, { kind: "component", type: XmlTagDownloadFileButtonComponent, selector: "croco-html-xml-tag-download-file-button", inputs: ["data", "tagData"] }, { kind: "component", type: XmlTagButtonComponent, selector: "croco-html-xml-tag-button", inputs: ["data", "tagData"] }, { kind: "component", type: XmlTagCustomWidgetComponent, selector: "croco-html-xml-tag-custom-widget", inputs: ["tagData"] }], encapsulation: i0.ViewEncapsulation.None }); }
1633
1733
  }
1634
1734
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: XmlTagViewComponent, decorators: [{
1635
1735
  type: Component,
@@ -1644,8 +1744,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
1644
1744
  XmlTagDownloadFileButtonComponent,
1645
1745
  XmlTagButtonComponent,
1646
1746
  XmlTagCustomWidgetComponent,
1647
- ], template: "<div>\n @for (item of data; track $index) {\n <div class=\"row\">\n\n @if (item.type === 'text') {\n <div>\n <croco-html-xml-tag-text-view [item]=\"item\"></croco-html-xml-tag-text-view>\n </div>\n }\n\n @if (item.type === 'html-raw') {\n <div>\n <croco-html-raw-view [rawHtml]=\"item.data.innerHTML\"></croco-html-raw-view>\n </div>\n }\n\n @if (isHeaderTextTag(item)) {\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 === 'custom-widget') {\n <div>\n <croco-html-xml-tag-custom-widget [tagData]=\"item.data\"></croco-html-xml-tag-custom-widget>\n </div>\n }\n\n @if (item.type === 'table' && item.validationResult) {\n\n @if (item.validationResult.isSucceeded){\n <croco-html-xml-tag-html-view [html]=\"item.bootstrapHtml\">\n </croco-html-xml-tag-html-view>\n }\n @else {\n <croco-html-error-banner [message]=\"item.validationResult.message\">\n </croco-html-error-banner>\n }\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 === 'download-file-button') {\n <div>\n <croco-html-xml-tag-download-file-button [data]=\"item\"></croco-html-xml-tag-download-file-button>\n </div>\n }\n\n @if (item.type === 'button') {\n <div>\n <croco-html-xml-tag-button [data]=\"item\"></croco-html-xml-tag-button>\n </div>\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>\n", styles: [".red{background-color:#c94444;color:#fff}\n"] }]
1648
- }], propDecorators: { data: [{
1747
+ ], template: "<div>\n @for (item of data; track $index) {\n <div class=\"row\">\n\n @if (item.tagName === 'text') {\n <div>\n <croco-html-xml-tag-text-view [item]=\"item\"></croco-html-xml-tag-text-view>\n </div>\n }\n\n @if (item.tagName === 'html-raw') {\n <div>\n <croco-html-raw-view [rawHtml]=\"item.data.innerHTML\"></croco-html-raw-view>\n </div>\n }\n\n @if (isHeaderTextTag(item)) {\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.tagName === '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.tagName === 'custom-widget') {\n <div>\n <croco-html-xml-tag-custom-widget [tagData]=\"item.data\"></croco-html-xml-tag-custom-widget>\n </div>\n }\n\n @if (item.tagName === 'table' && item.validationResult) {\n\n @if (item.validationResult.isSucceeded){\n <croco-html-xml-tag-html-view [html]=\"item.bootstrapHtml\">\n </croco-html-xml-tag-html-view>\n }\n @else {\n <croco-html-error-banner [message]=\"item.validationResult.message\">\n </croco-html-error-banner>\n }\n }\n\n @if (item.tagName === '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.tagName === 'download-file-button') {\n <div>\n <croco-html-xml-tag-download-file-button [data]=\"item\"></croco-html-xml-tag-download-file-button>\n </div>\n }\n\n @if (item.tagName === 'button') {\n <div>\n <croco-html-xml-tag-button [data]=\"item\"></croco-html-xml-tag-button>\n </div>\n }\n @if (item.tagName === '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"] }]
1748
+ }], ctorParameters: () => [{ type: undefined, decorators: [{
1749
+ type: Inject,
1750
+ args: [CrocoHtmlOptionsToken]
1751
+ }] }], propDecorators: { data: [{
1649
1752
  type: Input
1650
1753
  }] } });
1651
1754
 
@@ -1856,11 +1959,11 @@ class FileIdSelectComponent {
1856
1959
  this.loadFiles();
1857
1960
  }
1858
1961
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: FileIdSelectComponent, deps: [{ token: PublicFilesQueryService }, { token: PrivateFilesQueryService }, { token: CrocoHtmlFileOptionsService }, { token: CrocoHtmlOptionsToken }], target: i0.ɵɵFactoryTarget.Component }); }
1859
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: FileIdSelectComponent, isStandalone: true, selector: "croco-html-file-id-select", inputs: { labelText: "labelText", fileId: "fileId" }, outputs: { fileId: "fileId", onFileIdChanged: "onFileIdChanged" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"file-id\">\n <div class=\"form-group\">\n <label for=\"fileName\">{{labelText}}</label>\n <ng-select [(ngModel)]=\"fileId\" (ngModelChange)=\"onModelChanged($event)\" [items]=\"files\" #select\n bindLabel=\"fileName\" (search)=\"onSearchChanged($event)\" [loading]=\"loading\" [loadingText]=\"'\u0417\u0430\u0433\u0440\u0443\u0436\u0430\u044E \u0444\u0430\u0439\u043B\u044B'\"\n dropdownPosition=\"auto\" [bindValue]=\"'fileId'\" labelForId=\"fileName\" 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 class=\"file-id__container\">\n <div class=\"file-id__text-container\">\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 </div>\n <div class=\"file-id__img\">\n <img class=\"mx-auto d-block img-fluid\" [src]=\"getSrc(item.fileId)\" />\n </div>\n </div>\n\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: [".file-id__container{display:flex;align-items:center;justify-content:space-between;gap:10px}@media (max-width: 768px){.file-id__container{align-items:unset;flex-direction:column}}.file-id__text-container{display:flex;flex-direction:column}.file-id__text-container b{word-break:break-word;white-space:normal}@media (max-width: 768px){.file-id__text-container b{font-size:14px}}@media (max-width: 768px){.file-id__text-container span{font-size:14px}}.file-id__img img{width:100px;height:100px}\n"], dependencies: [{ kind: "ngmodule", type: NgSelectModule }, { kind: "component", type: i4.NgSelectComponent, selector: "ng-select", inputs: ["ariaLabelDropdown", "bindLabel", "bindValue", "ariaLabel", "markFirst", "placeholder", "fixedPlaceholder", "notFoundText", "typeToSearchText", "preventToggleOnRightClick", "addTagText", "loadingText", "clearAllText", "appearance", "dropdownPosition", "appendTo", "loading", "closeOnSelect", "hideSelected", "selectOnTab", "openOnEnter", "maxSelectedItems", "groupBy", "groupValue", "bufferAmount", "virtualScroll", "selectableGroup", "selectableGroupAsModel", "searchFn", "trackByFn", "clearOnBackspace", "labelForId", "inputAttrs", "tabIndex", "tabFocusOnClearButton", "readonly", "searchWhileComposing", "minTermLength", "editableSearchTerm", "ngClass", "typeahead", "multiple", "addTag", "searchable", "clearable", "isOpen", "items", "compareWith", "clearSearchOnAdd", "deselectOnClick", "keyDownFn"], outputs: ["blur", "focus", "change", "open", "close", "search", "clear", "add", "remove", "scroll", "scrollToEnd"] }, { kind: "directive", type: i4.NgOptionTemplateDirective, selector: "[ng-option-tmp]" }, { kind: "ngmodule", type: FormsModule }, { 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"] }] }); }
1962
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: FileIdSelectComponent, isStandalone: true, selector: "croco-html-file-id-select", inputs: { labelText: "labelText", fileId: "fileId" }, outputs: { fileId: "fileId", onFileIdChanged: "onFileIdChanged" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"file-id\">\n <div class=\"form-group\">\n <label for=\"fileName\">{{labelText}}</label>\n <ng-select [(ngModel)]=\"fileId\" (ngModelChange)=\"onModelChanged($event)\" [items]=\"files\" #select\n bindLabel=\"fileName\" (search)=\"onSearchChanged($event)\" [loading]=\"loading\" [loadingText]=\"'\u0417\u0430\u0433\u0440\u0443\u0436\u0430\u044E \u0444\u0430\u0439\u043B\u044B'\"\n dropdownPosition=\"auto\" [bindValue]=\"'fileId'\" labelForId=\"fileName\" 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 class=\"file-id__container\">\n <div class=\"file-id__text-container\">\n <div>\n <span class=\"h5\">\u0424\u0430\u0439\u043B: </span>\n <span class=\"h5\"><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 </div>\n <div class=\"file-id__img\">\n <img class=\"mx-auto d-block img-fluid\" [src]=\"getSrc(item.fileId)\" />\n </div>\n </div>\n\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: [".file-id__container{display:flex;align-items:center;justify-content:space-between;gap:10px}@media (max-width: 768px){.file-id__container{align-items:unset;flex-direction:column}}.file-id__text-container{display:flex;flex-direction:column}.file-id__text-container b{word-break:break-word;white-space:normal}@media (max-width: 768px){.file-id__text-container b{font-size:14px}}@media (max-width: 768px){.file-id__text-container span{font-size:14px}}.file-id__img img{width:100px;height:100px}\n"], dependencies: [{ kind: "ngmodule", type: NgSelectModule }, { kind: "component", type: i4.NgSelectComponent, selector: "ng-select", inputs: ["ariaLabelDropdown", "bindLabel", "bindValue", "ariaLabel", "markFirst", "placeholder", "fixedPlaceholder", "notFoundText", "typeToSearchText", "preventToggleOnRightClick", "addTagText", "loadingText", "clearAllText", "appearance", "dropdownPosition", "appendTo", "loading", "closeOnSelect", "hideSelected", "selectOnTab", "openOnEnter", "maxSelectedItems", "groupBy", "groupValue", "bufferAmount", "virtualScroll", "selectableGroup", "selectableGroupAsModel", "searchFn", "trackByFn", "clearOnBackspace", "labelForId", "inputAttrs", "tabIndex", "tabFocusOnClearButton", "readonly", "searchWhileComposing", "minTermLength", "editableSearchTerm", "ngClass", "typeahead", "multiple", "addTag", "searchable", "clearable", "isOpen", "items", "compareWith", "clearSearchOnAdd", "deselectOnClick", "keyDownFn"], outputs: ["blur", "focus", "change", "open", "close", "search", "clear", "add", "remove", "scroll", "scrollToEnd"] }, { kind: "directive", type: i4.NgOptionTemplateDirective, selector: "[ng-option-tmp]" }, { kind: "ngmodule", type: FormsModule }, { 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"] }] }); }
1860
1963
  }
1861
1964
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: FileIdSelectComponent, decorators: [{
1862
1965
  type: Component,
1863
- args: [{ selector: 'croco-html-file-id-select', standalone: true, imports: [NgSelectModule, FormsModule], template: "<div class=\"file-id\">\n <div class=\"form-group\">\n <label for=\"fileName\">{{labelText}}</label>\n <ng-select [(ngModel)]=\"fileId\" (ngModelChange)=\"onModelChanged($event)\" [items]=\"files\" #select\n bindLabel=\"fileName\" (search)=\"onSearchChanged($event)\" [loading]=\"loading\" [loadingText]=\"'\u0417\u0430\u0433\u0440\u0443\u0436\u0430\u044E \u0444\u0430\u0439\u043B\u044B'\"\n dropdownPosition=\"auto\" [bindValue]=\"'fileId'\" labelForId=\"fileName\" 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 class=\"file-id__container\">\n <div class=\"file-id__text-container\">\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 </div>\n <div class=\"file-id__img\">\n <img class=\"mx-auto d-block img-fluid\" [src]=\"getSrc(item.fileId)\" />\n </div>\n </div>\n\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: [".file-id__container{display:flex;align-items:center;justify-content:space-between;gap:10px}@media (max-width: 768px){.file-id__container{align-items:unset;flex-direction:column}}.file-id__text-container{display:flex;flex-direction:column}.file-id__text-container b{word-break:break-word;white-space:normal}@media (max-width: 768px){.file-id__text-container b{font-size:14px}}@media (max-width: 768px){.file-id__text-container span{font-size:14px}}.file-id__img img{width:100px;height:100px}\n"] }]
1966
+ args: [{ selector: 'croco-html-file-id-select', standalone: true, imports: [NgSelectModule, FormsModule], template: "<div class=\"file-id\">\n <div class=\"form-group\">\n <label for=\"fileName\">{{labelText}}</label>\n <ng-select [(ngModel)]=\"fileId\" (ngModelChange)=\"onModelChanged($event)\" [items]=\"files\" #select\n bindLabel=\"fileName\" (search)=\"onSearchChanged($event)\" [loading]=\"loading\" [loadingText]=\"'\u0417\u0430\u0433\u0440\u0443\u0436\u0430\u044E \u0444\u0430\u0439\u043B\u044B'\"\n dropdownPosition=\"auto\" [bindValue]=\"'fileId'\" labelForId=\"fileName\" 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 class=\"file-id__container\">\n <div class=\"file-id__text-container\">\n <div>\n <span class=\"h5\">\u0424\u0430\u0439\u043B: </span>\n <span class=\"h5\"><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 </div>\n <div class=\"file-id__img\">\n <img class=\"mx-auto d-block img-fluid\" [src]=\"getSrc(item.fileId)\" />\n </div>\n </div>\n\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: [".file-id__container{display:flex;align-items:center;justify-content:space-between;gap:10px}@media (max-width: 768px){.file-id__container{align-items:unset;flex-direction:column}}.file-id__text-container{display:flex;flex-direction:column}.file-id__text-container b{word-break:break-word;white-space:normal}@media (max-width: 768px){.file-id__text-container b{font-size:14px}}@media (max-width: 768px){.file-id__text-container span{font-size:14px}}.file-id__img img{width:100px;height:100px}\n"] }]
1864
1967
  }], ctorParameters: () => [{ type: PublicFilesQueryService }, { type: PrivateFilesQueryService }, { type: CrocoHtmlFileOptionsService }, { type: undefined, decorators: [{
1865
1968
  type: Inject,
1866
1969
  args: [CrocoHtmlOptionsToken]
@@ -1940,7 +2043,7 @@ class ImageEditorComponent {
1940
2043
  this.unsubscribe.complete();
1941
2044
  }
1942
2045
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ImageEditorComponent, deps: [{ token: CrocoHtmlOptionsToken }, { token: ScreenWidthService }], target: i0.ɵɵFactoryTarget.Component }); }
1943
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: ImageEditorComponent, isStandalone: true, 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\n [ngStyle]=\"{ 'max-height': imageMaxHeight ? imageMaxHeight + 'px' : '100%', 'max-width': imageMaxWidth ? imageMaxWidth + 'px' : '100%', }\"\n class=\"mx-auto d-block img-fluid\" [src]=\"getSrc()\" (error)=\"onErrorHandler()\" alt=\"photo\"/>\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\n @if(!tag.presentOrEdit) {\n <mat-slide-toggle style=\"padding: 10px 0\" [(ngModel)]=\"isShowMediaRequest\">\u041F\u043E\u043A\u0430\u0437\u044B\u0432\u0430\u0442\u044C \u043C\u0435\u0434\u0438\u0430 \u0437\u0430\u043F\u0440\u043E\u0441\u044B</mat-slide-toggle>\n }\n\n @if(isShowMediaRequest) {\n <div style=\"display: flex; flex-direction: column; gap: 20px\">\n <div class=\"media-request__header\">\n <span>\u041C\u0435\u0434\u0438\u0430 \u0437\u0430\u043F\u0440\u043E\u0441\u044B:</span>\n @if (!tag.presentOrEdit) {\n <button (click)=\"addNewMediaRequest()\" class=\"w-30\" mat-icon-button color=\"primary\">\n <mat-icon>add</mat-icon>\n </button>\n }\n </div>\n @for (request of requests; track $index) {\n <div class=\"media-request__container\">\n @if (tag.presentOrEdit) {\n <div style=\"display: flex; flex-direction: column; gap: 5px\">\n <span class=\"w-100\">\u041C\u0438\u043D\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0448\u0438\u0440\u0438\u043D\u0430: {{request.minScreenWidth}}</span>\n <span class=\"w-100\">\u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0448\u0438\u0440\u0438\u043D\u0430: {{request.maxScreenWidth}}</span>\n <span class=\"w-100\">\u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0432\u044B\u0441\u043E\u0442\u0430 \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F: {{request.maxImageHeight}}</span>\n <span class=\"w-100\">\u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0448\u0438\u0440\u0438\u043D\u0430 \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F: {{request.maxImageWidth}}</span>\n </div>\n }\n\n @if (!tag.presentOrEdit) {\n <div style=\"width: 100%\">\n <mat-form-field class=\"w-100\">\n <mat-label>\n \u041C\u0438\u043D\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0448\u0438\u0440\u0438\u043D\u0430\n </mat-label>\n <input matInput placeholder=\"\u041C\u0438\u043D\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0433\u0440\u0430\u043D\u0438\u0446\u0430 \u0448\u0438\u0440\u0438\u043D\u044B\"\n autocomplete=\"off\"\n [(ngModel)]=\"request.minScreenWidth\"\n (ngModelChange)=\"requestChanged()\">\n </mat-form-field>\n\n <mat-form-field class=\"w-100\">\n <mat-label>\n \u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0448\u0438\u0440\u0438\u043D\u0430\n </mat-label>\n <input matInput placeholder=\"\u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0433\u0440\u0430\u043D\u0438\u0446\u0430 \u0448\u0438\u0440\u0438\u043D\u044B\"\n autocomplete=\"off\"\n [(ngModel)]=\"request.maxScreenWidth\"\n (ngModelChange)=\"requestChanged()\">\n </mat-form-field>\n\n <mat-form-field class=\"w-100\">\n <mat-label>\n \u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0432\u044B\u0441\u043E\u0442\u0430 \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F\n </mat-label>\n <input matInput placeholder=\"\u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0432\u044B\u0441\u043E\u0442\u0430 \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F\"\n autocomplete=\"off\"\n [(ngModel)]=\"request.maxImageHeight\"\n (ngModelChange)=\"requestChanged()\">\n </mat-form-field>\n\n <mat-form-field class=\"w-100\">\n <mat-label>\n \u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0448\u0438\u0440\u0438\u043D\u0430 \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F\n </mat-label>\n <input matInput placeholder=\"\u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0448\u0438\u0440\u0438\u043D\u0430 \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F\"\n autocomplete=\"off\"\n [(ngModel)]=\"request.maxImageWidth\"\n (ngModelChange)=\"requestChanged()\">\n </mat-form-field>\n </div>\n\n <button (click)=\"deleteMediaRequest($index)\" class=\"w-30\" mat-icon-button color=\"warn\">\n <mat-icon>delete</mat-icon>\n </button>\n }\n </div>\n }\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)]=\"fileId\"\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 <mat-label>\n \u0418\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u043E\u0440 \u0444\u0430\u0439\u043B\u0430\n </mat-label>\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 [(ngModel)]=\"fileId\"\n (ngModelChange)=\"onFileIdChanged($event)\">\n </mat-form-field>\n </div>\n </div>\n </div>\n}\n", styles: [".error-block{background-color:#f32323;color:#fff;text-align:center;border-radius:10px;padding:10px}.media-request__header{align-items:center;display:flex;width:100%;justify-content:space-between}.media-request__container{display:flex;align-items:center;border-bottom:1px solid rgba(128,128,128,.7);padding-bottom:10px}@media screen and (max-width: 768px){mat-button-toggle-group{display:flex;flex-direction:column}}\n"], dependencies: [{ kind: "directive", type: MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled", "disabledInteractive", "hideSingleSelectionIndicator", "hideMultipleSelectionIndicator"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { kind: "ngmodule", type: FormsModule }, { 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: MatButtonToggle, selector: "mat-button-toggle", inputs: ["aria-label", "aria-labelledby", "id", "name", "value", "tabIndex", "disableRipple", "appearance", "checked", "disabled", "disabledInteractive"], outputs: ["change"], exportAs: ["matButtonToggle"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: FileIdSelectComponent, selector: "croco-html-file-id-select", inputs: ["labelText", "fileId"], outputs: ["fileId", "onFileIdChanged"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }] }); }
2046
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: ImageEditorComponent, isStandalone: true, 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\n [ngStyle]=\"{ 'max-height': imageMaxHeight ? imageMaxHeight + 'px' : '100%', 'max-width': imageMaxWidth ? imageMaxWidth + 'px' : '100%', }\"\n class=\"mx-auto d-block img-fluid\" [src]=\"getSrc()\" (error)=\"onErrorHandler()\" alt=\"photo\"/>\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\n @if(!tag.presentOrEdit) {\n <mat-slide-toggle style=\"padding: 10px 0\" [(ngModel)]=\"isShowMediaRequest\">\u041F\u043E\u043A\u0430\u0437\u044B\u0432\u0430\u0442\u044C \u043C\u0435\u0434\u0438\u0430 \u0437\u0430\u043F\u0440\u043E\u0441\u044B</mat-slide-toggle>\n }\n\n @if(isShowMediaRequest) {\n <div style=\"display: flex; flex-direction: column; gap: 20px\">\n <div class=\"media-request__header\">\n <span>\u041C\u0435\u0434\u0438\u0430 \u0437\u0430\u043F\u0440\u043E\u0441\u044B:</span>\n @if (!tag.presentOrEdit) {\n <button (click)=\"addNewMediaRequest()\" class=\"w-30\" mat-icon-button color=\"primary\">\n <mat-icon>add</mat-icon>\n </button>\n }\n </div>\n @for (request of requests; track $index) {\n <div class=\"media-request__container\">\n @if (tag.presentOrEdit) {\n <div style=\"display: flex; flex-direction: column; gap: 5px\">\n <span class=\"w-100\">\u041C\u0438\u043D\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0448\u0438\u0440\u0438\u043D\u0430: {{request.minScreenWidth}}</span>\n <span class=\"w-100\">\u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0448\u0438\u0440\u0438\u043D\u0430: {{request.maxScreenWidth}}</span>\n <span class=\"w-100\">\u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0432\u044B\u0441\u043E\u0442\u0430 \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F: {{request.maxImageHeight}}</span>\n <span class=\"w-100\">\u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0448\u0438\u0440\u0438\u043D\u0430 \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F: {{request.maxImageWidth}}</span>\n </div>\n }\n\n @if (!tag.presentOrEdit) {\n <div style=\"width: 100%\">\n <mat-form-field class=\"w-100\">\n <mat-label>\n \u041C\u0438\u043D\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0448\u0438\u0440\u0438\u043D\u0430\n </mat-label>\n <input matInput placeholder=\"\u041C\u0438\u043D\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0433\u0440\u0430\u043D\u0438\u0446\u0430 \u0448\u0438\u0440\u0438\u043D\u044B\"\n autocomplete=\"off\"\n [(ngModel)]=\"request.minScreenWidth\"\n (ngModelChange)=\"requestChanged()\">\n </mat-form-field>\n\n <mat-form-field class=\"w-100\">\n <mat-label>\n \u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0448\u0438\u0440\u0438\u043D\u0430\n </mat-label>\n <input matInput placeholder=\"\u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0433\u0440\u0430\u043D\u0438\u0446\u0430 \u0448\u0438\u0440\u0438\u043D\u044B\"\n autocomplete=\"off\"\n [(ngModel)]=\"request.maxScreenWidth\"\n (ngModelChange)=\"requestChanged()\">\n </mat-form-field>\n\n <mat-form-field class=\"w-100\">\n <mat-label>\n \u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0432\u044B\u0441\u043E\u0442\u0430 \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F\n </mat-label>\n <input matInput placeholder=\"\u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0432\u044B\u0441\u043E\u0442\u0430 \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F\"\n autocomplete=\"off\"\n [(ngModel)]=\"request.maxImageHeight\"\n (ngModelChange)=\"requestChanged()\">\n </mat-form-field>\n\n <mat-form-field class=\"w-100\">\n <mat-label>\n \u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0448\u0438\u0440\u0438\u043D\u0430 \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F\n </mat-label>\n <input matInput placeholder=\"\u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0448\u0438\u0440\u0438\u043D\u0430 \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F\"\n autocomplete=\"off\"\n [(ngModel)]=\"request.maxImageWidth\"\n (ngModelChange)=\"requestChanged()\">\n </mat-form-field>\n </div>\n\n <button (click)=\"deleteMediaRequest($index)\" class=\"w-30\" mat-icon-button color=\"warn\">\n <mat-icon>delete</mat-icon>\n </button>\n }\n </div>\n }\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]=\"fileId\"\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 <mat-label>\n \u0418\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u043E\u0440 \u0444\u0430\u0439\u043B\u0430\n </mat-label>\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 [(ngModel)]=\"fileId\"\n (ngModelChange)=\"onFileIdChanged($event)\">\n </mat-form-field>\n </div>\n </div>\n </div>\n}\n", styles: [".error-block{background-color:#f32323;color:#fff;text-align:center;border-radius:10px;padding:10px}.media-request__header{align-items:center;display:flex;width:100%;justify-content:space-between}.media-request__container{display:flex;align-items:center;border-bottom:1px solid rgba(128,128,128,.7);padding-bottom:10px}@media screen and (max-width: 768px){mat-button-toggle-group{display:flex;flex-direction:column}}\n"], dependencies: [{ kind: "directive", type: MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled", "disabledInteractive", "hideSingleSelectionIndicator", "hideMultipleSelectionIndicator"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { kind: "ngmodule", type: FormsModule }, { 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: MatButtonToggle, selector: "mat-button-toggle", inputs: ["aria-label", "aria-labelledby", "id", "name", "value", "tabIndex", "disableRipple", "appearance", "checked", "disabled", "disabledInteractive"], outputs: ["change"], exportAs: ["matButtonToggle"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: FileIdSelectComponent, selector: "croco-html-file-id-select", inputs: ["labelText", "fileId"], outputs: ["fileId", "onFileIdChanged"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }] }); }
1944
2047
  }
1945
2048
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ImageEditorComponent, decorators: [{
1946
2049
  type: Component,
@@ -1956,7 +2059,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
1956
2059
  NgStyle,
1957
2060
  MatIconButton,
1958
2061
  MatSlideToggle
1959
- ], 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\n [ngStyle]=\"{ 'max-height': imageMaxHeight ? imageMaxHeight + 'px' : '100%', 'max-width': imageMaxWidth ? imageMaxWidth + 'px' : '100%', }\"\n class=\"mx-auto d-block img-fluid\" [src]=\"getSrc()\" (error)=\"onErrorHandler()\" alt=\"photo\"/>\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\n @if(!tag.presentOrEdit) {\n <mat-slide-toggle style=\"padding: 10px 0\" [(ngModel)]=\"isShowMediaRequest\">\u041F\u043E\u043A\u0430\u0437\u044B\u0432\u0430\u0442\u044C \u043C\u0435\u0434\u0438\u0430 \u0437\u0430\u043F\u0440\u043E\u0441\u044B</mat-slide-toggle>\n }\n\n @if(isShowMediaRequest) {\n <div style=\"display: flex; flex-direction: column; gap: 20px\">\n <div class=\"media-request__header\">\n <span>\u041C\u0435\u0434\u0438\u0430 \u0437\u0430\u043F\u0440\u043E\u0441\u044B:</span>\n @if (!tag.presentOrEdit) {\n <button (click)=\"addNewMediaRequest()\" class=\"w-30\" mat-icon-button color=\"primary\">\n <mat-icon>add</mat-icon>\n </button>\n }\n </div>\n @for (request of requests; track $index) {\n <div class=\"media-request__container\">\n @if (tag.presentOrEdit) {\n <div style=\"display: flex; flex-direction: column; gap: 5px\">\n <span class=\"w-100\">\u041C\u0438\u043D\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0448\u0438\u0440\u0438\u043D\u0430: {{request.minScreenWidth}}</span>\n <span class=\"w-100\">\u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0448\u0438\u0440\u0438\u043D\u0430: {{request.maxScreenWidth}}</span>\n <span class=\"w-100\">\u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0432\u044B\u0441\u043E\u0442\u0430 \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F: {{request.maxImageHeight}}</span>\n <span class=\"w-100\">\u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0448\u0438\u0440\u0438\u043D\u0430 \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F: {{request.maxImageWidth}}</span>\n </div>\n }\n\n @if (!tag.presentOrEdit) {\n <div style=\"width: 100%\">\n <mat-form-field class=\"w-100\">\n <mat-label>\n \u041C\u0438\u043D\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0448\u0438\u0440\u0438\u043D\u0430\n </mat-label>\n <input matInput placeholder=\"\u041C\u0438\u043D\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0433\u0440\u0430\u043D\u0438\u0446\u0430 \u0448\u0438\u0440\u0438\u043D\u044B\"\n autocomplete=\"off\"\n [(ngModel)]=\"request.minScreenWidth\"\n (ngModelChange)=\"requestChanged()\">\n </mat-form-field>\n\n <mat-form-field class=\"w-100\">\n <mat-label>\n \u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0448\u0438\u0440\u0438\u043D\u0430\n </mat-label>\n <input matInput placeholder=\"\u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0433\u0440\u0430\u043D\u0438\u0446\u0430 \u0448\u0438\u0440\u0438\u043D\u044B\"\n autocomplete=\"off\"\n [(ngModel)]=\"request.maxScreenWidth\"\n (ngModelChange)=\"requestChanged()\">\n </mat-form-field>\n\n <mat-form-field class=\"w-100\">\n <mat-label>\n \u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0432\u044B\u0441\u043E\u0442\u0430 \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F\n </mat-label>\n <input matInput placeholder=\"\u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0432\u044B\u0441\u043E\u0442\u0430 \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F\"\n autocomplete=\"off\"\n [(ngModel)]=\"request.maxImageHeight\"\n (ngModelChange)=\"requestChanged()\">\n </mat-form-field>\n\n <mat-form-field class=\"w-100\">\n <mat-label>\n \u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0448\u0438\u0440\u0438\u043D\u0430 \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F\n </mat-label>\n <input matInput placeholder=\"\u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0448\u0438\u0440\u0438\u043D\u0430 \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F\"\n autocomplete=\"off\"\n [(ngModel)]=\"request.maxImageWidth\"\n (ngModelChange)=\"requestChanged()\">\n </mat-form-field>\n </div>\n\n <button (click)=\"deleteMediaRequest($index)\" class=\"w-30\" mat-icon-button color=\"warn\">\n <mat-icon>delete</mat-icon>\n </button>\n }\n </div>\n }\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)]=\"fileId\"\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 <mat-label>\n \u0418\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u043E\u0440 \u0444\u0430\u0439\u043B\u0430\n </mat-label>\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 [(ngModel)]=\"fileId\"\n (ngModelChange)=\"onFileIdChanged($event)\">\n </mat-form-field>\n </div>\n </div>\n </div>\n}\n", styles: [".error-block{background-color:#f32323;color:#fff;text-align:center;border-radius:10px;padding:10px}.media-request__header{align-items:center;display:flex;width:100%;justify-content:space-between}.media-request__container{display:flex;align-items:center;border-bottom:1px solid rgba(128,128,128,.7);padding-bottom:10px}@media screen and (max-width: 768px){mat-button-toggle-group{display:flex;flex-direction:column}}\n"] }]
2062
+ ], 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\n [ngStyle]=\"{ 'max-height': imageMaxHeight ? imageMaxHeight + 'px' : '100%', 'max-width': imageMaxWidth ? imageMaxWidth + 'px' : '100%', }\"\n class=\"mx-auto d-block img-fluid\" [src]=\"getSrc()\" (error)=\"onErrorHandler()\" alt=\"photo\"/>\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\n @if(!tag.presentOrEdit) {\n <mat-slide-toggle style=\"padding: 10px 0\" [(ngModel)]=\"isShowMediaRequest\">\u041F\u043E\u043A\u0430\u0437\u044B\u0432\u0430\u0442\u044C \u043C\u0435\u0434\u0438\u0430 \u0437\u0430\u043F\u0440\u043E\u0441\u044B</mat-slide-toggle>\n }\n\n @if(isShowMediaRequest) {\n <div style=\"display: flex; flex-direction: column; gap: 20px\">\n <div class=\"media-request__header\">\n <span>\u041C\u0435\u0434\u0438\u0430 \u0437\u0430\u043F\u0440\u043E\u0441\u044B:</span>\n @if (!tag.presentOrEdit) {\n <button (click)=\"addNewMediaRequest()\" class=\"w-30\" mat-icon-button color=\"primary\">\n <mat-icon>add</mat-icon>\n </button>\n }\n </div>\n @for (request of requests; track $index) {\n <div class=\"media-request__container\">\n @if (tag.presentOrEdit) {\n <div style=\"display: flex; flex-direction: column; gap: 5px\">\n <span class=\"w-100\">\u041C\u0438\u043D\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0448\u0438\u0440\u0438\u043D\u0430: {{request.minScreenWidth}}</span>\n <span class=\"w-100\">\u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0448\u0438\u0440\u0438\u043D\u0430: {{request.maxScreenWidth}}</span>\n <span class=\"w-100\">\u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0432\u044B\u0441\u043E\u0442\u0430 \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F: {{request.maxImageHeight}}</span>\n <span class=\"w-100\">\u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0448\u0438\u0440\u0438\u043D\u0430 \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F: {{request.maxImageWidth}}</span>\n </div>\n }\n\n @if (!tag.presentOrEdit) {\n <div style=\"width: 100%\">\n <mat-form-field class=\"w-100\">\n <mat-label>\n \u041C\u0438\u043D\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0448\u0438\u0440\u0438\u043D\u0430\n </mat-label>\n <input matInput placeholder=\"\u041C\u0438\u043D\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0433\u0440\u0430\u043D\u0438\u0446\u0430 \u0448\u0438\u0440\u0438\u043D\u044B\"\n autocomplete=\"off\"\n [(ngModel)]=\"request.minScreenWidth\"\n (ngModelChange)=\"requestChanged()\">\n </mat-form-field>\n\n <mat-form-field class=\"w-100\">\n <mat-label>\n \u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0448\u0438\u0440\u0438\u043D\u0430\n </mat-label>\n <input matInput placeholder=\"\u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0433\u0440\u0430\u043D\u0438\u0446\u0430 \u0448\u0438\u0440\u0438\u043D\u044B\"\n autocomplete=\"off\"\n [(ngModel)]=\"request.maxScreenWidth\"\n (ngModelChange)=\"requestChanged()\">\n </mat-form-field>\n\n <mat-form-field class=\"w-100\">\n <mat-label>\n \u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0432\u044B\u0441\u043E\u0442\u0430 \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F\n </mat-label>\n <input matInput placeholder=\"\u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0432\u044B\u0441\u043E\u0442\u0430 \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F\"\n autocomplete=\"off\"\n [(ngModel)]=\"request.maxImageHeight\"\n (ngModelChange)=\"requestChanged()\">\n </mat-form-field>\n\n <mat-form-field class=\"w-100\">\n <mat-label>\n \u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0448\u0438\u0440\u0438\u043D\u0430 \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F\n </mat-label>\n <input matInput placeholder=\"\u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0448\u0438\u0440\u0438\u043D\u0430 \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F\"\n autocomplete=\"off\"\n [(ngModel)]=\"request.maxImageWidth\"\n (ngModelChange)=\"requestChanged()\">\n </mat-form-field>\n </div>\n\n <button (click)=\"deleteMediaRequest($index)\" class=\"w-30\" mat-icon-button color=\"warn\">\n <mat-icon>delete</mat-icon>\n </button>\n }\n </div>\n }\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]=\"fileId\"\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 <mat-label>\n \u0418\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u043E\u0440 \u0444\u0430\u0439\u043B\u0430\n </mat-label>\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 [(ngModel)]=\"fileId\"\n (ngModelChange)=\"onFileIdChanged($event)\">\n </mat-form-field>\n </div>\n </div>\n </div>\n}\n", styles: [".error-block{background-color:#f32323;color:#fff;text-align:center;border-radius:10px;padding:10px}.media-request__header{align-items:center;display:flex;width:100%;justify-content:space-between}.media-request__container{display:flex;align-items:center;border-bottom:1px solid rgba(128,128,128,.7);padding-bottom:10px}@media screen and (max-width: 768px){mat-button-toggle-group{display:flex;flex-direction:column}}\n"] }]
1960
2063
  }], ctorParameters: () => [{ type: undefined, decorators: [{
1961
2064
  type: Inject,
1962
2065
  args: [CrocoHtmlOptionsToken]
@@ -1990,6 +2093,12 @@ class DefaultTags {
1990
2093
  }
1991
2094
  }
1992
2095
 
2096
+ const AlignmentsData = [
2097
+ { value: TextAlignment.Left, text: 'Слева' },
2098
+ { value: TextAlignment.Center, text: 'По центру' },
2099
+ { value: TextAlignment.Right, text: 'Справа' },
2100
+ ];
2101
+
1993
2102
  class DownloadFileButtonEditorComponent {
1994
2103
  constructor() {
1995
2104
  this.onTagUpdated = new EventEmitter();
@@ -2028,8 +2137,6 @@ class TextEditorComponent {
2028
2137
  constructor() {
2029
2138
  this.onTagUpdated = new EventEmitter();
2030
2139
  }
2031
- ngOnInit() {
2032
- }
2033
2140
  getInnerHtml() {
2034
2141
  return `<${this.tag.tagDescription.tag}>${this.tag.innerHtml}<${this.tag.tagDescription.tag}/>`;
2035
2142
  }
@@ -2039,7 +2146,7 @@ class TextEditorComponent {
2039
2146
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: TextEditorComponent, decorators: [{
2040
2147
  type: Component,
2041
2148
  args: [{ selector: 'croco-html-text-editor', standalone: true, imports: [MatButtonToggleGroup, FormsModule, MatButtonToggle, MatIcon, MatFormField, MatLabel, MatInput, CdkTextareaAutosize], 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 <mat-label>\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</mat-label>\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}\n" }]
2042
- }], ctorParameters: () => [], propDecorators: { tag: [{
2149
+ }], propDecorators: { tag: [{
2043
2150
  type: Input
2044
2151
  }], onTagUpdated: [{
2045
2152
  type: Output
@@ -2167,9 +2274,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
2167
2274
  }]
2168
2275
  }] });
2169
2276
 
2170
- const defaultLinkYouTube = "https://www.youtube.com/embed/4CtSAnJDfsI?si=scyBNJa0Hs2t5aLE";
2171
- const defaultLinkVk = "https://vk.com/video_ext.php?oid=-22822305&id=456241864&hd=2";
2172
- const defaultLinkForDownload = "https://storage.yandexcloud.net/mega-academy/presentation.pdf";
2173
2277
  class VisualEditorComponent {
2174
2278
  isHtmlSet() {
2175
2279
  return this.html.startsWith("<body>");
@@ -2189,7 +2293,7 @@ class VisualEditorComponent {
2189
2293
  this.loadingText = "Идёт загрузка";
2190
2294
  this.text = '';
2191
2295
  this.htmlRaw = '';
2192
- this.alignment = EAlignments.Left;
2296
+ this.alignment = TextAlignment.Left;
2193
2297
  this.textTag = DefaultTags.textTags[0].tag;
2194
2298
  this.textTagOptions = DefaultTags.textTags;
2195
2299
  this.alignmentOptions = AlignmentsData;
@@ -2218,55 +2322,24 @@ class VisualEditorComponent {
2218
2322
  addTagClickHandler() {
2219
2323
  let tagDescription = this.tags
2220
2324
  .find(x => x.tag === this.selectedValue);
2221
- if (TextTags.allTextTags.includes(tagDescription.tag)) {
2325
+ const tagName = tagDescription.tag;
2326
+ if (TextTags.allTextTags.includes(tagName)) {
2222
2327
  this.addTextTags();
2223
2328
  this.startAddingText();
2224
2329
  return;
2225
2330
  }
2226
- let attrs = {};
2227
- let innerHtml = "";
2228
- if (tagDescription.tag == ExternalVideoTagDataConsts.TagName) {
2229
- attrs[ExternalVideoTagDataConsts.VideoTypeAttrName] = this.selectedVideoPlayer;
2230
- attrs[ExternalVideoTagDataConsts.UseResponsiveWrapperAttrName] = false;
2231
- attrs[ExternalVideoTagDataConsts.LinkAttrName] = this.selectedVideoPlayer === ExternalVideoSupportedTypes.Code ? '' :
2232
- this.selectedVideoPlayer === ExternalVideoSupportedTypes.VkVideo
2233
- ? defaultLinkVk
2234
- : defaultLinkYouTube;
2235
- if (this.selectedVideoPlayer === ExternalVideoSupportedTypes.Code) {
2236
- innerHtml = this.htmlRaw;
2237
- }
2238
- }
2239
- else if (tagDescription.tag == FileImageTagDataConsts.TagName) {
2240
- attrs[FileImageTagDataConsts.ScreenMediaRequest] = FileImageTagDataConsts.DefaultValueForFileImage;
2241
- }
2242
- else if (tagDescription.tag == DownloadButtonTagDataConsts.TagName) {
2243
- attrs[DownloadButtonTagDataConsts.LinkAttrName] = defaultLinkForDownload;
2244
- attrs[DownloadButtonTagDataConsts.TitleAttrName] = 'Скачать';
2245
- }
2246
- else if (tagDescription.tag == ButtonTagDataConsts.TagName) {
2247
- attrs[ButtonTagDataConsts.ClickAttrName] = '';
2248
- attrs[ButtonTagDataConsts.TypeAttrName] = 'button';
2249
- attrs[ButtonTagDataConsts.TextAttrName] = 'Кнопка';
2250
- }
2251
- else if (tagDescription.tag === HtmlRawTagDataConsts.TagName) {
2252
- innerHtml = this.htmlRaw;
2253
- }
2254
- else if (tagDescription.tag == CustomWidgetTagDataConsts.TagName) {
2255
- attrs[CustomWidgetTagDataConsts.TypeAttrName] = 'example-type';
2256
- attrs[CustomWidgetTagDataConsts.DataIdAttrName] = 'example-data-id';
2257
- attrs[CustomWidgetTagDataConsts.WidgetIdAttrName] = 'example-widget-id';
2258
- }
2259
- else if (tagDescription.tag === FileImageTagDataConsts.TagName) {
2260
- attrs[FileImageTagDataConsts.FileIdAttrName] = null;
2331
+ if (BodyTagsExtensions.tagServices.hasOwnProperty(tagName)) {
2332
+ const tagService = BodyTagsExtensions.tagServices[tagName];
2333
+ let tag = tagService.getDefaultValue({
2334
+ htmlRaw: this.htmlRaw,
2335
+ selectedVideoPlayer: this.selectedVideoPlayer
2336
+ });
2337
+ this.bodyTags.push(tag);
2338
+ this.htmlRaw = '';
2339
+ this.recalculateHtml();
2340
+ return;
2261
2341
  }
2262
- this.bodyTags.push({
2263
- tagDescription,
2264
- innerHtml,
2265
- attributes: attrs,
2266
- presentOrEdit: true
2267
- });
2268
- this.htmlRaw = '';
2269
- this.recalculateHtml();
2342
+ alert(`Сервис для тега ${tagName} не зарегистрирован.`);
2270
2343
  }
2271
2344
  startAddingText(tag = '') {
2272
2345
  this.saveBodyTags = [...this.bodyTags];
@@ -2279,7 +2352,7 @@ class VisualEditorComponent {
2279
2352
  }
2280
2353
  resetTextStyle() {
2281
2354
  this.text = '';
2282
- this.alignment = EAlignments.Left;
2355
+ this.alignment = TextAlignment.Left;
2283
2356
  this.textTag = DefaultTags.textTags[0].tag;
2284
2357
  }
2285
2358
  addTextTags() {
@@ -2358,7 +2431,7 @@ class VisualEditorComponent {
2358
2431
  return `align-${type}`;
2359
2432
  }
2360
2433
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: VisualEditorComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: CrocoHtmlOptionsToken }], target: i0.ɵɵFactoryTarget.Component }); }
2361
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: VisualEditorComponent, isStandalone: true, 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 <div class=\"w-100\" style=\"margin-bottom: 22px\">\n <div class=\"tags\">\n @for (tag of tags; track tag) {\n <span class=\"tag-item\" (click)=\"selectTag(tag)\" [class.active]=\"selectedValue === tag.tag\">\n <span class=\"text-align-icon\">\n <ng-container [ngTemplateOutlet]=\"tagButtonIcons\"\n [ngTemplateOutletContext]=\"{icon: tag.tag}\">\n </ng-container>\n </span>\n {{tag.displayValue}}\n </span>\n }\n\n @if (useCustomWidgetsButton) {\n <span class=\"tag-item\" (click)=\"customWidgetsClickHandler()\">\n <span class=\"text-align-icon\">\n <ng-container [ngTemplateOutlet]=\"tagButtonIcons\"\n [ngTemplateOutletContext]=\"{icon: 'custom-widget'}\">\n </ng-container>\n </span>\n \u0414\u0440\u0443\u0433\u0438\u0435 \u0432\u0438\u0434\u0436\u0435\u0442\u044B\n </span>\n }\n \n </div>\n </div>\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 @if (selectedVideoPlayer === ExternalVideoSupportedTypes.Code) {\n <div class=\"col-12\">\n <mat-form-field class=\"w-100\" appearance=\"outline\">\n <mat-label>\u0420\u0430\u0437\u043C\u0435\u0442\u043A\u0430</mat-label>\n <input\n matInput\n placeholder=\"\u0420\u0430\u0437\u043C\u0435\u0442\u043A\u0430\"\n [(ngModel)]=\"htmlRaw\"\n >\n </mat-form-field>\n </div>\n }\n }\n @if (selectedValue === HtmlRawTagDataConsts.TagName) {\n <div class=\"col-12\">\n <mat-form-field class=\"w-100\">\n <mat-label>\u0420\u0430\u0437\u043C\u0435\u0442\u043A\u0430</mat-label>\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)]=\"htmlRaw\"\n ></textarea>\n </mat-form-field>\n </div>\n }\n @if (selectedValue === 'text') {\n <div style=\"display: flex; justify-content: space-between; flex-wrap: wrap\">\n <div style=\"margin-bottom: 22px; overflow-x: auto;\">\n <mat-button-toggle-group\n [(ngModel)]=\"textTag\"\n [hideSingleSelectionIndicator]=\"true\"\n >\n @for (option of textTagOptions; track option) {\n <mat-button-toggle value=\"{{ option.tag }}\">\n {{ option.displayValue }}\n </mat-button-toggle>\n }\n </mat-button-toggle-group>\n </div>\n\n <div style=\"margin-bottom: 22px\">\n <mat-button-toggle-group\n [(ngModel)]=\"alignment\"\n [hideSingleSelectionIndicator]=\"true\"\n >\n @for (option of alignmentOptions; track option) {\n <mat-button-toggle value=\"{{ option.value }}\">\n <span class=\"text-align-icon\">\n <ng-container [ngTemplateOutlet]=\"textAlignToggleIcons\"\n [ngTemplateOutletContext]=\"{icon: option.value}\">\n </ng-container>\n </span>\n </mat-button-toggle>\n }\n </mat-button-toggle-group>\n </div>\n </div>\n <mat-form-field class=\"w-100\">\n <mat-label>\u0422\u0435\u043A\u0441\u0442</mat-label>\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 ></textarea>\n </mat-form-field>\n }\n\n <div class=\"col-12\">\n <button (click)=\"addTagClickHandler()\" 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()\" 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 special\">\n <mat-card-content>\n <div class=\"d-flex justify-content-between\">\n <div class=\"example-handle\" cdkDragHandle>\n <svg width=\"24\" height=\"24\" class=\"move-icon\">\n <use [attr.xlink:href]=\"'move-icon' | spriteIconPath\"></use>\n </svg>\n </div>\n <div>\n <div class=\"badge\" [matTooltip]=\"tag.tagDescription.tag\">\n <span class=\"text-align-icon\">\n <ng-container [ngTemplateOutlet]=\"tagButtonIcons\"\n [ngTemplateOutletContext]=\"{icon: tag.tagDescription.tag}\">\n </ng-container>\n </span>\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>\n }\n </div>\n</div>\n\n<ng-template #textAlignToggleIcons let-icon=\"icon\">\n <svg width=\"20\" height=\"20\">\n <use [attr.xlink:href]=\"setAlignButton(icon) | spriteIconPath\"></use>\n </svg>\n</ng-template>\n\n<ng-template #tagButtonIcons let-icon=\"icon\">\n @if (icon.indexOf('h') === 0 && icon.length === 2) {\n {{icon.toUpperCase()}}\n }\n @else {\n <svg width=\"20\" height=\"20\">\n <use [attr.xlink:href]=\"setTagButton(icon) | spriteIconPath\"></use>\n </svg>\n }\n</ng-template>", styles: [":host{--mat-standard-button-toggle-selected-state-background-color: #323E8B;--mat-standard-button-toggle-text-color: #323E8B;--mat-standard-button-toggle-selected-state-text-color: white;--mat-standard-button-toggle-height: 36px;--mat-standard-button-toggle-divider-color: #323E8B;--mdc-outlined-button-label-text-weight: 400;--mdc-outlined-button-label-text-color: #333333 !important;--mdc-outlined-button-container-shape: 30px;--mdc-outlined-button-outline-width: 2px;--mdc-outlined-button-container-height: 44px}:host ::ng-deep .mat-button-toggle-appearance-standard span.mat-button-toggle-label-content{padding:0 8px;min-width:36px}.text-align-icon,.mat-button-toggle .text-align-icon{color:#323e8b}.mat-button-toggle:hover,.mat-button-toggle:hover .text-align-icon{color:#747ebf}.mat-button-toggle-checked .text-align-icon{color:#fff}.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{width:44px;height:44px;border-radius:50%;border:1px solid #323E8B;display:flex;align-items:center;justify-content:center;color:#323e8b}.mat-card.special{border:1px solid #747EBF;border-radius:8px;box-shadow:none;margin:2px 2px 10px}.tags{display:flex;gap:10px;flex-wrap:wrap}.tag-item{display:flex;align-items:center;gap:5px;cursor:pointer;padding:10px 20px;border:1px solid #323E8B;border-radius:30px;background-color:#fff;color:#23262a;transition:.2s ease-in-out}.text-align-icon{color:#323e8b}.tag-item.active{background-color:#323e8b;color:#fff}.tag-item.active svg{color:#fff}.tag-item:hover{color:#747ebf;box-shadow:0 0 4px #747ebf}.tag-item:hover svg{color:#747ebf}@media (max-width: 768px){.tag-item:hover{color:inherit;box-shadow:none}.tag-item:hover svg{color:inherit}.tag-item:active{color:#747ebf;box-shadow:0 0 4px #747ebf}.tag-item:active svg{color:#747ebf}}.move-icon:hover{cursor:pointer;opacity:.7}.cdk-drag.cdk-drag-placeholder,.cdk-drag-preview{opacity:.5;transition:opacity .2s}.example-handle{color:#323e8b}\n"], dependencies: [{ kind: "component", type: MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: MatCardContent, selector: "mat-card-content" }, { kind: "component", type: MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "directive", type: CdkTextareaAutosize, selector: "textarea[cdkTextareaAutosize]", inputs: ["cdkAutosizeMinRows", "cdkAutosizeMaxRows", "cdkTextareaAutosize", "placeholder"], exportAs: ["cdkTextareaAutosize"] }, { kind: "ngmodule", type: FormsModule }, { 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: 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", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: AddFilesBtnComponent, selector: "croco-html-add-files-btn", outputs: ["postFilesStarted", "filesTagsReady"] }, { kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "component", type: MainEditorBlockComponent, selector: "croco-html-main-editor-block", inputs: ["tag"], outputs: ["onTagSaved", "onTagRemoved"] }, { kind: "directive", type: MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled", "disabledInteractive", "hideSingleSelectionIndicator", "hideMultipleSelectionIndicator"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { kind: "component", type: MatButtonToggle, selector: "mat-button-toggle", inputs: ["aria-label", "aria-labelledby", "id", "name", "value", "tabIndex", "disableRipple", "appearance", "checked", "disabled", "disabledInteractive"], outputs: ["change"], exportAs: ["matButtonToggle"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "pipe", type: SpriteIconPathPipe, name: "spriteIconPath" }] }); }
2434
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: VisualEditorComponent, isStandalone: true, 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 <div class=\"w-100\" style=\"margin-bottom: 22px\">\n <div class=\"tags\">\n @for (tag of tags; track tag) {\n <span class=\"tag-item\" (click)=\"selectTag(tag)\" [class.active]=\"selectedValue === tag.tag\">\n <span class=\"text-align-icon\">\n <ng-container [ngTemplateOutlet]=\"tagButtonIcons\"\n [ngTemplateOutletContext]=\"{icon: tag.tag}\">\n </ng-container>\n </span>\n {{tag.displayValue}}\n </span>\n }\n\n @if (useCustomWidgetsButton) {\n <span class=\"tag-item\" (click)=\"customWidgetsClickHandler()\">\n <span class=\"text-align-icon\">\n <ng-container [ngTemplateOutlet]=\"tagButtonIcons\"\n [ngTemplateOutletContext]=\"{icon: 'custom-widget'}\">\n </ng-container>\n </span>\n \u0414\u0440\u0443\u0433\u0438\u0435 \u0432\u0438\u0434\u0436\u0435\u0442\u044B\n </span>\n }\n \n </div>\n </div>\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 @if (selectedVideoPlayer === ExternalVideoSupportedTypes.Code) {\n <div class=\"col-12\">\n <mat-form-field class=\"w-100\" appearance=\"outline\">\n <mat-label>\u0420\u0430\u0437\u043C\u0435\u0442\u043A\u0430</mat-label>\n <input\n matInput\n placeholder=\"\u0420\u0430\u0437\u043C\u0435\u0442\u043A\u0430\"\n [(ngModel)]=\"htmlRaw\"\n >\n </mat-form-field>\n </div>\n }\n }\n @if (selectedValue === HtmlRawTagDataConsts.TagName) {\n <div class=\"col-12\">\n <mat-form-field class=\"w-100\">\n <mat-label>\u0420\u0430\u0437\u043C\u0435\u0442\u043A\u0430</mat-label>\n <textarea\n #autosize=\"cdkTextareaAutosize\"\n matInput\n cdkTextareaAutosize\n cdkAutosizeMinRows=\"1\"\n cdkAutosizeMaxRows=\"5\"\n placeholder=\"\u0420\u0430\u0437\u043C\u0435\u0442\u043A\u0430\"\n #textArea\n [(ngModel)]=\"htmlRaw\"\n ></textarea>\n </mat-form-field>\n </div>\n }\n @if (selectedValue === 'text') {\n <div style=\"display: flex; justify-content: space-between; flex-wrap: wrap\">\n <div style=\"margin-bottom: 22px; overflow-x: auto;\">\n <mat-button-toggle-group\n [(ngModel)]=\"textTag\"\n [hideSingleSelectionIndicator]=\"true\"\n >\n @for (option of textTagOptions; track option) {\n <mat-button-toggle value=\"{{ option.tag }}\">\n {{ option.displayValue }}\n </mat-button-toggle>\n }\n </mat-button-toggle-group>\n </div>\n\n <div style=\"margin-bottom: 22px\">\n <mat-button-toggle-group\n [(ngModel)]=\"alignment\"\n [hideSingleSelectionIndicator]=\"true\"\n >\n @for (option of alignmentOptions; track option) {\n <mat-button-toggle value=\"{{ option.value }}\">\n <span class=\"text-align-icon\">\n <ng-container [ngTemplateOutlet]=\"textAlignToggleIcons\"\n [ngTemplateOutletContext]=\"{icon: option.value}\">\n </ng-container>\n </span>\n </mat-button-toggle>\n }\n </mat-button-toggle-group>\n </div>\n </div>\n <mat-form-field class=\"w-100\">\n <mat-label>\u0422\u0435\u043A\u0441\u0442</mat-label>\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 ></textarea>\n </mat-form-field>\n }\n\n <div class=\"col-12\">\n <button (click)=\"addTagClickHandler()\" 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()\" 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 special\">\n <mat-card-content>\n <div class=\"d-flex justify-content-between\">\n <div class=\"example-handle\" cdkDragHandle>\n <svg width=\"24\" height=\"24\" class=\"move-icon\">\n <use [attr.xlink:href]=\"'move-icon' | spriteIconPath\"></use>\n </svg>\n </div>\n <div>\n <div class=\"badge\" [matTooltip]=\"tag.tagDescription.tag\">\n <span class=\"text-align-icon\">\n <ng-container [ngTemplateOutlet]=\"tagButtonIcons\"\n [ngTemplateOutletContext]=\"{icon: tag.tagDescription.tag}\">\n </ng-container>\n </span>\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>\n }\n </div>\n</div>\n\n<ng-template #textAlignToggleIcons let-icon=\"icon\">\n <svg width=\"20\" height=\"20\">\n <use [attr.xlink:href]=\"setAlignButton(icon) | spriteIconPath\"></use>\n </svg>\n</ng-template>\n\n<ng-template #tagButtonIcons let-icon=\"icon\">\n @if (icon.indexOf('h') === 0 && icon.length === 2) {\n {{icon.toUpperCase()}}\n }\n @else {\n <svg width=\"20\" height=\"20\">\n <use [attr.xlink:href]=\"setTagButton(icon) | spriteIconPath\"></use>\n </svg>\n }\n</ng-template>", styles: [":host{--mat-standard-button-toggle-selected-state-background-color: #323E8B;--mat-standard-button-toggle-text-color: #323E8B;--mat-standard-button-toggle-selected-state-text-color: white;--mat-standard-button-toggle-height: 36px;--mat-standard-button-toggle-divider-color: #323E8B;--mdc-outlined-button-label-text-weight: 400;--mdc-outlined-button-label-text-color: #333333 !important;--mdc-outlined-button-container-shape: 30px;--mdc-outlined-button-outline-width: 2px;--mdc-outlined-button-container-height: 44px}:host ::ng-deep .mat-button-toggle-appearance-standard span.mat-button-toggle-label-content{padding:0 8px;min-width:36px}.text-align-icon,.mat-button-toggle .text-align-icon{color:#323e8b}.mat-button-toggle:hover,.mat-button-toggle:hover .text-align-icon{color:#747ebf}.mat-button-toggle-checked .text-align-icon{color:#fff}.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{width:44px;height:44px;border-radius:50%;border:1px solid #323E8B;display:flex;align-items:center;justify-content:center;color:#323e8b}.mat-card.special{border:1px solid #747EBF;border-radius:8px;box-shadow:none;margin:2px 2px 10px}.tags{display:flex;gap:10px;flex-wrap:wrap}.tag-item{display:flex;align-items:center;gap:5px;cursor:pointer;padding:10px 20px;border:1px solid #323E8B;border-radius:30px;background-color:#fff;color:#23262a;transition:.2s ease-in-out}.text-align-icon{color:#323e8b}.tag-item.active{background-color:#323e8b;color:#fff}.tag-item.active svg{color:#fff}.tag-item:hover{color:#747ebf;box-shadow:0 0 4px #747ebf}.tag-item:hover svg{color:#747ebf}@media (max-width: 768px){.tag-item:hover{color:inherit;box-shadow:none}.tag-item:hover svg{color:inherit}.tag-item:active{color:#747ebf;box-shadow:0 0 4px #747ebf}.tag-item:active svg{color:#747ebf}}.move-icon:hover{cursor:pointer;opacity:.7}.cdk-drag.cdk-drag-placeholder,.cdk-drag-preview{opacity:.5;transition:opacity .2s}.example-handle{color:#323e8b}\n"], dependencies: [{ kind: "component", type: MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: MatCardContent, selector: "mat-card-content" }, { kind: "component", type: MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "directive", type: CdkTextareaAutosize, selector: "textarea[cdkTextareaAutosize]", inputs: ["cdkAutosizeMinRows", "cdkAutosizeMaxRows", "cdkTextareaAutosize", "placeholder"], exportAs: ["cdkTextareaAutosize"] }, { kind: "ngmodule", type: FormsModule }, { 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: 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", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: AddFilesBtnComponent, selector: "croco-html-add-files-btn", outputs: ["postFilesStarted", "filesTagsReady"] }, { kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "component", type: MainEditorBlockComponent, selector: "croco-html-main-editor-block", inputs: ["tag"], outputs: ["onTagSaved", "onTagRemoved"] }, { kind: "directive", type: MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled", "disabledInteractive", "hideSingleSelectionIndicator", "hideMultipleSelectionIndicator"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { kind: "component", type: MatButtonToggle, selector: "mat-button-toggle", inputs: ["aria-label", "aria-labelledby", "id", "name", "value", "tabIndex", "disableRipple", "appearance", "checked", "disabled", "disabledInteractive"], outputs: ["change"], exportAs: ["matButtonToggle"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "pipe", type: SpriteIconPathPipe, name: "spriteIconPath" }] }); }
2362
2435
  }
2363
2436
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: VisualEditorComponent, decorators: [{
2364
2437
  type: Component,
@@ -2384,7 +2457,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
2384
2457
  NgTemplateOutlet,
2385
2458
  MatTooltip,
2386
2459
  SpriteIconPathPipe,
2387
- ], 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 <div class=\"w-100\" style=\"margin-bottom: 22px\">\n <div class=\"tags\">\n @for (tag of tags; track tag) {\n <span class=\"tag-item\" (click)=\"selectTag(tag)\" [class.active]=\"selectedValue === tag.tag\">\n <span class=\"text-align-icon\">\n <ng-container [ngTemplateOutlet]=\"tagButtonIcons\"\n [ngTemplateOutletContext]=\"{icon: tag.tag}\">\n </ng-container>\n </span>\n {{tag.displayValue}}\n </span>\n }\n\n @if (useCustomWidgetsButton) {\n <span class=\"tag-item\" (click)=\"customWidgetsClickHandler()\">\n <span class=\"text-align-icon\">\n <ng-container [ngTemplateOutlet]=\"tagButtonIcons\"\n [ngTemplateOutletContext]=\"{icon: 'custom-widget'}\">\n </ng-container>\n </span>\n \u0414\u0440\u0443\u0433\u0438\u0435 \u0432\u0438\u0434\u0436\u0435\u0442\u044B\n </span>\n }\n \n </div>\n </div>\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 @if (selectedVideoPlayer === ExternalVideoSupportedTypes.Code) {\n <div class=\"col-12\">\n <mat-form-field class=\"w-100\" appearance=\"outline\">\n <mat-label>\u0420\u0430\u0437\u043C\u0435\u0442\u043A\u0430</mat-label>\n <input\n matInput\n placeholder=\"\u0420\u0430\u0437\u043C\u0435\u0442\u043A\u0430\"\n [(ngModel)]=\"htmlRaw\"\n >\n </mat-form-field>\n </div>\n }\n }\n @if (selectedValue === HtmlRawTagDataConsts.TagName) {\n <div class=\"col-12\">\n <mat-form-field class=\"w-100\">\n <mat-label>\u0420\u0430\u0437\u043C\u0435\u0442\u043A\u0430</mat-label>\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)]=\"htmlRaw\"\n ></textarea>\n </mat-form-field>\n </div>\n }\n @if (selectedValue === 'text') {\n <div style=\"display: flex; justify-content: space-between; flex-wrap: wrap\">\n <div style=\"margin-bottom: 22px; overflow-x: auto;\">\n <mat-button-toggle-group\n [(ngModel)]=\"textTag\"\n [hideSingleSelectionIndicator]=\"true\"\n >\n @for (option of textTagOptions; track option) {\n <mat-button-toggle value=\"{{ option.tag }}\">\n {{ option.displayValue }}\n </mat-button-toggle>\n }\n </mat-button-toggle-group>\n </div>\n\n <div style=\"margin-bottom: 22px\">\n <mat-button-toggle-group\n [(ngModel)]=\"alignment\"\n [hideSingleSelectionIndicator]=\"true\"\n >\n @for (option of alignmentOptions; track option) {\n <mat-button-toggle value=\"{{ option.value }}\">\n <span class=\"text-align-icon\">\n <ng-container [ngTemplateOutlet]=\"textAlignToggleIcons\"\n [ngTemplateOutletContext]=\"{icon: option.value}\">\n </ng-container>\n </span>\n </mat-button-toggle>\n }\n </mat-button-toggle-group>\n </div>\n </div>\n <mat-form-field class=\"w-100\">\n <mat-label>\u0422\u0435\u043A\u0441\u0442</mat-label>\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 ></textarea>\n </mat-form-field>\n }\n\n <div class=\"col-12\">\n <button (click)=\"addTagClickHandler()\" 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()\" 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 special\">\n <mat-card-content>\n <div class=\"d-flex justify-content-between\">\n <div class=\"example-handle\" cdkDragHandle>\n <svg width=\"24\" height=\"24\" class=\"move-icon\">\n <use [attr.xlink:href]=\"'move-icon' | spriteIconPath\"></use>\n </svg>\n </div>\n <div>\n <div class=\"badge\" [matTooltip]=\"tag.tagDescription.tag\">\n <span class=\"text-align-icon\">\n <ng-container [ngTemplateOutlet]=\"tagButtonIcons\"\n [ngTemplateOutletContext]=\"{icon: tag.tagDescription.tag}\">\n </ng-container>\n </span>\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>\n }\n </div>\n</div>\n\n<ng-template #textAlignToggleIcons let-icon=\"icon\">\n <svg width=\"20\" height=\"20\">\n <use [attr.xlink:href]=\"setAlignButton(icon) | spriteIconPath\"></use>\n </svg>\n</ng-template>\n\n<ng-template #tagButtonIcons let-icon=\"icon\">\n @if (icon.indexOf('h') === 0 && icon.length === 2) {\n {{icon.toUpperCase()}}\n }\n @else {\n <svg width=\"20\" height=\"20\">\n <use [attr.xlink:href]=\"setTagButton(icon) | spriteIconPath\"></use>\n </svg>\n }\n</ng-template>", styles: [":host{--mat-standard-button-toggle-selected-state-background-color: #323E8B;--mat-standard-button-toggle-text-color: #323E8B;--mat-standard-button-toggle-selected-state-text-color: white;--mat-standard-button-toggle-height: 36px;--mat-standard-button-toggle-divider-color: #323E8B;--mdc-outlined-button-label-text-weight: 400;--mdc-outlined-button-label-text-color: #333333 !important;--mdc-outlined-button-container-shape: 30px;--mdc-outlined-button-outline-width: 2px;--mdc-outlined-button-container-height: 44px}:host ::ng-deep .mat-button-toggle-appearance-standard span.mat-button-toggle-label-content{padding:0 8px;min-width:36px}.text-align-icon,.mat-button-toggle .text-align-icon{color:#323e8b}.mat-button-toggle:hover,.mat-button-toggle:hover .text-align-icon{color:#747ebf}.mat-button-toggle-checked .text-align-icon{color:#fff}.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{width:44px;height:44px;border-radius:50%;border:1px solid #323E8B;display:flex;align-items:center;justify-content:center;color:#323e8b}.mat-card.special{border:1px solid #747EBF;border-radius:8px;box-shadow:none;margin:2px 2px 10px}.tags{display:flex;gap:10px;flex-wrap:wrap}.tag-item{display:flex;align-items:center;gap:5px;cursor:pointer;padding:10px 20px;border:1px solid #323E8B;border-radius:30px;background-color:#fff;color:#23262a;transition:.2s ease-in-out}.text-align-icon{color:#323e8b}.tag-item.active{background-color:#323e8b;color:#fff}.tag-item.active svg{color:#fff}.tag-item:hover{color:#747ebf;box-shadow:0 0 4px #747ebf}.tag-item:hover svg{color:#747ebf}@media (max-width: 768px){.tag-item:hover{color:inherit;box-shadow:none}.tag-item:hover svg{color:inherit}.tag-item:active{color:#747ebf;box-shadow:0 0 4px #747ebf}.tag-item:active svg{color:#747ebf}}.move-icon:hover{cursor:pointer;opacity:.7}.cdk-drag.cdk-drag-placeholder,.cdk-drag-preview{opacity:.5;transition:opacity .2s}.example-handle{color:#323e8b}\n"] }]
2460
+ ], 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 <div class=\"w-100\" style=\"margin-bottom: 22px\">\n <div class=\"tags\">\n @for (tag of tags; track tag) {\n <span class=\"tag-item\" (click)=\"selectTag(tag)\" [class.active]=\"selectedValue === tag.tag\">\n <span class=\"text-align-icon\">\n <ng-container [ngTemplateOutlet]=\"tagButtonIcons\"\n [ngTemplateOutletContext]=\"{icon: tag.tag}\">\n </ng-container>\n </span>\n {{tag.displayValue}}\n </span>\n }\n\n @if (useCustomWidgetsButton) {\n <span class=\"tag-item\" (click)=\"customWidgetsClickHandler()\">\n <span class=\"text-align-icon\">\n <ng-container [ngTemplateOutlet]=\"tagButtonIcons\"\n [ngTemplateOutletContext]=\"{icon: 'custom-widget'}\">\n </ng-container>\n </span>\n \u0414\u0440\u0443\u0433\u0438\u0435 \u0432\u0438\u0434\u0436\u0435\u0442\u044B\n </span>\n }\n \n </div>\n </div>\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 @if (selectedVideoPlayer === ExternalVideoSupportedTypes.Code) {\n <div class=\"col-12\">\n <mat-form-field class=\"w-100\" appearance=\"outline\">\n <mat-label>\u0420\u0430\u0437\u043C\u0435\u0442\u043A\u0430</mat-label>\n <input\n matInput\n placeholder=\"\u0420\u0430\u0437\u043C\u0435\u0442\u043A\u0430\"\n [(ngModel)]=\"htmlRaw\"\n >\n </mat-form-field>\n </div>\n }\n }\n @if (selectedValue === HtmlRawTagDataConsts.TagName) {\n <div class=\"col-12\">\n <mat-form-field class=\"w-100\">\n <mat-label>\u0420\u0430\u0437\u043C\u0435\u0442\u043A\u0430</mat-label>\n <textarea\n #autosize=\"cdkTextareaAutosize\"\n matInput\n cdkTextareaAutosize\n cdkAutosizeMinRows=\"1\"\n cdkAutosizeMaxRows=\"5\"\n placeholder=\"\u0420\u0430\u0437\u043C\u0435\u0442\u043A\u0430\"\n #textArea\n [(ngModel)]=\"htmlRaw\"\n ></textarea>\n </mat-form-field>\n </div>\n }\n @if (selectedValue === 'text') {\n <div style=\"display: flex; justify-content: space-between; flex-wrap: wrap\">\n <div style=\"margin-bottom: 22px; overflow-x: auto;\">\n <mat-button-toggle-group\n [(ngModel)]=\"textTag\"\n [hideSingleSelectionIndicator]=\"true\"\n >\n @for (option of textTagOptions; track option) {\n <mat-button-toggle value=\"{{ option.tag }}\">\n {{ option.displayValue }}\n </mat-button-toggle>\n }\n </mat-button-toggle-group>\n </div>\n\n <div style=\"margin-bottom: 22px\">\n <mat-button-toggle-group\n [(ngModel)]=\"alignment\"\n [hideSingleSelectionIndicator]=\"true\"\n >\n @for (option of alignmentOptions; track option) {\n <mat-button-toggle value=\"{{ option.value }}\">\n <span class=\"text-align-icon\">\n <ng-container [ngTemplateOutlet]=\"textAlignToggleIcons\"\n [ngTemplateOutletContext]=\"{icon: option.value}\">\n </ng-container>\n </span>\n </mat-button-toggle>\n }\n </mat-button-toggle-group>\n </div>\n </div>\n <mat-form-field class=\"w-100\">\n <mat-label>\u0422\u0435\u043A\u0441\u0442</mat-label>\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 ></textarea>\n </mat-form-field>\n }\n\n <div class=\"col-12\">\n <button (click)=\"addTagClickHandler()\" 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()\" 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 special\">\n <mat-card-content>\n <div class=\"d-flex justify-content-between\">\n <div class=\"example-handle\" cdkDragHandle>\n <svg width=\"24\" height=\"24\" class=\"move-icon\">\n <use [attr.xlink:href]=\"'move-icon' | spriteIconPath\"></use>\n </svg>\n </div>\n <div>\n <div class=\"badge\" [matTooltip]=\"tag.tagDescription.tag\">\n <span class=\"text-align-icon\">\n <ng-container [ngTemplateOutlet]=\"tagButtonIcons\"\n [ngTemplateOutletContext]=\"{icon: tag.tagDescription.tag}\">\n </ng-container>\n </span>\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>\n }\n </div>\n</div>\n\n<ng-template #textAlignToggleIcons let-icon=\"icon\">\n <svg width=\"20\" height=\"20\">\n <use [attr.xlink:href]=\"setAlignButton(icon) | spriteIconPath\"></use>\n </svg>\n</ng-template>\n\n<ng-template #tagButtonIcons let-icon=\"icon\">\n @if (icon.indexOf('h') === 0 && icon.length === 2) {\n {{icon.toUpperCase()}}\n }\n @else {\n <svg width=\"20\" height=\"20\">\n <use [attr.xlink:href]=\"setTagButton(icon) | spriteIconPath\"></use>\n </svg>\n }\n</ng-template>", styles: [":host{--mat-standard-button-toggle-selected-state-background-color: #323E8B;--mat-standard-button-toggle-text-color: #323E8B;--mat-standard-button-toggle-selected-state-text-color: white;--mat-standard-button-toggle-height: 36px;--mat-standard-button-toggle-divider-color: #323E8B;--mdc-outlined-button-label-text-weight: 400;--mdc-outlined-button-label-text-color: #333333 !important;--mdc-outlined-button-container-shape: 30px;--mdc-outlined-button-outline-width: 2px;--mdc-outlined-button-container-height: 44px}:host ::ng-deep .mat-button-toggle-appearance-standard span.mat-button-toggle-label-content{padding:0 8px;min-width:36px}.text-align-icon,.mat-button-toggle .text-align-icon{color:#323e8b}.mat-button-toggle:hover,.mat-button-toggle:hover .text-align-icon{color:#747ebf}.mat-button-toggle-checked .text-align-icon{color:#fff}.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{width:44px;height:44px;border-radius:50%;border:1px solid #323E8B;display:flex;align-items:center;justify-content:center;color:#323e8b}.mat-card.special{border:1px solid #747EBF;border-radius:8px;box-shadow:none;margin:2px 2px 10px}.tags{display:flex;gap:10px;flex-wrap:wrap}.tag-item{display:flex;align-items:center;gap:5px;cursor:pointer;padding:10px 20px;border:1px solid #323E8B;border-radius:30px;background-color:#fff;color:#23262a;transition:.2s ease-in-out}.text-align-icon{color:#323e8b}.tag-item.active{background-color:#323e8b;color:#fff}.tag-item.active svg{color:#fff}.tag-item:hover{color:#747ebf;box-shadow:0 0 4px #747ebf}.tag-item:hover svg{color:#747ebf}@media (max-width: 768px){.tag-item:hover{color:inherit;box-shadow:none}.tag-item:hover svg{color:inherit}.tag-item:active{color:#747ebf;box-shadow:0 0 4px #747ebf}.tag-item:active svg{color:#747ebf}}.move-icon:hover{cursor:pointer;opacity:.7}.cdk-drag.cdk-drag-placeholder,.cdk-drag-preview{opacity:.5;transition:opacity .2s}.example-handle{color:#323e8b}\n"] }]
2388
2461
  }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: undefined, decorators: [{
2389
2462
  type: Inject,
2390
2463
  args: [CrocoHtmlOptionsToken]
@@ -2431,13 +2504,14 @@ class HtmlViewComponent {
2431
2504
  this.html = "<body></body>";
2432
2505
  }
2433
2506
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: HtmlViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2434
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: HtmlViewComponent, isStandalone: true, selector: "croco-html-view", inputs: { html: "html" }, ngImport: i0, template: "<croco-html-xml-tag-view [data]=\"html | topreview\"></croco-html-xml-tag-view>", styles: [""], dependencies: [{ kind: "component", type: XmlTagViewComponent, selector: "croco-html-xml-tag-view", inputs: ["data"] }, { kind: "pipe", type: ToPreviewPipe, name: "topreview" }] }); }
2507
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: HtmlViewComponent, isStandalone: true, selector: "croco-html-view", inputs: { html: "html" }, ngImport: i0, template: "<croco-html-xml-tag-view [data]=\"html | topreview\"></croco-html-xml-tag-view>", dependencies: [{ kind: "component", type: XmlTagViewComponent, selector: "croco-html-xml-tag-view", inputs: ["data"] }, { kind: "pipe", type: ToPreviewPipe, name: "topreview" }] }); }
2435
2508
  }
2436
2509
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: HtmlViewComponent, decorators: [{
2437
2510
  type: Component,
2438
2511
  args: [{ selector: 'croco-html-view', standalone: true, imports: [XmlTagViewComponent, ToPreviewPipe], template: "<croco-html-xml-tag-view [data]=\"html | topreview\"></croco-html-xml-tag-view>" }]
2439
2512
  }], propDecorators: { html: [{
2440
- type: Input
2513
+ type: Input,
2514
+ args: [{ required: true }]
2441
2515
  }] } });
2442
2516
 
2443
2517
  class HtmlEditorSettingsModalComponent {
@@ -2644,7 +2718,6 @@ const EditorComponents = [
2644
2718
  CustomWidgetEditorComponent,
2645
2719
  ];
2646
2720
  const XmlComponents = [
2647
- XmlTagTableViewComponent,
2648
2721
  XmlTagViewComponent,
2649
2722
  XmlTagHtmlViewComponent,
2650
2723
  XmlTagTextViewComponent,
@@ -2710,13 +2783,13 @@ class CrocoHtmlModule {
2710
2783
  VkVideoPlayerComponent,
2711
2784
  YoutubeVideoPlayerComponent,
2712
2785
  DownloadFileButtonEditorComponent,
2713
- XmlTagDownloadFileButtonComponent, UploadFilesBtnComponent, HtmlViewComponent, XmlTagTableViewComponent, XmlTagViewComponent, XmlTagHtmlViewComponent, XmlTagTextViewComponent, XmlTagHeaderTextViewComponent, XmlTagHeaderInnerTextViewComponent, XmlTagExternalVideoComponent, HtmlRawViewComponent, FileImageTagViewComponent, XmlTagCustomWidgetComponent, HtmlViewComponent, MainEditorComponent, FileIdSelectComponent, TextEditorComponent, ImageEditorComponent, MainEditorBlockComponent, VisualEditorComponent, AddFilesBtnComponent, HtmlRawEditorComponent, CustomWidgetEditorComponent, TagToSpanPipe, ToPreviewPipe, ToHtmlBodyTagsPipe, ToPreviewHtmlPipe], exports: [UploadFilesBtnComponent, HtmlViewComponent, XmlTagTableViewComponent, XmlTagViewComponent, XmlTagHtmlViewComponent, XmlTagTextViewComponent, XmlTagHeaderTextViewComponent, XmlTagHeaderInnerTextViewComponent, XmlTagExternalVideoComponent, HtmlRawViewComponent, FileImageTagViewComponent, XmlTagCustomWidgetComponent, HtmlViewComponent, MainEditorComponent, FileIdSelectComponent, TextEditorComponent, ImageEditorComponent, MainEditorBlockComponent, VisualEditorComponent, AddFilesBtnComponent, HtmlRawEditorComponent, CustomWidgetEditorComponent, TagToSpanPipe, ToPreviewPipe, ToHtmlBodyTagsPipe, ToPreviewHtmlPipe] }); }
2786
+ XmlTagDownloadFileButtonComponent, UploadFilesBtnComponent, HtmlViewComponent, XmlTagViewComponent, XmlTagHtmlViewComponent, XmlTagTextViewComponent, XmlTagHeaderTextViewComponent, XmlTagHeaderInnerTextViewComponent, XmlTagExternalVideoComponent, HtmlRawViewComponent, FileImageTagViewComponent, XmlTagCustomWidgetComponent, HtmlViewComponent, MainEditorComponent, FileIdSelectComponent, TextEditorComponent, ImageEditorComponent, MainEditorBlockComponent, VisualEditorComponent, AddFilesBtnComponent, HtmlRawEditorComponent, CustomWidgetEditorComponent, TagToSpanPipe, ToPreviewPipe, ToHtmlBodyTagsPipe, ToPreviewHtmlPipe], exports: [UploadFilesBtnComponent, HtmlViewComponent, XmlTagViewComponent, XmlTagHtmlViewComponent, XmlTagTextViewComponent, XmlTagHeaderTextViewComponent, XmlTagHeaderInnerTextViewComponent, XmlTagExternalVideoComponent, HtmlRawViewComponent, FileImageTagViewComponent, XmlTagCustomWidgetComponent, HtmlViewComponent, MainEditorComponent, FileIdSelectComponent, TextEditorComponent, ImageEditorComponent, MainEditorBlockComponent, VisualEditorComponent, AddFilesBtnComponent, HtmlRawEditorComponent, CustomWidgetEditorComponent, TagToSpanPipe, ToPreviewPipe, ToHtmlBodyTagsPipe, ToPreviewHtmlPipe] }); }
2714
2787
  static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: CrocoHtmlModule, imports: [CommonModule,
2715
2788
  FormsModule,
2716
2789
  ReactiveFormsModule,
2717
2790
  NgSelectModule, MaterialModules, ErrorBannerComponent,
2718
2791
  DownloadFileButtonEditorComponent,
2719
- XmlTagDownloadFileButtonComponent, UploadFilesBtnComponent, HtmlViewComponent, XmlTagTableViewComponent, XmlTagViewComponent, HtmlViewComponent, MainEditorComponent, FileIdSelectComponent, TextEditorComponent, ImageEditorComponent, MainEditorBlockComponent, VisualEditorComponent, AddFilesBtnComponent, HtmlRawEditorComponent, CustomWidgetEditorComponent] }); }
2792
+ XmlTagDownloadFileButtonComponent, UploadFilesBtnComponent, HtmlViewComponent, XmlTagViewComponent, HtmlViewComponent, MainEditorComponent, FileIdSelectComponent, TextEditorComponent, ImageEditorComponent, MainEditorBlockComponent, VisualEditorComponent, AddFilesBtnComponent, HtmlRawEditorComponent, CustomWidgetEditorComponent] }); }
2720
2793
  }
2721
2794
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: CrocoHtmlModule, decorators: [{
2722
2795
  type: NgModule,
@@ -2748,5 +2821,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
2748
2821
  * Generated bundle index. Do not edit.
2749
2822
  */
2750
2823
 
2751
- export { AddFilesBtnComponent, AngularMaterialTableMethods, BodyTagsExtensions, BootstrapTableMethods, CrocoHtmlFileOptionsService, CrocoHtmlModule, CrocoHtmlOptionsToken, CustomWidgetEditorComponent, ExternalVideoEditorComponent, ExternalVideoPlayers, ExternalVideoSupportedTypes, ExternalVideoTagDataConsts, FileIdSelectComponent, FileImageTagDataConsts, FileImageTagViewComponent, FileType, HtmlRawEditorComponent, HtmlRawViewComponent, HtmlViewComponent, HtmlViewController, ImageEditorComponent, ImageMethods, MainEditorBlockComponent, MainEditorComponent, TableBuilder, TableMethods, TableTypes, TagToSpanPipe, TextEditorComponent, TextSimpleMethods, TextTag, TextTagDataConsts, TextTags, ToHtmlBodyTagsPipe, ToPreviewHtmlPipe, ToPreviewPipe, UploadFilesBtnComponent, VisualEditorComponent, XmlExtensions, XmlTagCustomWidgetComponent, XmlTagExternalVideoComponent, XmlTagHeaderInnerTextViewComponent, XmlTagHeaderTextViewComponent, XmlTagHtmlViewComponent, XmlTagTableViewComponent, XmlTagTextViewComponent, XmlTagViewComponent, defaultLinkForDownload, defaultLinkVk, defaultLinkYouTube };
2824
+ export { AddFilesBtnComponent, AngularMaterialTableMethods, BodyTagsExtensions, BootstrapTableMethods, CrocoHtmlFileOptionsService, CrocoHtmlModule, CrocoHtmlOptionsToken, CustomWidgetEditorComponent, ExternalVideoEditorComponent, ExternalVideoPlayers, ExternalVideoSupportedTypes, ExternalVideoTagDataConsts, FileIdSelectComponent, FileImageTagDataConsts, FileImageTagViewComponent, FileType, HtmlRawEditorComponent, HtmlRawViewComponent, HtmlViewComponent, HtmlViewController, ImageEditorComponent, ImageMethods, MainEditorBlockComponent, MainEditorComponent, TableBuilder, TableMethods, TableTypes, TagToSpanPipe, TextEditorComponent, TextSimpleMethods, TextTag, TextTags, ToHtmlBodyTagsPipe, ToPreviewHtmlPipe, ToPreviewPipe, UploadFilesBtnComponent, VisualEditorComponent, XmlExtensions, XmlTagCustomWidgetComponent, XmlTagExternalVideoComponent, XmlTagHeaderInnerTextViewComponent, XmlTagHeaderTextViewComponent, XmlTagHtmlViewComponent, XmlTagTextViewComponent, XmlTagViewComponent };
2752
2825
  //# sourceMappingURL=croco-html.mjs.map