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