croco-html 2.14.0 → 2.16.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/esm2022/lib/components/add-files-btn/add-files-btn.component.mjs +4 -3
- package/esm2022/lib/components/editor/external-video-block/external-video-block.component.mjs +7 -4
- package/esm2022/lib/components/editor/image-editor/image-editor.component.mjs +43 -8
- package/esm2022/lib/components/editor/visual-editor/visual-editor.component.mjs +4 -1
- package/esm2022/lib/croco-html.module.mjs +1 -1
- package/esm2022/lib/extensions/BodyTagsExtensions.mjs +9 -5
- package/esm2022/lib/extensions/HtmlRawTagDataConsts.mjs +4 -1
- package/esm2022/lib/extensions/ImageMethods.mjs +38 -1
- package/esm2022/lib/services/screen-width.service.mjs +24 -0
- package/fesm2022/croco-html.mjs +282 -184
- package/fesm2022/croco-html.mjs.map +1 -1
- package/lib/components/editor/image-editor/image-editor.component.d.ts +13 -3
- package/lib/extensions/HtmlRawTagDataConsts.d.ts +3 -0
- package/lib/extensions/ImageMethods.d.ts +13 -0
- package/lib/index.d.ts +7 -7
- package/lib/services/screen-width.service.d.ts +10 -0
- package/package.json +1 -1
package/fesm2022/croco-html.mjs
CHANGED
|
@@ -8,21 +8,25 @@ import { MatFormFieldModule, MatFormField, MatLabel } from '@angular/material/fo
|
|
|
8
8
|
import * as i1$4 from '@angular/forms';
|
|
9
9
|
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
|
10
10
|
import * as i1$1 from '@angular/platform-browser';
|
|
11
|
-
import * as i2$
|
|
11
|
+
import * as i2$4 from '@angular/material/table';
|
|
12
12
|
import { MatTable, MatColumnDef, MatHeaderCellDef, MatHeaderCell, MatCellDef, MatCell, MatHeaderRowDef, MatHeaderRow, MatRowDef, MatRow, MatTableModule } from '@angular/material/table';
|
|
13
13
|
import * as i27 from '@angular/material/icon';
|
|
14
14
|
import { MatIcon, MatIconModule } from '@angular/material/icon';
|
|
15
15
|
import * as i1$2 from '@angular/material/card';
|
|
16
16
|
import { MatCardModule, MatCard, MatCardContent } from '@angular/material/card';
|
|
17
|
+
import * as i2$1 from '@angular/material/input';
|
|
18
|
+
import { MatInputModule, MatInput } from '@angular/material/input';
|
|
17
19
|
import { CdkTextareaAutosize } from '@angular/cdk/text-field';
|
|
18
|
-
import * as
|
|
19
|
-
import { MatInput, MatInputModule } from '@angular/material/input';
|
|
20
|
-
import * as i2$1 from '@ng-select/ng-select';
|
|
20
|
+
import * as i2$2 from '@ng-select/ng-select';
|
|
21
21
|
import { NgSelectModule } from '@ng-select/ng-select';
|
|
22
22
|
import * as i29 from '@angular/material/button-toggle';
|
|
23
23
|
import { MatButtonToggleGroup, MatButtonToggle, MatButtonToggleModule } from '@angular/material/button-toggle';
|
|
24
24
|
import * as i28 from '@angular/cdk/drag-drop';
|
|
25
|
-
import { moveItemInArray, CdkDropList, CdkDrag,
|
|
25
|
+
import { CdkDragHandle, moveItemInArray, CdkDropList, CdkDrag, DragDropModule } from '@angular/cdk/drag-drop';
|
|
26
|
+
import { NgStyle, CommonModule } from '@angular/common';
|
|
27
|
+
import * as i22 from '@angular/material/slide-toggle';
|
|
28
|
+
import { MatSlideToggle, MatSlideToggleModule } from '@angular/material/slide-toggle';
|
|
29
|
+
import { BehaviorSubject, Subject, takeUntil } from 'rxjs';
|
|
26
30
|
import * as i24 from '@angular/material/core';
|
|
27
31
|
import { MatOption, MatNativeDateModule } from '@angular/material/core';
|
|
28
32
|
import * as i11 from '@angular/material/select';
|
|
@@ -32,9 +36,8 @@ import { MatProgressSpinner, MatProgressSpinnerModule } from '@angular/material/
|
|
|
32
36
|
import * as i8 from '@angular/material/tabs';
|
|
33
37
|
import { MatTabGroup, MatTab, MatTabsModule } from '@angular/material/tabs';
|
|
34
38
|
import * as i1$5 from 'ngx-clipboard';
|
|
35
|
-
import * as i2$
|
|
39
|
+
import * as i2$3 from '@angular/material/snack-bar';
|
|
36
40
|
import { MatSnackBarModule } from '@angular/material/snack-bar';
|
|
37
|
-
import { CommonModule } from '@angular/common';
|
|
38
41
|
import * as i12 from '@angular/material/tooltip';
|
|
39
42
|
import { MatTooltipModule } from '@angular/material/tooltip';
|
|
40
43
|
import * as i13 from '@angular/material/checkbox';
|
|
@@ -61,173 +64,11 @@ import * as i6 from '@angular/material/progress-bar';
|
|
|
61
64
|
import { MatProgressBarModule } from '@angular/material/progress-bar';
|
|
62
65
|
import * as i26 from '@angular/material/sidenav';
|
|
63
66
|
import { MatSidenavModule } from '@angular/material/sidenav';
|
|
64
|
-
import * as i22 from '@angular/material/slide-toggle';
|
|
65
|
-
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
|
|
66
67
|
import * as i23 from '@angular/material/tree';
|
|
67
68
|
import { MatTreeModule } from '@angular/material/tree';
|
|
68
69
|
import * as i1$6 from '@angular/material/badge';
|
|
69
70
|
import { MatBadgeModule } from '@angular/material/badge';
|
|
70
71
|
|
|
71
|
-
class FileImageTagDataConsts {
|
|
72
|
-
static { this.TagName = "file-image"; }
|
|
73
|
-
static { this.FileIdAttrName = "file-id"; }
|
|
74
|
-
}
|
|
75
|
-
class ImageMethods {
|
|
76
|
-
static buildUrl(fileId, sizeType, options) {
|
|
77
|
-
if (fileId === null || fileId === undefined) {
|
|
78
|
-
return null;
|
|
79
|
-
}
|
|
80
|
-
return options.publicImageResizedUrlFormat
|
|
81
|
-
.replace("{sizeType}", sizeType)
|
|
82
|
-
.replace("{fileId}", fileId.toString());
|
|
83
|
-
}
|
|
84
|
-
static buildSmallUrl(fileId, options) {
|
|
85
|
-
return ImageMethods.buildUrl(fileId, "Small", options);
|
|
86
|
-
}
|
|
87
|
-
static buildMediumUrl(fileId, options) {
|
|
88
|
-
return ImageMethods.buildUrl(fileId, "Medium", options);
|
|
89
|
-
}
|
|
90
|
-
static ExtractImage(elem, options) {
|
|
91
|
-
let fileId = +elem.getAttribute(FileImageTagDataConsts.FileIdAttrName);
|
|
92
|
-
let src = ImageMethods.buildMediumUrl(fileId, options);
|
|
93
|
-
return {
|
|
94
|
-
type: FileImageTagDataConsts.TagName,
|
|
95
|
-
data: {
|
|
96
|
-
src,
|
|
97
|
-
fileId: fileId,
|
|
98
|
-
}
|
|
99
|
-
};
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
class FileUploadService {
|
|
104
|
-
constructor(_httpClient, baseUrl) {
|
|
105
|
-
this._httpClient = _httpClient;
|
|
106
|
-
this.baseUrl = baseUrl;
|
|
107
|
-
}
|
|
108
|
-
postFiles(files, createLocalCopiesNow = false) {
|
|
109
|
-
const formData = new FormData();
|
|
110
|
-
for (let i = 0; i < files.length; i++) {
|
|
111
|
-
var fileToUpload = files.item(i);
|
|
112
|
-
formData.append(`fileKey${i}`, fileToUpload, fileToUpload?.name);
|
|
113
|
-
}
|
|
114
|
-
return this.postFilesInner(formData, createLocalCopiesNow);
|
|
115
|
-
}
|
|
116
|
-
postFilesInner(formData, createLocalCopiesNow = false, withProgress = false) {
|
|
117
|
-
let endpoint = createLocalCopiesNow
|
|
118
|
-
? this.baseUrl + 'api/files/upload/now/with-handlers'
|
|
119
|
-
: this.baseUrl + 'Api/Files/UploadFiles';
|
|
120
|
-
return this._httpClient.post(endpoint, formData, withProgress ? { reportProgress: true, observe: 'events' } : undefined);
|
|
121
|
-
}
|
|
122
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: FileUploadService, deps: [{ token: i1.HttpClient }, { token: 'BASE_URL' }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
123
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: FileUploadService, providedIn: 'root' }); }
|
|
124
|
-
}
|
|
125
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: FileUploadService, decorators: [{
|
|
126
|
-
type: Injectable,
|
|
127
|
-
args: [{ providedIn: 'root' }]
|
|
128
|
-
}], ctorParameters: () => [{ type: i1.HttpClient }, { type: undefined, decorators: [{
|
|
129
|
-
type: Inject,
|
|
130
|
-
args: ['BASE_URL']
|
|
131
|
-
}] }] });
|
|
132
|
-
|
|
133
|
-
class UploadFilesBtnComponent {
|
|
134
|
-
constructor(_fileUploadService) {
|
|
135
|
-
this._fileUploadService = _fileUploadService;
|
|
136
|
-
this.extAccepts = "*/*";
|
|
137
|
-
this.isMultiple = true;
|
|
138
|
-
this.btnText = "Загрузить файлы";
|
|
139
|
-
this.createLocalCopiesNow = true;
|
|
140
|
-
this.hidden = false;
|
|
141
|
-
this.postFilesStarted = new EventEmitter();
|
|
142
|
-
this.onFilesUploaded = new EventEmitter();
|
|
143
|
-
}
|
|
144
|
-
handleFileInput(files) {
|
|
145
|
-
this.postFilesStarted.emit({
|
|
146
|
-
filesCount: files.length,
|
|
147
|
-
createLocalCopiesNow: this.createLocalCopiesNow
|
|
148
|
-
});
|
|
149
|
-
this._fileUploadService.postFiles(files, this.createLocalCopiesNow).subscribe(data => {
|
|
150
|
-
this.onFilesUploaded.emit(data);
|
|
151
|
-
});
|
|
152
|
-
}
|
|
153
|
-
clickFileInput() {
|
|
154
|
-
this.fileInput.nativeElement.click();
|
|
155
|
-
}
|
|
156
|
-
ngOnInit() {
|
|
157
|
-
}
|
|
158
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: UploadFilesBtnComponent, deps: [{ token: FileUploadService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
159
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.4", type: UploadFilesBtnComponent, isStandalone: true, 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: MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }] }); }
|
|
160
|
-
}
|
|
161
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: UploadFilesBtnComponent, decorators: [{
|
|
162
|
-
type: Component,
|
|
163
|
-
args: [{ selector: 'croco-app-upload-files-btn', standalone: true, imports: [MatButton], template: "<button [hidden]=\"hidden\" mat-raised-button color=\"primary\" (click)=\"filesInput.click()\">{{btnText}}</button>\n<input [hidden]=\"true\" [accept]=\"extAccepts\" [multiple]=\"isMultiple\" type=\"file\" #filesInput (change)=\"handleFileInput($event.target.files)\" />" }]
|
|
164
|
-
}], ctorParameters: () => [{ type: FileUploadService }], propDecorators: { fileInput: [{
|
|
165
|
-
type: ViewChild,
|
|
166
|
-
args: ['filesInput']
|
|
167
|
-
}], extAccepts: [{
|
|
168
|
-
type: Input
|
|
169
|
-
}], isMultiple: [{
|
|
170
|
-
type: Input
|
|
171
|
-
}], btnText: [{
|
|
172
|
-
type: Input
|
|
173
|
-
}], createLocalCopiesNow: [{
|
|
174
|
-
type: Input
|
|
175
|
-
}], hidden: [{
|
|
176
|
-
type: Input
|
|
177
|
-
}], postFilesStarted: [{
|
|
178
|
-
type: Output
|
|
179
|
-
}], onFilesUploaded: [{
|
|
180
|
-
type: Output
|
|
181
|
-
}] } });
|
|
182
|
-
|
|
183
|
-
class AddFilesBtnComponent {
|
|
184
|
-
constructor() {
|
|
185
|
-
this.postFilesStarted = new EventEmitter();
|
|
186
|
-
this.fileIds = [];
|
|
187
|
-
this.filesTagsReady = new EventEmitter();
|
|
188
|
-
}
|
|
189
|
-
postFilesStartedEventHandler(data) {
|
|
190
|
-
this.postFilesStarted.emit(data);
|
|
191
|
-
}
|
|
192
|
-
filesUploadedHandler(data) {
|
|
193
|
-
this.fileIds = data.responseObject;
|
|
194
|
-
let fileTags = [];
|
|
195
|
-
for (let i = 0; i < this.fileIds.length; i++) {
|
|
196
|
-
let fileTag = {
|
|
197
|
-
presentOrEdit: true,
|
|
198
|
-
tagDescription: {
|
|
199
|
-
tag: FileImageTagDataConsts.TagName,
|
|
200
|
-
displayValue: "Изображение"
|
|
201
|
-
},
|
|
202
|
-
attributes: {
|
|
203
|
-
[FileImageTagDataConsts.FileIdAttrName]: this.fileIds[i]
|
|
204
|
-
},
|
|
205
|
-
innerHtml: ""
|
|
206
|
-
};
|
|
207
|
-
fileTags.push(fileTag);
|
|
208
|
-
}
|
|
209
|
-
this.filesTagsReady.emit(fileTags);
|
|
210
|
-
}
|
|
211
|
-
handleClick() {
|
|
212
|
-
this.fakeBtn.clickFileInput();
|
|
213
|
-
}
|
|
214
|
-
ngOnInit() {
|
|
215
|
-
}
|
|
216
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: AddFilesBtnComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
217
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.4", type: AddFilesBtnComponent, isStandalone: true, 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: UploadFilesBtnComponent, selector: "croco-app-upload-files-btn", inputs: ["extAccepts", "isMultiple", "btnText", "createLocalCopiesNow", "hidden"], outputs: ["postFilesStarted", "onFilesUploaded"] }, { kind: "component", type: MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }] }); }
|
|
218
|
-
}
|
|
219
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: AddFilesBtnComponent, decorators: [{
|
|
220
|
-
type: Component,
|
|
221
|
-
args: [{ selector: 'croco-html-add-files-btn', standalone: true, imports: [UploadFilesBtnComponent, MatButton], 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>" }]
|
|
222
|
-
}], ctorParameters: () => [], propDecorators: { postFilesStarted: [{
|
|
223
|
-
type: Output
|
|
224
|
-
}], fakeBtn: [{
|
|
225
|
-
type: ViewChild,
|
|
226
|
-
args: ["fakeBtn"]
|
|
227
|
-
}], filesTagsReady: [{
|
|
228
|
-
type: Output
|
|
229
|
-
}] } });
|
|
230
|
-
|
|
231
72
|
class AngularMaterialTableMethods {
|
|
232
73
|
static getAngularMaterialTableData(columns, rows) {
|
|
233
74
|
let data = [];
|
|
@@ -292,6 +133,75 @@ class AngularMaterialTableMethods {
|
|
|
292
133
|
}
|
|
293
134
|
}
|
|
294
135
|
|
|
136
|
+
class FileImageTagDataConsts {
|
|
137
|
+
static { this.TagName = "file-image"; }
|
|
138
|
+
static { this.FileIdAttrName = "file-id"; }
|
|
139
|
+
static { this.ScreenMediaRequest = "screen-media-request"; }
|
|
140
|
+
static { this.DefaultValueForFileImage = "screen-width:1200,max-image-height:300;screen-width:900,max-image-height:200"; }
|
|
141
|
+
static { this.ScreenWidth = 'screen-width'; }
|
|
142
|
+
static { this.MaxImageHeight = 'max-image-height'; }
|
|
143
|
+
}
|
|
144
|
+
class ImageMethods {
|
|
145
|
+
static buildUrl(fileId, sizeType, options) {
|
|
146
|
+
if (fileId === null || fileId === undefined) {
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
return options.publicImageResizedUrlFormat
|
|
150
|
+
.replace("{sizeType}", sizeType)
|
|
151
|
+
.replace("{fileId}", fileId.toString());
|
|
152
|
+
}
|
|
153
|
+
static buildSmallUrl(fileId, options) {
|
|
154
|
+
return ImageMethods.buildUrl(fileId, "Small", options);
|
|
155
|
+
}
|
|
156
|
+
static buildMediumUrl(fileId, options) {
|
|
157
|
+
return ImageMethods.buildUrl(fileId, "Medium", options);
|
|
158
|
+
}
|
|
159
|
+
static ExtractImage(elem, options) {
|
|
160
|
+
let fileId = +elem.getAttribute(FileImageTagDataConsts.FileIdAttrName);
|
|
161
|
+
let src = ImageMethods.buildMediumUrl(fileId, options);
|
|
162
|
+
return {
|
|
163
|
+
type: FileImageTagDataConsts.TagName,
|
|
164
|
+
data: {
|
|
165
|
+
src,
|
|
166
|
+
fileId: fileId,
|
|
167
|
+
screenMediaRequest: elem.getAttribute(FileImageTagDataConsts.ScreenMediaRequest)
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
static { this.mediaRequestStringToArrayParser = (data) => {
|
|
172
|
+
if (!data.length) {
|
|
173
|
+
return [];
|
|
174
|
+
}
|
|
175
|
+
return data.split(';').reduce((requests, currentValue) => {
|
|
176
|
+
requests.push({
|
|
177
|
+
screenWidth: ImageMethods.createMediaRequestValue(currentValue.split(','), FileImageTagDataConsts.ScreenWidth),
|
|
178
|
+
maxImageHeight: ImageMethods.createMediaRequestValue(currentValue.split(','), FileImageTagDataConsts.MaxImageHeight),
|
|
179
|
+
});
|
|
180
|
+
return requests;
|
|
181
|
+
}, []);
|
|
182
|
+
}; }
|
|
183
|
+
static createMediaRequestValue(arr, attribute) {
|
|
184
|
+
return +arr.find(el => el.includes(attribute)).match(/\d+/g).join('');
|
|
185
|
+
}
|
|
186
|
+
static { this.mediaRequestsArrayToStringParser = (data) => {
|
|
187
|
+
if (!data.length) {
|
|
188
|
+
return '';
|
|
189
|
+
}
|
|
190
|
+
return data.map(el => `${FileImageTagDataConsts.ScreenWidth}:${el.screenWidth},${FileImageTagDataConsts.MaxImageHeight}:${el.maxImageHeight}`).join(';');
|
|
191
|
+
}; }
|
|
192
|
+
static { this.screenSizeChanged = (screenSize, requests) => {
|
|
193
|
+
let newSize = null;
|
|
194
|
+
requests
|
|
195
|
+
.sort((a, b) => a.screenWidth > b.screenWidth ? -1 : 1)
|
|
196
|
+
.forEach((el, index) => {
|
|
197
|
+
if (screenSize < +el.screenWidth) {
|
|
198
|
+
newSize = el.maxImageHeight;
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
return newSize;
|
|
202
|
+
}; }
|
|
203
|
+
}
|
|
204
|
+
|
|
295
205
|
var EAlignments;
|
|
296
206
|
(function (EAlignments) {
|
|
297
207
|
EAlignments["Left"] = "left";
|
|
@@ -698,6 +608,9 @@ class HtmlExtractionMethods {
|
|
|
698
608
|
|
|
699
609
|
class HtmlRawTagDataConsts {
|
|
700
610
|
static { this.TagName = "html-raw"; }
|
|
611
|
+
static { this.ScreenWidth = "screen-width"; }
|
|
612
|
+
static { this.MaxImageHeight = "max-image-height"; }
|
|
613
|
+
static { this.MediaRequest = " media-request"; }
|
|
701
614
|
}
|
|
702
615
|
|
|
703
616
|
class Tags {
|
|
@@ -757,12 +670,13 @@ class BodyTagsExtensions {
|
|
|
757
670
|
return result;
|
|
758
671
|
}
|
|
759
672
|
static imageTagToHtml(imageTag) {
|
|
760
|
-
|
|
761
|
-
|
|
673
|
+
let fileIdAttr = "";
|
|
674
|
+
let screenMediaRequestAttr = "";
|
|
675
|
+
let attrValue = imageTag.attributes[FileImageTagDataConsts.FileIdAttrName];
|
|
762
676
|
if (imageTag.attributes.hasOwnProperty(FileImageTagDataConsts.FileIdAttrName) && attrValue) {
|
|
763
|
-
|
|
677
|
+
fileIdAttr = `${FileImageTagDataConsts.FileIdAttrName}="${attrValue}"`;
|
|
764
678
|
}
|
|
765
|
-
return `<${FileImageTagDataConsts.TagName} ${
|
|
679
|
+
return `<${FileImageTagDataConsts.TagName} ${fileIdAttr} ${FileImageTagDataConsts.ScreenMediaRequest}="${imageTag.attributes[FileImageTagDataConsts.ScreenMediaRequest]}"></${FileImageTagDataConsts.TagName}>`;
|
|
766
680
|
}
|
|
767
681
|
static getBodyTags(html, options) {
|
|
768
682
|
let result = HtmlExtractionMethods.transformHtmlStringToBlocks(html, options);
|
|
@@ -790,6 +704,9 @@ class BodyTagsExtensions {
|
|
|
790
704
|
if (fileData.fileId) {
|
|
791
705
|
attrs[FileImageTagDataConsts.FileIdAttrName] = fileData.fileId;
|
|
792
706
|
}
|
|
707
|
+
if (fileData.screenMediaRequest) {
|
|
708
|
+
attrs[FileImageTagDataConsts.ScreenMediaRequest] = fileData.screenMediaRequest;
|
|
709
|
+
}
|
|
793
710
|
return {
|
|
794
711
|
presentOrEdit: true,
|
|
795
712
|
tagDescription: {
|
|
@@ -895,6 +812,135 @@ class TableBuilder {
|
|
|
895
812
|
}
|
|
896
813
|
}
|
|
897
814
|
|
|
815
|
+
class FileUploadService {
|
|
816
|
+
constructor(_httpClient, baseUrl) {
|
|
817
|
+
this._httpClient = _httpClient;
|
|
818
|
+
this.baseUrl = baseUrl;
|
|
819
|
+
}
|
|
820
|
+
postFiles(files, createLocalCopiesNow = false) {
|
|
821
|
+
const formData = new FormData();
|
|
822
|
+
for (let i = 0; i < files.length; i++) {
|
|
823
|
+
var fileToUpload = files.item(i);
|
|
824
|
+
formData.append(`fileKey${i}`, fileToUpload, fileToUpload?.name);
|
|
825
|
+
}
|
|
826
|
+
return this.postFilesInner(formData, createLocalCopiesNow);
|
|
827
|
+
}
|
|
828
|
+
postFilesInner(formData, createLocalCopiesNow = false, withProgress = false) {
|
|
829
|
+
let endpoint = createLocalCopiesNow
|
|
830
|
+
? this.baseUrl + 'api/files/upload/now/with-handlers'
|
|
831
|
+
: this.baseUrl + 'Api/Files/UploadFiles';
|
|
832
|
+
return this._httpClient.post(endpoint, formData, withProgress ? { reportProgress: true, observe: 'events' } : undefined);
|
|
833
|
+
}
|
|
834
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: FileUploadService, deps: [{ token: i1.HttpClient }, { token: 'BASE_URL' }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
835
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: FileUploadService, providedIn: 'root' }); }
|
|
836
|
+
}
|
|
837
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: FileUploadService, decorators: [{
|
|
838
|
+
type: Injectable,
|
|
839
|
+
args: [{ providedIn: 'root' }]
|
|
840
|
+
}], ctorParameters: () => [{ type: i1.HttpClient }, { type: undefined, decorators: [{
|
|
841
|
+
type: Inject,
|
|
842
|
+
args: ['BASE_URL']
|
|
843
|
+
}] }] });
|
|
844
|
+
|
|
845
|
+
class UploadFilesBtnComponent {
|
|
846
|
+
constructor(_fileUploadService) {
|
|
847
|
+
this._fileUploadService = _fileUploadService;
|
|
848
|
+
this.extAccepts = "*/*";
|
|
849
|
+
this.isMultiple = true;
|
|
850
|
+
this.btnText = "Загрузить файлы";
|
|
851
|
+
this.createLocalCopiesNow = true;
|
|
852
|
+
this.hidden = false;
|
|
853
|
+
this.postFilesStarted = new EventEmitter();
|
|
854
|
+
this.onFilesUploaded = new EventEmitter();
|
|
855
|
+
}
|
|
856
|
+
handleFileInput(files) {
|
|
857
|
+
this.postFilesStarted.emit({
|
|
858
|
+
filesCount: files.length,
|
|
859
|
+
createLocalCopiesNow: this.createLocalCopiesNow
|
|
860
|
+
});
|
|
861
|
+
this._fileUploadService.postFiles(files, this.createLocalCopiesNow).subscribe(data => {
|
|
862
|
+
this.onFilesUploaded.emit(data);
|
|
863
|
+
});
|
|
864
|
+
}
|
|
865
|
+
clickFileInput() {
|
|
866
|
+
this.fileInput.nativeElement.click();
|
|
867
|
+
}
|
|
868
|
+
ngOnInit() {
|
|
869
|
+
}
|
|
870
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: UploadFilesBtnComponent, deps: [{ token: FileUploadService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
871
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.4", type: UploadFilesBtnComponent, isStandalone: true, 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: MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }] }); }
|
|
872
|
+
}
|
|
873
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: UploadFilesBtnComponent, decorators: [{
|
|
874
|
+
type: Component,
|
|
875
|
+
args: [{ selector: 'croco-app-upload-files-btn', standalone: true, imports: [MatButton], template: "<button [hidden]=\"hidden\" mat-raised-button color=\"primary\" (click)=\"filesInput.click()\">{{btnText}}</button>\n<input [hidden]=\"true\" [accept]=\"extAccepts\" [multiple]=\"isMultiple\" type=\"file\" #filesInput (change)=\"handleFileInput($event.target.files)\" />" }]
|
|
876
|
+
}], ctorParameters: () => [{ type: FileUploadService }], propDecorators: { fileInput: [{
|
|
877
|
+
type: ViewChild,
|
|
878
|
+
args: ['filesInput']
|
|
879
|
+
}], extAccepts: [{
|
|
880
|
+
type: Input
|
|
881
|
+
}], isMultiple: [{
|
|
882
|
+
type: Input
|
|
883
|
+
}], btnText: [{
|
|
884
|
+
type: Input
|
|
885
|
+
}], createLocalCopiesNow: [{
|
|
886
|
+
type: Input
|
|
887
|
+
}], hidden: [{
|
|
888
|
+
type: Input
|
|
889
|
+
}], postFilesStarted: [{
|
|
890
|
+
type: Output
|
|
891
|
+
}], onFilesUploaded: [{
|
|
892
|
+
type: Output
|
|
893
|
+
}] } });
|
|
894
|
+
|
|
895
|
+
class AddFilesBtnComponent {
|
|
896
|
+
constructor() {
|
|
897
|
+
this.postFilesStarted = new EventEmitter();
|
|
898
|
+
this.fileIds = [];
|
|
899
|
+
this.filesTagsReady = new EventEmitter();
|
|
900
|
+
}
|
|
901
|
+
postFilesStartedEventHandler(data) {
|
|
902
|
+
this.postFilesStarted.emit(data);
|
|
903
|
+
}
|
|
904
|
+
filesUploadedHandler(data) {
|
|
905
|
+
this.fileIds = data.responseObject;
|
|
906
|
+
let fileTags = [];
|
|
907
|
+
for (let i = 0; i < this.fileIds.length; i++) {
|
|
908
|
+
let fileTag = {
|
|
909
|
+
presentOrEdit: true,
|
|
910
|
+
tagDescription: {
|
|
911
|
+
tag: FileImageTagDataConsts.TagName,
|
|
912
|
+
displayValue: "Изображение"
|
|
913
|
+
},
|
|
914
|
+
attributes: {
|
|
915
|
+
[FileImageTagDataConsts.FileIdAttrName]: this.fileIds[i],
|
|
916
|
+
[FileImageTagDataConsts.ScreenMediaRequest]: FileImageTagDataConsts.DefaultValueForFileImage
|
|
917
|
+
},
|
|
918
|
+
innerHtml: ""
|
|
919
|
+
};
|
|
920
|
+
fileTags.push(fileTag);
|
|
921
|
+
}
|
|
922
|
+
this.filesTagsReady.emit(fileTags);
|
|
923
|
+
}
|
|
924
|
+
handleClick() {
|
|
925
|
+
this.fakeBtn.clickFileInput();
|
|
926
|
+
}
|
|
927
|
+
ngOnInit() {
|
|
928
|
+
}
|
|
929
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: AddFilesBtnComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
930
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.4", type: AddFilesBtnComponent, isStandalone: true, 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: UploadFilesBtnComponent, selector: "croco-app-upload-files-btn", inputs: ["extAccepts", "isMultiple", "btnText", "createLocalCopiesNow", "hidden"], outputs: ["postFilesStarted", "onFilesUploaded"] }, { kind: "component", type: MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }] }); }
|
|
931
|
+
}
|
|
932
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: AddFilesBtnComponent, decorators: [{
|
|
933
|
+
type: Component,
|
|
934
|
+
args: [{ selector: 'croco-html-add-files-btn', standalone: true, imports: [UploadFilesBtnComponent, MatButton], 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>" }]
|
|
935
|
+
}], ctorParameters: () => [], propDecorators: { postFilesStarted: [{
|
|
936
|
+
type: Output
|
|
937
|
+
}], fakeBtn: [{
|
|
938
|
+
type: ViewChild,
|
|
939
|
+
args: ["fakeBtn"]
|
|
940
|
+
}], filesTagsReady: [{
|
|
941
|
+
type: Output
|
|
942
|
+
}] } });
|
|
943
|
+
|
|
898
944
|
class YoutubeVideoPlayerComponent {
|
|
899
945
|
set link(link) {
|
|
900
946
|
this.safeUrl = this.sanitizer.bypassSecurityTrustResourceUrl(link);
|
|
@@ -1246,14 +1292,15 @@ class ExternalVideoBlockComponent {
|
|
|
1246
1292
|
this.tagData.link = src;
|
|
1247
1293
|
}
|
|
1248
1294
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: ExternalVideoBlockComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1249
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.4", type: ExternalVideoBlockComponent, isStandalone: true, 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 {{linkText}}: {{tagData.link}}\n }\n @case (ExternalVideoSupportedTypes.Youtube) {\n {{linkText}}: {{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 <mat-form-field class=\"w-100\">\n <mat-label>\n {{linkText}}\n </mat-label>\n <input matInput placeholder=\"{{linkText}}\"\n autocomplete=\"off\"\n [(ngModel)]=\"tagData.link\"\n (ngModelChange)=\"linkChanged()\">\n </mat-form-field>\n </div>\n}\n", styles: [".video-player{margin:0 auto;max-width:640px;width:100%;height:360px}@media screen and (max-width: 760px){.video-player{height:300px}}@media screen and (max-width: 540px){.video-player{height:250px}}@media screen and (max-width: 450px){.video-player{height:200px}}@media screen and (max-width: 380px){.video-player{height:180px}}\n"], dependencies: [{ kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i1$3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i1$3.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: XmlTagExternalVideoComponent, selector: "croco-html-xml-tag-external-video", inputs: ["data", "tagData"] }] }); }
|
|
1295
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.4", type: ExternalVideoBlockComponent, isStandalone: true, 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 {{linkText}}: {{tagData.link}}\n }\n @case (ExternalVideoSupportedTypes.Youtube) {\n {{linkText}}: {{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 <mat-form-field class=\"w-100\">\n <mat-label>\n {{linkText}}\n </mat-label>\n <input matInput placeholder=\"{{linkText}}\"\n autocomplete=\"off\"\n [(ngModel)]=\"tagData.link\"\n (ngModelChange)=\"linkChanged()\">\n </mat-form-field>\n </div>\n}\n", styles: [".video-player{margin:0 auto;max-width:640px;width:100%;height:360px}@media screen and (max-width: 760px){.video-player{height:300px}}@media screen and (max-width: 540px){.video-player{height:250px}}@media screen and (max-width: 450px){.video-player{height:200px}}@media screen and (max-width: 380px){.video-player{height:180px}}\n"], dependencies: [{ kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i1$3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i1$3.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i2$1.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: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: XmlTagExternalVideoComponent, selector: "croco-html-xml-tag-external-video", inputs: ["data", "tagData"] }] }); }
|
|
1250
1296
|
}
|
|
1251
1297
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: ExternalVideoBlockComponent, decorators: [{
|
|
1252
1298
|
type: Component,
|
|
1253
1299
|
args: [{ selector: 'croco-html-external-video-block', standalone: true, imports: [
|
|
1254
1300
|
MatFormFieldModule,
|
|
1301
|
+
MatInputModule,
|
|
1255
1302
|
FormsModule,
|
|
1256
|
-
XmlTagExternalVideoComponent
|
|
1303
|
+
XmlTagExternalVideoComponent,
|
|
1257
1304
|
], template: "@if (tag.presentOrEdit) {\n <div>\n <div>\n @switch (tagData.type) {\n @case (ExternalVideoSupportedTypes.VkVideo) {\n {{linkText}}: {{tagData.link}}\n }\n @case (ExternalVideoSupportedTypes.Youtube) {\n {{linkText}}: {{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 <mat-form-field class=\"w-100\">\n <mat-label>\n {{linkText}}\n </mat-label>\n <input matInput placeholder=\"{{linkText}}\"\n autocomplete=\"off\"\n [(ngModel)]=\"tagData.link\"\n (ngModelChange)=\"linkChanged()\">\n </mat-form-field>\n </div>\n}\n", styles: [".video-player{margin:0 auto;max-width:640px;width:100%;height:360px}@media screen and (max-width: 760px){.video-player{height:300px}}@media screen and (max-width: 540px){.video-player{height:250px}}@media screen and (max-width: 450px){.video-player{height:200px}}@media screen and (max-width: 380px){.video-player{height:180px}}\n"] }]
|
|
1258
1305
|
}], propDecorators: { tag: [{
|
|
1259
1306
|
type: Input
|
|
@@ -1355,7 +1402,7 @@ class FileIdSelectComponent {
|
|
|
1355
1402
|
this.loadFiles();
|
|
1356
1403
|
}
|
|
1357
1404
|
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 }); }
|
|
1358
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.4", type: FileIdSelectComponent, isStandalone: true, selector: "croco-html-file-id-select", inputs: { labelText: "labelText", fileId: "fileId" }, outputs: { fileId: "fileId", onFileIdChanged: "onFileIdChanged" }, usesOnChanges: true, ngImport: i0, template: "<div>\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: "ngmodule", type: NgSelectModule }, { kind: "component", type: i2$
|
|
1405
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.4", type: FileIdSelectComponent, isStandalone: true, selector: "croco-html-file-id-select", inputs: { labelText: "labelText", fileId: "fileId" }, outputs: { fileId: "fileId", onFileIdChanged: "onFileIdChanged" }, usesOnChanges: true, ngImport: i0, template: "<div>\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: "ngmodule", type: NgSelectModule }, { kind: "component", type: i2$2.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: i2$2.NgOptionTemplateDirective, selector: "[ng-option-tmp]" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] }); }
|
|
1359
1406
|
}
|
|
1360
1407
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: FileIdSelectComponent, decorators: [{
|
|
1361
1408
|
type: Component,
|
|
@@ -1373,15 +1420,45 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImpor
|
|
|
1373
1420
|
type: Output
|
|
1374
1421
|
}] } });
|
|
1375
1422
|
|
|
1423
|
+
class ScreenWidthService {
|
|
1424
|
+
constructor() {
|
|
1425
|
+
this.screenWidth = new BehaviorSubject(window.innerWidth);
|
|
1426
|
+
window.addEventListener('resize', this.onResize.bind(this));
|
|
1427
|
+
}
|
|
1428
|
+
onResize(event) {
|
|
1429
|
+
this.screenWidth.next(window.innerWidth);
|
|
1430
|
+
}
|
|
1431
|
+
getScreenWidth() {
|
|
1432
|
+
return this.screenWidth.asObservable();
|
|
1433
|
+
}
|
|
1434
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: ScreenWidthService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1435
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: ScreenWidthService, providedIn: 'root' }); }
|
|
1436
|
+
}
|
|
1437
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: ScreenWidthService, decorators: [{
|
|
1438
|
+
type: Injectable,
|
|
1439
|
+
args: [{
|
|
1440
|
+
providedIn: 'root'
|
|
1441
|
+
}]
|
|
1442
|
+
}], ctorParameters: () => [] });
|
|
1443
|
+
|
|
1376
1444
|
class ImageEditorComponent {
|
|
1377
1445
|
onErrorHandler() {
|
|
1378
1446
|
this.hasImageError = true;
|
|
1379
1447
|
}
|
|
1380
|
-
constructor(_options) {
|
|
1448
|
+
constructor(_options, screenWidth) {
|
|
1381
1449
|
this._options = _options;
|
|
1382
1450
|
this.hasImageError = false;
|
|
1383
1451
|
this.searchOrEdit = "search";
|
|
1452
|
+
this.requests = [];
|
|
1453
|
+
this.imageMaxHeight = null;
|
|
1454
|
+
this.isShowMediaRequest = false;
|
|
1455
|
+
this.unsubscribe = new Subject();
|
|
1384
1456
|
this.onTagUpdated = new EventEmitter();
|
|
1457
|
+
screenWidth.getScreenWidth()
|
|
1458
|
+
.pipe(takeUntil(this.unsubscribe))
|
|
1459
|
+
.subscribe(screenWidth => {
|
|
1460
|
+
this.imageMaxHeight = ImageMethods.screenSizeChanged(screenWidth, this.requests);
|
|
1461
|
+
});
|
|
1385
1462
|
}
|
|
1386
1463
|
getSrc() {
|
|
1387
1464
|
return ImageMethods.buildUrl(this.tag.attributes[FileImageTagDataConsts.FileIdAttrName], "Medium", this._options);
|
|
@@ -1397,17 +1474,35 @@ class ImageEditorComponent {
|
|
|
1397
1474
|
this.hasImageError = false;
|
|
1398
1475
|
}
|
|
1399
1476
|
ngOnInit() {
|
|
1477
|
+
this.requests = ImageMethods.mediaRequestStringToArrayParser(this.tag.attributes[FileImageTagDataConsts.ScreenMediaRequest]);
|
|
1478
|
+
}
|
|
1479
|
+
requestChanged() {
|
|
1480
|
+
this.tag.attributes[FileImageTagDataConsts.ScreenMediaRequest] = ImageMethods.mediaRequestsArrayToStringParser(this.requests);
|
|
1400
1481
|
}
|
|
1401
|
-
|
|
1402
|
-
|
|
1482
|
+
addNewMediaRequest() {
|
|
1483
|
+
this.requests.push({
|
|
1484
|
+
screenWidth: 0,
|
|
1485
|
+
maxImageHeight: 0,
|
|
1486
|
+
});
|
|
1487
|
+
}
|
|
1488
|
+
deleteMediaRequest(index) {
|
|
1489
|
+
this.requests.splice(index, 1);
|
|
1490
|
+
this.requestChanged();
|
|
1491
|
+
}
|
|
1492
|
+
ngOnDestroy() {
|
|
1493
|
+
this.unsubscribe.next();
|
|
1494
|
+
this.unsubscribe.complete();
|
|
1495
|
+
}
|
|
1496
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: ImageEditorComponent, deps: [{ token: CrocoHtmlOptionsToken }, { token: ScreenWidthService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1497
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.4", type: ImageEditorComponent, isStandalone: true, selector: "croco-html-image-editor", inputs: { tag: "tag" }, outputs: { onTagUpdated: "onTagUpdated" }, ngImport: i0, template: "<div>\n <div style=\"height: 10px;\">\n </div>\n\n @if (hasImageError) {\n <div class=\"error-block\">\n \u0418\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435 \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D\u043E \u043F\u043E \u0443\u043A\u0430\u0437\u0430\u043D\u043D\u043E\u043C\u0443 \u0438\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u043E\u0440\u0443, \u0432\u043E\u0437\u043C\u043E\u0436\u043D\u043E \u0444\u0430\u0439\u043B \u043D\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0438\u043B\u0438 \u043E\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043D\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435.\n </div>\n }\n\n @if (hasFileId() && !hasImageError) {\n <div>\n <img\n [ngStyle]=\"{ 'max-height': imageMaxHeight ? imageMaxHeight + 'px' : '100%'}\"\n class=\"mx-auto d-block img-fluid\" [src]=\"getSrc()\" (error)=\"onErrorHandler()\" alt=\"photo\"/>\n </div>\n }\n\n @if (!hasFileId()) {\n <div>\n <h5>[\u0418\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435 \u043D\u0435 \u0432\u044B\u0431\u0440\u0430\u043D\u043E]</h5>\n </div>\n }\n\n @if(!tag.presentOrEdit) {\n <mat-slide-toggle style=\"padding: 10px 0\" [(ngModel)]=\"isShowMediaRequest\">\u041F\u043E\u043A\u0430\u0437\u044B\u0432\u0430\u0442\u044C \u043C\u0435\u0434\u0438\u0430 \u0437\u0430\u043F\u0440\u043E\u0441\u044B</mat-slide-toggle>\n }\n\n @if(isShowMediaRequest) {\n <div style=\"display: flex; flex-direction: column; gap: 20px\">\n <div class=\"media-request__header\">\n <span>\u041C\u0435\u0434\u0438\u0430 \u0437\u0430\u043F\u0440\u043E\u0441\u044B:</span>\n @if (!tag.presentOrEdit) {\n <button (click)=\"addNewMediaRequest()\" class=\"w-30\" mat-icon-button color=\"primary\">\n <mat-icon>add</mat-icon>\n </button>\n }\n </div>\n @for (request of requests; track $index) {\n <div class=\"media-request__container\">\n @if (tag.presentOrEdit) {\n <div style=\"display: flex; flex-direction: column; gap: 5px\">\n <span class=\"w-100\">\u0413\u0440\u0430\u043D\u0438\u0446\u0430 \u0448\u0438\u0440\u0438\u043D\u044B: {{request.screenWidth}}</span>\n <span class=\"w-100\">\u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0432\u044B\u0441\u043E\u0442\u0430: {{request.maxImageHeight}}</span>\n </div>\n }\n\n @if (!tag.presentOrEdit) {\n <div style=\"width: 100%\">\n <mat-form-field class=\"w-100\">\n <mat-label>\n \u0413\u0440\u0430\u043D\u0438\u0446\u0430 \u0448\u0438\u0440\u0438\u043D\u044B\n </mat-label>\n <input matInput placeholder=\"\u0413\u0440\u0430\u043D\u0438\u0446\u0430 \u0448\u0438\u0440\u0438\u043D\u044B\"\n autocomplete=\"off\"\n [(ngModel)]=\"request.screenWidth\"\n (ngModelChange)=\"requestChanged()\">\n </mat-form-field>\n\n <mat-form-field class=\"w-100\">\n <mat-label>\n \u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0432\u044B\u0441\u043E\u0442\u0430\n </mat-label>\n <input matInput placeholder=\" \u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0432\u044B\u0441\u043E\u0442\u0430\"\n autocomplete=\"off\"\n [(ngModel)]=\"request.maxImageHeight\"\n (ngModelChange)=\"requestChanged()\">\n </mat-form-field>\n </div>\n\n <button (click)=\"deleteMediaRequest($index)\" class=\"w-30\" mat-icon-button color=\"warn\">\n <mat-icon>delete</mat-icon>\n </button>\n }\n </div>\n }\n </div>\n }\n</div>\n\n@if (!tag.presentOrEdit) {\n <div>\n <div style=\"height: 10px;\"></div>\n <div style=\"overflow-x:auto;\">\n <mat-button-toggle-group [(ngModel)]=\"searchOrEdit\">\n <mat-button-toggle value=\"search\">\n \u0418\u0441\u043A\u0430\u0442\u044C \u0444\u0430\u0439\u043B <mat-icon>search</mat-icon>\n </mat-button-toggle>\n <mat-button-toggle value=\"edit\">\n \u0423\u043A\u0430\u0437\u0430\u0442\u044C \u043F\u043E \u0438\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u043E\u0440\u0443 <mat-icon>settings</mat-icon>\n </mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n <div style=\"height: 10px;\"></div>\n <div [hidden]=\"searchOrEdit !== 'search'\">\n <croco-html-file-id-select\n [labelText]=\"'\u0412\u044B\u0431\u0440\u0430\u0442\u044C \u0444\u0430\u0439\u043B'\"\n [(fileId)]=\"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 <mat-label>\n \u0418\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u043E\u0440 \u0444\u0430\u0439\u043B\u0430\n </mat-label>\n <input matInput placeholder=\"\u0418\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u043E\u0440 \u0444\u0430\u0439\u043B\u0430\" new-autocomplete=\"off\" autocomplete=\"off\"\n type=\"number\"\n [(ngModel)]=\"tag.attributes['file-id']\"\n (ngModelChange)=\"removeImageError()\">\n </mat-form-field>\n </div>\n </div>\n </div>\n}\n", styles: [".error-block{background-color:#f32323;color:#fff;text-align:center;border-radius:10px;padding:10px}.media-request__header{align-items:center;display:flex;width:100%;justify-content:space-between}.media-request__container{display:flex;align-items:center;border-bottom:1px solid rgba(128,128,128,.7);padding-bottom:10px}\n"], dependencies: [{ kind: "directive", type: MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled", "hideSingleSelectionIndicator", "hideMultipleSelectionIndicator"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$4.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: 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: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: FileIdSelectComponent, selector: "croco-html-file-id-select", inputs: ["labelText", "fileId"], outputs: ["fileId", "onFileIdChanged"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }] }); }
|
|
1403
1498
|
}
|
|
1404
1499
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: ImageEditorComponent, decorators: [{
|
|
1405
1500
|
type: Component,
|
|
1406
|
-
args: [{ selector: 'croco-html-image-editor', standalone: true, imports: [MatButtonToggleGroup, FormsModule, MatButtonToggle, MatIcon, FileIdSelectComponent, MatFormField, MatLabel, MatInput], 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 <mat-label>\n \u0418\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u043E\u0440 \u0444\u0430\u0439\u043B\u0430\n </mat-label>\n <input matInput placeholder=\"\u0418\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u043E\u0440 \u0444\u0430\u0439\u043B\u0430\" new-autocomplete=\"off\" autocomplete=\"off\"\n 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"] }]
|
|
1501
|
+
args: [{ selector: 'croco-html-image-editor', standalone: true, imports: [MatButtonToggleGroup, FormsModule, MatButtonToggle, MatIcon, FileIdSelectComponent, MatFormField, MatLabel, MatInput, CdkDragHandle, MatCard, MatCardContent, XmlTagExternalVideoComponent, NgStyle, MatButton, MatIconButton, MatSlideToggle], template: "<div>\n <div style=\"height: 10px;\">\n </div>\n\n @if (hasImageError) {\n <div class=\"error-block\">\n \u0418\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435 \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D\u043E \u043F\u043E \u0443\u043A\u0430\u0437\u0430\u043D\u043D\u043E\u043C\u0443 \u0438\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u043E\u0440\u0443, \u0432\u043E\u0437\u043C\u043E\u0436\u043D\u043E \u0444\u0430\u0439\u043B \u043D\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0438\u043B\u0438 \u043E\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043D\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435.\n </div>\n }\n\n @if (hasFileId() && !hasImageError) {\n <div>\n <img\n [ngStyle]=\"{ 'max-height': imageMaxHeight ? imageMaxHeight + 'px' : '100%'}\"\n class=\"mx-auto d-block img-fluid\" [src]=\"getSrc()\" (error)=\"onErrorHandler()\" alt=\"photo\"/>\n </div>\n }\n\n @if (!hasFileId()) {\n <div>\n <h5>[\u0418\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435 \u043D\u0435 \u0432\u044B\u0431\u0440\u0430\u043D\u043E]</h5>\n </div>\n }\n\n @if(!tag.presentOrEdit) {\n <mat-slide-toggle style=\"padding: 10px 0\" [(ngModel)]=\"isShowMediaRequest\">\u041F\u043E\u043A\u0430\u0437\u044B\u0432\u0430\u0442\u044C \u043C\u0435\u0434\u0438\u0430 \u0437\u0430\u043F\u0440\u043E\u0441\u044B</mat-slide-toggle>\n }\n\n @if(isShowMediaRequest) {\n <div style=\"display: flex; flex-direction: column; gap: 20px\">\n <div class=\"media-request__header\">\n <span>\u041C\u0435\u0434\u0438\u0430 \u0437\u0430\u043F\u0440\u043E\u0441\u044B:</span>\n @if (!tag.presentOrEdit) {\n <button (click)=\"addNewMediaRequest()\" class=\"w-30\" mat-icon-button color=\"primary\">\n <mat-icon>add</mat-icon>\n </button>\n }\n </div>\n @for (request of requests; track $index) {\n <div class=\"media-request__container\">\n @if (tag.presentOrEdit) {\n <div style=\"display: flex; flex-direction: column; gap: 5px\">\n <span class=\"w-100\">\u0413\u0440\u0430\u043D\u0438\u0446\u0430 \u0448\u0438\u0440\u0438\u043D\u044B: {{request.screenWidth}}</span>\n <span class=\"w-100\">\u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0432\u044B\u0441\u043E\u0442\u0430: {{request.maxImageHeight}}</span>\n </div>\n }\n\n @if (!tag.presentOrEdit) {\n <div style=\"width: 100%\">\n <mat-form-field class=\"w-100\">\n <mat-label>\n \u0413\u0440\u0430\u043D\u0438\u0446\u0430 \u0448\u0438\u0440\u0438\u043D\u044B\n </mat-label>\n <input matInput placeholder=\"\u0413\u0440\u0430\u043D\u0438\u0446\u0430 \u0448\u0438\u0440\u0438\u043D\u044B\"\n autocomplete=\"off\"\n [(ngModel)]=\"request.screenWidth\"\n (ngModelChange)=\"requestChanged()\">\n </mat-form-field>\n\n <mat-form-field class=\"w-100\">\n <mat-label>\n \u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0432\u044B\u0441\u043E\u0442\u0430\n </mat-label>\n <input matInput placeholder=\" \u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0432\u044B\u0441\u043E\u0442\u0430\"\n autocomplete=\"off\"\n [(ngModel)]=\"request.maxImageHeight\"\n (ngModelChange)=\"requestChanged()\">\n </mat-form-field>\n </div>\n\n <button (click)=\"deleteMediaRequest($index)\" class=\"w-30\" mat-icon-button color=\"warn\">\n <mat-icon>delete</mat-icon>\n </button>\n }\n </div>\n }\n </div>\n }\n</div>\n\n@if (!tag.presentOrEdit) {\n <div>\n <div style=\"height: 10px;\"></div>\n <div style=\"overflow-x:auto;\">\n <mat-button-toggle-group [(ngModel)]=\"searchOrEdit\">\n <mat-button-toggle value=\"search\">\n \u0418\u0441\u043A\u0430\u0442\u044C \u0444\u0430\u0439\u043B <mat-icon>search</mat-icon>\n </mat-button-toggle>\n <mat-button-toggle value=\"edit\">\n \u0423\u043A\u0430\u0437\u0430\u0442\u044C \u043F\u043E \u0438\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u043E\u0440\u0443 <mat-icon>settings</mat-icon>\n </mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n <div style=\"height: 10px;\"></div>\n <div [hidden]=\"searchOrEdit !== 'search'\">\n <croco-html-file-id-select\n [labelText]=\"'\u0412\u044B\u0431\u0440\u0430\u0442\u044C \u0444\u0430\u0439\u043B'\"\n [(fileId)]=\"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 <mat-label>\n \u0418\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u043E\u0440 \u0444\u0430\u0439\u043B\u0430\n </mat-label>\n <input matInput placeholder=\"\u0418\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u043E\u0440 \u0444\u0430\u0439\u043B\u0430\" new-autocomplete=\"off\" autocomplete=\"off\"\n type=\"number\"\n [(ngModel)]=\"tag.attributes['file-id']\"\n (ngModelChange)=\"removeImageError()\">\n </mat-form-field>\n </div>\n </div>\n </div>\n}\n", styles: [".error-block{background-color:#f32323;color:#fff;text-align:center;border-radius:10px;padding:10px}.media-request__header{align-items:center;display:flex;width:100%;justify-content:space-between}.media-request__container{display:flex;align-items:center;border-bottom:1px solid rgba(128,128,128,.7);padding-bottom:10px}\n"] }]
|
|
1407
1502
|
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
1408
1503
|
type: Inject,
|
|
1409
1504
|
args: [CrocoHtmlOptionsToken]
|
|
1410
|
-
}] }], propDecorators: { tag: [{
|
|
1505
|
+
}] }, { type: ScreenWidthService }], propDecorators: { tag: [{
|
|
1411
1506
|
type: Input
|
|
1412
1507
|
}], onTagUpdated: [{
|
|
1413
1508
|
type: Output
|
|
@@ -1591,6 +1686,9 @@ class VisualEditorComponent {
|
|
|
1591
1686
|
attrs[ExternalVideoTagDataConsts.VideoTypeAttrName] = this.selectedVideoPlayer;
|
|
1592
1687
|
attrs[ExternalVideoTagDataConsts.LinkAttrName] = this.selectedVideoPlayer === ExternalVideoSupportedTypes.VkVideo ? defaultLinkVk : defaultLinkYouTube;
|
|
1593
1688
|
}
|
|
1689
|
+
else if (tagDescription.tag == FileImageTagDataConsts.TagName) {
|
|
1690
|
+
attrs[FileImageTagDataConsts.ScreenMediaRequest] = FileImageTagDataConsts.DefaultValueForFileImage;
|
|
1691
|
+
}
|
|
1594
1692
|
else if (tagDescription.tag == DownloadButtonTagDataConsts.TagName) {
|
|
1595
1693
|
attrs[DownloadButtonTagDataConsts.LinkAttrName] = defaultLinkForDownload;
|
|
1596
1694
|
attrs[DownloadButtonTagDataConsts.TitleAttrName] = 'Скачать';
|
|
@@ -1772,13 +1870,13 @@ class MainEditorComponent {
|
|
|
1772
1870
|
ngOnInit() {
|
|
1773
1871
|
this.visualEditor.recalculateBodyTags();
|
|
1774
1872
|
}
|
|
1775
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: MainEditorComponent, deps: [{ token: i1$5.ClipboardService }, { token: i2$
|
|
1873
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: MainEditorComponent, deps: [{ token: i1$5.ClipboardService }, { token: i2$3.MatSnackBar }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1776
1874
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.4", type: MainEditorComponent, isStandalone: true, 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 <mat-label>\u0418\u0441\u0445\u043E\u0434\u043D\u044B\u0439 \u043A\u043E\u0434</mat-label>\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: "component", type: 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: MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass"], exportAs: ["matTab"] }, { kind: "component", type: VisualEditorComponent, selector: "croco-visual-editor", inputs: ["showMarkUp", "useHtmlRaw", "html"], outputs: ["html", "onHtmlChanged", "rendered"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "directive", type: CdkTextareaAutosize, selector: "textarea[cdkTextareaAutosize]", inputs: ["cdkAutosizeMinRows", "cdkAutosizeMaxRows", "cdkTextareaAutosize", "placeholder"], exportAs: ["cdkTextareaAutosize"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: MatCardContent, selector: "mat-card-content" }, { kind: "component", type: XmlTagViewComponent, selector: "croco-html-xml-tag-view", inputs: ["data"] }, { kind: "pipe", type: ToPreviewPipe, name: "topreview" }] }); }
|
|
1777
1875
|
}
|
|
1778
1876
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: MainEditorComponent, decorators: [{
|
|
1779
1877
|
type: Component,
|
|
1780
1878
|
args: [{ selector: 'croco-html-main-editor', standalone: true, imports: [MatTabGroup, MatTab, VisualEditorComponent, MatFormField, MatLabel, MatInput, CdkTextareaAutosize, FormsModule, MatButton, MatCard, MatCardContent, XmlTagViewComponent, ToPreviewPipe], 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 <mat-label>\u0418\u0441\u0445\u043E\u0434\u043D\u044B\u0439 \u043A\u043E\u0434</mat-label>\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"] }]
|
|
1781
|
-
}], ctorParameters: () => [{ type: i1$5.ClipboardService }, { type: i2$
|
|
1879
|
+
}], ctorParameters: () => [{ type: i1$5.ClipboardService }, { type: i2$3.MatSnackBar }, { type: i0.ChangeDetectorRef }], propDecorators: { visualEditor: [{
|
|
1782
1880
|
type: ViewChild,
|
|
1783
1881
|
args: ["visualEditor", { static: true }]
|
|
1784
1882
|
}], showMarkUp: [{
|
|
@@ -1938,7 +2036,7 @@ class CrocoHtmlModule {
|
|
|
1938
2036
|
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.3.4", ngImport: i0, type: CrocoHtmlModule, imports: [CommonModule,
|
|
1939
2037
|
FormsModule,
|
|
1940
2038
|
ReactiveFormsModule,
|
|
1941
|
-
NgSelectModule, i1$6.MatBadgeModule, i2$
|
|
2039
|
+
NgSelectModule, i1$6.MatBadgeModule, i2$4.MatTableModule, i3.MatExpansionModule, i1$3.MatFormFieldModule, i2$3.MatSnackBarModule, i6.MatProgressBarModule, i7.MatProgressSpinnerModule, i8.MatTabsModule, i9.MatMenuModule, i1$2.MatCardModule, i11.MatSelectModule, i12.MatTooltipModule, i13.MatCheckboxModule, i14.MatChipsModule, i15.MatListModule, i2.MatButtonModule, i2$1.MatInputModule, i18.MatDialogModule, i19.MatPaginatorModule, i20.MatDatepickerModule, i21.MatGridListModule, i22.MatSlideToggleModule, i23.MatTreeModule, i24.MatNativeDateModule, i25.MatAutocompleteModule, i26.MatSidenavModule, i27.MatIconModule, i28.DragDropModule, i29.MatButtonToggleModule, ErrorBannerComponent,
|
|
1942
2040
|
VkVideoPlayerComponent,
|
|
1943
2041
|
YoutubeVideoPlayerComponent,
|
|
1944
2042
|
DownloadFileButtonBlockComponent,
|