@ebl-vue/editor-full 1.0.11 → 1.0.13
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/dist/index.d.ts +5 -0
- package/dist/index.mjs +733 -440
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -1
- package/src/components/Editor/Editor.vue +34 -10
- package/src/i18n/zh-cn.ts +6 -1
- package/src/icons/index.ts +15 -0
- package/src/installer.ts +4 -3
- package/src/plugins/alert/index.ts +19 -27
- package/src/plugins/block-alignment/index.ts +4 -3
- package/src/plugins/code/index.ts +3 -2
- package/src/plugins/color-picker/index.ts +3 -11
- package/src/plugins/delimiter/index.ts +5 -6
- package/src/plugins/header/H1.ts +1 -1
- package/src/plugins/header/H2.ts +1 -1
- package/src/plugins/header/H3.ts +1 -1
- package/src/plugins/header/H4.ts +1 -2
- package/src/plugins/header/H5.ts +1 -3
- package/src/plugins/header/H6.ts +1 -3
- package/src/plugins/imageTool/index.css +145 -0
- package/src/plugins/imageTool/index.ts +519 -0
- package/src/plugins/imageTool/types/codexteam__ajax.d.ts +89 -0
- package/src/plugins/imageTool/types/types.ts +234 -0
- package/src/plugins/imageTool/ui.ts +312 -0
- package/src/plugins/imageTool/uploader.ts +234 -0
- package/src/plugins/imageTool/utils/dom.ts +24 -0
- package/src/plugins/imageTool/utils/isPromise.ts +10 -0
- package/src/plugins/indent/index.ts +5 -7
- package/src/plugins/inline-code/index.ts +2 -5
- package/src/plugins/list/ListRenderer/ChecklistRenderer.ts +1 -4
- package/src/plugins/list/index.ts +20 -37
- package/src/plugins/list/types/OlCounterType.ts +1 -1
- package/src/plugins/marker/index.ts +28 -16
- package/src/plugins/paragraph/index.ts +3 -2
- package/src/plugins/quote/index.ts +1 -4
- package/src/plugins/table/plugin.ts +1 -1
- package/src/plugins/table/table.ts +40 -38
- package/src/plugins/table/toolbox.ts +5 -4
- package/src/plugins/table/utils/dom.ts +15 -14
- package/src/plugins/table/utils/popover.ts +28 -15
- package/src/plugins/underline/index.ts +2 -4
- package/src/plugins/undo/index.ts +48 -33
- package/src/plugins/undo/observer.ts +3 -3
- package/src/style.css +6 -0
- package/types/index.d.ts +5 -0
- package/vite.config.ts +3 -1
- package/src/plugins/list/styles/icons/index.ts +0 -10
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Module declaration for '@codexteam/ajax'.
|
|
3
|
+
*/
|
|
4
|
+
declare module '@codexteam/ajax' {
|
|
5
|
+
/**
|
|
6
|
+
* Options for configuring an Ajax request.
|
|
7
|
+
*/
|
|
8
|
+
export interface AjaxOptions {
|
|
9
|
+
/**
|
|
10
|
+
* The URL to which the request is sent.
|
|
11
|
+
*/
|
|
12
|
+
url?: string;
|
|
13
|
+
/**
|
|
14
|
+
* The data to send with the request.
|
|
15
|
+
*/
|
|
16
|
+
data?: object;
|
|
17
|
+
/**
|
|
18
|
+
* The MIME type of the request.
|
|
19
|
+
*/
|
|
20
|
+
accept?: string;
|
|
21
|
+
/**
|
|
22
|
+
* The headers to send with the request.
|
|
23
|
+
*/
|
|
24
|
+
headers?: object;
|
|
25
|
+
/**
|
|
26
|
+
* A function to call before the request is sent, with the files to be sent.
|
|
27
|
+
*/
|
|
28
|
+
beforeSend?: (files: File[]) => void;
|
|
29
|
+
/**
|
|
30
|
+
* The name of the field in the form data to which the file should be assigned.
|
|
31
|
+
*/
|
|
32
|
+
fieldName?: string;
|
|
33
|
+
/**
|
|
34
|
+
* The type of the request (e.g., 'POST', 'GET').
|
|
35
|
+
*/
|
|
36
|
+
type?: string;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Parameter type of selectFiles function in AjaxOptions interface
|
|
41
|
+
*/
|
|
42
|
+
export type AjaxFileOptionsParam = {
|
|
43
|
+
/**
|
|
44
|
+
* the accepted file types.
|
|
45
|
+
*/
|
|
46
|
+
accept: string;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Represents the response from an Ajax request.
|
|
51
|
+
* @template T - The type of the response body.
|
|
52
|
+
*/
|
|
53
|
+
export interface AjaxResponse<T = object> {
|
|
54
|
+
/** The body of the response. */
|
|
55
|
+
body: T;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Prompts the user to select files and returns a promise that resolves with the selected files.
|
|
60
|
+
* @param options - Options for file selection.
|
|
61
|
+
* @param options.accept - The accepted file types.
|
|
62
|
+
* @returns A promise that resolves with the selected files.
|
|
63
|
+
*/
|
|
64
|
+
export function selectFiles(options: AjaxFileOptionsParam): Promise<File[]>;
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Sends an Ajax request with the specified options.
|
|
68
|
+
* @param options - Options for the Ajax request.
|
|
69
|
+
* @returns A promise that resolves with the Ajax response.
|
|
70
|
+
*/
|
|
71
|
+
export function transport(options: AjaxOptions): Promise<AjaxResponse>;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Sends a POST request with the specified options.
|
|
75
|
+
* @param options - Options for the POST request.
|
|
76
|
+
* @returns A promise that resolves with the Ajax response.
|
|
77
|
+
*/
|
|
78
|
+
export function post(options: AjaxOptions): Promise<AjaxResponse>;
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Represents common content types.
|
|
82
|
+
*/
|
|
83
|
+
export const contentType: {
|
|
84
|
+
/**
|
|
85
|
+
* The MIME type for JSON content.
|
|
86
|
+
*/
|
|
87
|
+
JSON: string;
|
|
88
|
+
};
|
|
89
|
+
}
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
import type { HTMLPasteEventDetail } from '@editorjs/editorjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Represents options for uploading, including a function to handle previewing.
|
|
5
|
+
*/
|
|
6
|
+
export interface UploadOptions {
|
|
7
|
+
/**
|
|
8
|
+
* Callback function to be called when the preview is ready.
|
|
9
|
+
* @param src - The source of the preview as a string.
|
|
10
|
+
* @returns void
|
|
11
|
+
*/
|
|
12
|
+
onPreview: (src: string) => void;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* User configuration of Image block tunes. Allows to add custom tunes through the config
|
|
17
|
+
*/
|
|
18
|
+
export interface ActionConfig {
|
|
19
|
+
/**
|
|
20
|
+
* The name of the tune.
|
|
21
|
+
*/
|
|
22
|
+
name: string;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* The icon for the tune. Should be an SVG string.
|
|
26
|
+
*/
|
|
27
|
+
icon: string;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* The title of the tune. This will be displayed in the UI.
|
|
31
|
+
*/
|
|
32
|
+
title: string;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* An optional flag indicating whether the tune is a toggle (true) or not (false).
|
|
36
|
+
*/
|
|
37
|
+
toggle?: boolean;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* An optional action function to be executed when the tune is activated.
|
|
41
|
+
*/
|
|
42
|
+
action?: Function;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* UploadResponseFormat interface representing the response format expected from the backend on file uploading.
|
|
47
|
+
*/
|
|
48
|
+
export interface UploadResponseFormat<AdditionalFileData = {}> {
|
|
49
|
+
status?: number;
|
|
50
|
+
/**
|
|
51
|
+
* success - 1 for successful uploading, 0 for failure
|
|
52
|
+
*/
|
|
53
|
+
success: number;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Object with file data.
|
|
57
|
+
* 'url' is required,
|
|
58
|
+
* also can contain any additional data that will be saved and passed back
|
|
59
|
+
*/
|
|
60
|
+
file: {
|
|
61
|
+
/**
|
|
62
|
+
* The URL of the uploaded image.
|
|
63
|
+
*/
|
|
64
|
+
url: string;
|
|
65
|
+
} & AdditionalFileData;
|
|
66
|
+
}
|
|
67
|
+
export interface IUploadResponseFormat<> {
|
|
68
|
+
|
|
69
|
+
success: boolean;
|
|
70
|
+
data?: any,
|
|
71
|
+
message?: string;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* ImageToolData type representing the input and output data format for the image tool, including optional custome actions.
|
|
75
|
+
*/
|
|
76
|
+
export type ImageToolData<Actions = {}, AdditionalFileData = {}> = {
|
|
77
|
+
/**
|
|
78
|
+
* Caption for the image.
|
|
79
|
+
*/
|
|
80
|
+
caption: string;
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Flag indicating whether the image has a border.
|
|
84
|
+
*/
|
|
85
|
+
withBorder: boolean;
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Flag indicating whether the image has a background.
|
|
89
|
+
*/
|
|
90
|
+
withBackground: boolean;
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Flag indicating whether the image is stretched.
|
|
94
|
+
*/
|
|
95
|
+
stretched: boolean;
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Object containing the URL of the image file.
|
|
99
|
+
* Also can contain any additional data.
|
|
100
|
+
*/
|
|
101
|
+
file: {
|
|
102
|
+
/**
|
|
103
|
+
* The URL of the image.
|
|
104
|
+
*/
|
|
105
|
+
url: string;
|
|
106
|
+
} & AdditionalFileData;
|
|
107
|
+
} & (Actions extends Record<string, boolean> ? Actions : {});
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* @description Allows to enable or disable features.
|
|
111
|
+
*/
|
|
112
|
+
export type FeaturesConfig = {
|
|
113
|
+
/**
|
|
114
|
+
* Flag to enable/disable tune - background.
|
|
115
|
+
*/
|
|
116
|
+
background?: boolean;
|
|
117
|
+
/**
|
|
118
|
+
* Flag to enable/disable tune - border.
|
|
119
|
+
*/
|
|
120
|
+
border?: boolean;
|
|
121
|
+
/**
|
|
122
|
+
* Flag to enable/disable caption.
|
|
123
|
+
* Can be set to 'optional' to allow users to toggle via block tunes.
|
|
124
|
+
*/
|
|
125
|
+
caption?: boolean | 'optional';
|
|
126
|
+
/**
|
|
127
|
+
* Flag to enable/disable tune - stretched
|
|
128
|
+
*/
|
|
129
|
+
stretch?: boolean;
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
*
|
|
134
|
+
* @description Config supported by Tool
|
|
135
|
+
*/
|
|
136
|
+
export interface ImageConfig {
|
|
137
|
+
/**
|
|
138
|
+
* Endpoints for upload, whether using file or URL.
|
|
139
|
+
*/
|
|
140
|
+
endpoints: {
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Endpoint for file upload.
|
|
144
|
+
*/
|
|
145
|
+
byFile?: string;
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Endpoints for URL upload.
|
|
149
|
+
*/
|
|
150
|
+
byUrl?: string;
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Field name for the uploaded image.
|
|
155
|
+
*/
|
|
156
|
+
field?: string;
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Allowed mime-types for the uploaded image.
|
|
160
|
+
*/
|
|
161
|
+
types?: string;
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Placeholder text for the caption field.
|
|
165
|
+
*/
|
|
166
|
+
captionPlaceholder?: string;
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Additional data to send with requests.
|
|
170
|
+
*/
|
|
171
|
+
additionalRequestData?: object;
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Additional headers to send with requests.
|
|
175
|
+
*/
|
|
176
|
+
additionalRequestHeaders?: object;
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Custom content for the select file button.
|
|
180
|
+
*/
|
|
181
|
+
buttonContent?: string;
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Optional custom uploader.
|
|
185
|
+
*/
|
|
186
|
+
uploader?: {
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Method to upload an image by file.
|
|
190
|
+
*/
|
|
191
|
+
uploadByFile?: (file: Blob) => Promise<UploadResponseFormat>;
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Method to upload an image by URL.
|
|
195
|
+
*/
|
|
196
|
+
uploadByUrl?: (url: string) => Promise<UploadResponseFormat>;
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Additional actions for the tool.
|
|
201
|
+
*/
|
|
202
|
+
actions?: ActionConfig[];
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Tunes to be enabled.
|
|
206
|
+
*/
|
|
207
|
+
features?: FeaturesConfig;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Interface representing the details of a paste event for HTML elements.
|
|
212
|
+
* Extends the `HTMLPasteEventDetail` interface to include additional data properties.
|
|
213
|
+
*/
|
|
214
|
+
export interface HTMLPasteEventDetailExtended extends HTMLPasteEventDetail {
|
|
215
|
+
/**
|
|
216
|
+
* The data property containing the source of the image and HTML element details.
|
|
217
|
+
*/
|
|
218
|
+
data: {
|
|
219
|
+
/**
|
|
220
|
+
* The source URL of the pasted image.
|
|
221
|
+
*/
|
|
222
|
+
src: string;
|
|
223
|
+
} & HTMLElement;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Parameter type of Image setter function in ImageTool
|
|
228
|
+
*/
|
|
229
|
+
export type ImageSetterParam = {
|
|
230
|
+
/**
|
|
231
|
+
* url path of the image
|
|
232
|
+
*/
|
|
233
|
+
url: string;
|
|
234
|
+
};
|
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
import { IconPicture } from '@codexteam/icons';
|
|
2
|
+
import { make } from './utils/dom';
|
|
3
|
+
import type { API } from '@editorjs/editorjs';
|
|
4
|
+
import type { ImageConfig } from './types/types';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Enumeration representing the different states of the UI.
|
|
8
|
+
*/
|
|
9
|
+
export enum UiState {
|
|
10
|
+
/**
|
|
11
|
+
* The UI is in an empty state, with no image loaded or being selected.
|
|
12
|
+
*/
|
|
13
|
+
Empty = 'empty',
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* The UI is in an uploading state, indicating an image is currently being uploaded.
|
|
17
|
+
*/
|
|
18
|
+
Uploading = 'uploading',
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* The UI is in a filled state, with an image successfully loaded.
|
|
22
|
+
*/
|
|
23
|
+
Filled = 'filled'
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Nodes interface representing various elements in the UI.
|
|
28
|
+
*/
|
|
29
|
+
interface Nodes {
|
|
30
|
+
/**
|
|
31
|
+
* Wrapper element in the UI.
|
|
32
|
+
*/
|
|
33
|
+
wrapper: HTMLElement;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Container for the image element in the UI.
|
|
37
|
+
*/
|
|
38
|
+
imageContainer: HTMLElement;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Button for selecting files.
|
|
42
|
+
*/
|
|
43
|
+
fileButton: HTMLElement;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Represents the image element in the UI, if one is present; otherwise, it's undefined.
|
|
47
|
+
*/
|
|
48
|
+
imageEl?: HTMLElement;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Preloader element for the image.
|
|
52
|
+
*/
|
|
53
|
+
imagePreloader: HTMLElement;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Caption element for the image.
|
|
57
|
+
*/
|
|
58
|
+
caption: HTMLElement;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* ConstructorParams interface representing parameters for the Ui class constructor.
|
|
63
|
+
*/
|
|
64
|
+
interface ConstructorParams {
|
|
65
|
+
/**
|
|
66
|
+
* Editor.js API.
|
|
67
|
+
*/
|
|
68
|
+
api: API;
|
|
69
|
+
/**
|
|
70
|
+
* Configuration for the image.
|
|
71
|
+
*/
|
|
72
|
+
config: ImageConfig;
|
|
73
|
+
/**
|
|
74
|
+
* Callback function for selecting a file.
|
|
75
|
+
*/
|
|
76
|
+
onSelectFile: () => void;
|
|
77
|
+
/**
|
|
78
|
+
* Flag indicating if the UI is in read-only mode.
|
|
79
|
+
*/
|
|
80
|
+
readOnly: boolean;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Class for working with UI:
|
|
85
|
+
* - rendering base structure
|
|
86
|
+
* - show/hide preview
|
|
87
|
+
* - apply tune view
|
|
88
|
+
*/
|
|
89
|
+
export default class Ui {
|
|
90
|
+
/**
|
|
91
|
+
* Nodes representing various elements in the UI.
|
|
92
|
+
*/
|
|
93
|
+
public nodes: Nodes;
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* API instance for Editor.js.
|
|
97
|
+
*/
|
|
98
|
+
private api: API;
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Configuration for the image tool.
|
|
102
|
+
*/
|
|
103
|
+
private config: ImageConfig;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Callback function for selecting a file.
|
|
107
|
+
*/
|
|
108
|
+
private onSelectFile: () => void;
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Flag indicating if the UI is in read-only mode.
|
|
112
|
+
*/
|
|
113
|
+
private readOnly: boolean;
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* @param ui - image tool Ui module
|
|
117
|
+
* @param ui.api - Editor.js API
|
|
118
|
+
* @param ui.config - user config
|
|
119
|
+
* @param ui.onSelectFile - callback for clicks on Select file button
|
|
120
|
+
* @param ui.readOnly - read-only mode flag
|
|
121
|
+
*/
|
|
122
|
+
constructor({ api, config, onSelectFile, readOnly }: ConstructorParams) {
|
|
123
|
+
this.api = api;
|
|
124
|
+
this.config = config;
|
|
125
|
+
this.onSelectFile = onSelectFile;
|
|
126
|
+
|
|
127
|
+
this.readOnly = readOnly;
|
|
128
|
+
this.nodes = {
|
|
129
|
+
wrapper: make('div', [this.CSS.baseClass, this.CSS.wrapper]),
|
|
130
|
+
imageContainer: make('div', [this.CSS.imageContainer]),
|
|
131
|
+
fileButton: this.createFileButton(),
|
|
132
|
+
imageEl: undefined,
|
|
133
|
+
imagePreloader: make('div', this.CSS.imagePreloader),
|
|
134
|
+
caption: make('div', [this.CSS.input, this.CSS.caption], {
|
|
135
|
+
contentEditable: !this.readOnly,
|
|
136
|
+
}),
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Create base structure
|
|
141
|
+
* <wrapper>
|
|
142
|
+
* <image-container>
|
|
143
|
+
* <image-preloader />
|
|
144
|
+
* </image-container>
|
|
145
|
+
* <caption />
|
|
146
|
+
* <select-file-button />
|
|
147
|
+
* </wrapper>
|
|
148
|
+
*/
|
|
149
|
+
this.nodes.caption.dataset.placeholder = this.config.captionPlaceholder;
|
|
150
|
+
this.nodes.imageContainer.appendChild(this.nodes.imagePreloader);
|
|
151
|
+
this.nodes.wrapper.appendChild(this.nodes.imageContainer);
|
|
152
|
+
this.nodes.wrapper.appendChild(this.nodes.caption);
|
|
153
|
+
this.nodes.wrapper.appendChild(this.nodes.fileButton);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Apply visual representation of activated tune
|
|
158
|
+
* @param tuneName - one of available tunes {@link Tunes.tunes}
|
|
159
|
+
* @param status - true for enable, false for disable
|
|
160
|
+
*/
|
|
161
|
+
public applyTune(tuneName: string, status: boolean): void {
|
|
162
|
+
this.nodes.wrapper.classList.toggle(`${this.CSS.wrapper}--${tuneName}`, status);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Renders tool UI
|
|
167
|
+
*/
|
|
168
|
+
public render(): HTMLElement {
|
|
169
|
+
this.toggleStatus(UiState.Empty);
|
|
170
|
+
|
|
171
|
+
return this.nodes.wrapper;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Shows uploading preloader
|
|
176
|
+
* @param src - preview source
|
|
177
|
+
*/
|
|
178
|
+
public showPreloader(src: string): void {
|
|
179
|
+
this.nodes.imagePreloader.style.backgroundImage = `url(${src})`;
|
|
180
|
+
|
|
181
|
+
this.toggleStatus(UiState.Uploading);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Hide uploading preloader
|
|
186
|
+
*/
|
|
187
|
+
public hidePreloader(): void {
|
|
188
|
+
this.nodes.imagePreloader.style.backgroundImage = '';
|
|
189
|
+
this.toggleStatus(UiState.Empty);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Shows an image
|
|
194
|
+
* @param url - image source
|
|
195
|
+
*/
|
|
196
|
+
public fillImage(url: string): void {
|
|
197
|
+
/**
|
|
198
|
+
* Check for a source extension to compose element correctly: video tag for mp4, img — for others
|
|
199
|
+
*/
|
|
200
|
+
const tag = /\.mp4$/.test(url) ? 'VIDEO' : 'IMG';
|
|
201
|
+
|
|
202
|
+
const attributes: { [key: string]: string | boolean } = {
|
|
203
|
+
src: url,
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* We use eventName variable because IMG and VIDEO tags have different event to be called on source load
|
|
208
|
+
* - IMG: load
|
|
209
|
+
* - VIDEO: loadeddata
|
|
210
|
+
*/
|
|
211
|
+
let eventName = 'load';
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Update attributes and eventName if source is a mp4 video
|
|
215
|
+
*/
|
|
216
|
+
if (tag === 'VIDEO') {
|
|
217
|
+
/**
|
|
218
|
+
* Add attributes for playing muted mp4 as a gif
|
|
219
|
+
*/
|
|
220
|
+
attributes.autoplay = true;
|
|
221
|
+
attributes.loop = true;
|
|
222
|
+
attributes.muted = true;
|
|
223
|
+
attributes.playsinline = true;
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Change event to be listened
|
|
227
|
+
*/
|
|
228
|
+
eventName = 'loadeddata';
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Compose tag with defined attributes
|
|
233
|
+
*/
|
|
234
|
+
this.nodes.imageEl = make(tag, this.CSS.imageEl, attributes);
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Add load event listener
|
|
238
|
+
*/
|
|
239
|
+
this.nodes.imageEl.addEventListener(eventName, () => {
|
|
240
|
+
this.toggleStatus(UiState.Filled);
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Preloader does not exists on first rendering with presaved data
|
|
244
|
+
*/
|
|
245
|
+
if (this.nodes.imagePreloader !== undefined) {
|
|
246
|
+
this.nodes.imagePreloader.style.backgroundImage = '';
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
this.nodes.imageContainer.appendChild(this.nodes.imageEl);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Shows caption input
|
|
255
|
+
* @param text - caption content text
|
|
256
|
+
*/
|
|
257
|
+
public fillCaption(text: string): void {
|
|
258
|
+
if (this.nodes.caption !== undefined) {
|
|
259
|
+
this.nodes.caption.innerHTML = text;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Changes UI status
|
|
265
|
+
* @param status - see {@link Ui.status} constants
|
|
266
|
+
*/
|
|
267
|
+
public toggleStatus(status: UiState): void {
|
|
268
|
+
for (const statusType in UiState) {
|
|
269
|
+
if (Object.prototype.hasOwnProperty.call(UiState, statusType)) {
|
|
270
|
+
const state = UiState[statusType as keyof typeof UiState];
|
|
271
|
+
|
|
272
|
+
this.nodes.wrapper.classList.toggle(`${this.CSS.wrapper}--${state}`, state === status);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* CSS classes
|
|
279
|
+
*/
|
|
280
|
+
private get CSS(): Record<string, string> {
|
|
281
|
+
return {
|
|
282
|
+
baseClass: this.api.styles.block,
|
|
283
|
+
loading: this.api.styles.loader,
|
|
284
|
+
input: this.api.styles.input,
|
|
285
|
+
button: this.api.styles.button,
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Tool's classes
|
|
289
|
+
*/
|
|
290
|
+
wrapper: 'image-tool',
|
|
291
|
+
imageContainer: 'image-tool__image',
|
|
292
|
+
imagePreloader: 'image-tool__image-preloader',
|
|
293
|
+
imageEl: 'image-tool__image-picture',
|
|
294
|
+
caption: 'image-tool__caption',
|
|
295
|
+
};
|
|
296
|
+
};
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Creates upload-file button
|
|
300
|
+
*/
|
|
301
|
+
private createFileButton(): HTMLElement {
|
|
302
|
+
const button = make('div', [this.CSS.button]);
|
|
303
|
+
|
|
304
|
+
button.innerHTML = this.config.buttonContent ?? `${IconPicture} ${this.api.i18n.t('Select an Image')}`;
|
|
305
|
+
|
|
306
|
+
button.addEventListener('click', () => {
|
|
307
|
+
this.onSelectFile();
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
return button;
|
|
311
|
+
}
|
|
312
|
+
}
|