@ckeditor/ckeditor5-upload 41.2.0 → 41.3.0-alpha.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,342 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
+ */
5
+ /**
6
+ * @module upload/filerepository
7
+ */
8
+ import { Plugin, PendingActions } from '@ckeditor/ckeditor5-core';
9
+ import { Collection } from '@ckeditor/ckeditor5-utils';
10
+ /**
11
+ * File repository plugin. A central point for managing file upload.
12
+ *
13
+ * To use it, first you need an upload adapter. Upload adapter's job is to handle communication with the server
14
+ * (sending the file and handling server's response). You can use one of the existing plugins introducing upload adapters
15
+ * (e.g. {@link module:easy-image/cloudservicesuploadadapter~CloudServicesUploadAdapter} or
16
+ * {@link module:adapter-ckfinder/uploadadapter~CKFinderUploadAdapter}) or write your own one – see
17
+ * the {@glink framework/deep-dive/upload-adapter Custom image upload adapter deep-dive} guide.
18
+ *
19
+ * Then, you can use {@link module:upload/filerepository~FileRepository#createLoader `createLoader()`} and the returned
20
+ * {@link module:upload/filerepository~FileLoader} instance to load and upload files.
21
+ */
22
+ export default class FileRepository extends Plugin {
23
+ /**
24
+ * Collection of loaders associated with this repository.
25
+ */
26
+ loaders: Collection<FileLoader>;
27
+ /**
28
+ * A factory function which should be defined before using `FileRepository`.
29
+ *
30
+ * It should return a new instance of {@link module:upload/filerepository~UploadAdapter} that will be used to upload files.
31
+ * {@link module:upload/filerepository~FileLoader} instance associated with the adapter
32
+ * will be passed to that function.
33
+ *
34
+ * For more information and example see {@link module:upload/filerepository~UploadAdapter}.
35
+ */
36
+ createUploadAdapter?: (loader: FileLoader) => UploadAdapter;
37
+ /**
38
+ * Loaders mappings used to retrieve loaders references.
39
+ */
40
+ private _loadersMap;
41
+ /**
42
+ * Reference to a pending action registered in a {@link module:core/pendingactions~PendingActions} plugin
43
+ * while upload is in progress. When there is no upload then value is `null`.
44
+ */
45
+ private _pendingAction;
46
+ /**
47
+ * Number of bytes uploaded.
48
+ *
49
+ * @readonly
50
+ * @observable
51
+ */
52
+ uploaded: number;
53
+ /**
54
+ * Number of total bytes to upload.
55
+ *
56
+ * It might be different than the file size because of headers and additional data.
57
+ * It contains `null` if value is not available yet, so it's better to use {@link #uploadedPercent} to monitor
58
+ * the progress.
59
+ *
60
+ * @readonly
61
+ * @observable
62
+ */
63
+ uploadTotal: number | null;
64
+ /**
65
+ * Upload progress in percents.
66
+ *
67
+ * @readonly
68
+ * @observable
69
+ */
70
+ uploadedPercent: number;
71
+ /**
72
+ * @inheritDoc
73
+ */
74
+ static get pluginName(): "FileRepository";
75
+ /**
76
+ * @inheritDoc
77
+ */
78
+ static get requires(): readonly [typeof PendingActions];
79
+ /**
80
+ * @inheritDoc
81
+ */
82
+ init(): void;
83
+ /**
84
+ * Returns the loader associated with specified file or promise.
85
+ *
86
+ * To get loader by id use `fileRepository.loaders.get( id )`.
87
+ *
88
+ * @param fileOrPromise Native file or promise handle.
89
+ */
90
+ getLoader(fileOrPromise: File | Promise<File>): FileLoader | null;
91
+ /**
92
+ * Creates a loader instance for the given file.
93
+ *
94
+ * Requires {@link #createUploadAdapter} factory to be defined.
95
+ *
96
+ * @param fileOrPromise Native File object or native Promise object which resolves to a File.
97
+ */
98
+ createLoader(fileOrPromise: File | Promise<File>): FileLoader | null;
99
+ /**
100
+ * Destroys the given loader.
101
+ *
102
+ * @param fileOrPromiseOrLoader File or Promise associated with that loader or loader itself.
103
+ */
104
+ destroyLoader(fileOrPromiseOrLoader: File | Promise<File> | FileLoader): void;
105
+ /**
106
+ * Registers or deregisters pending action bound with upload progress.
107
+ */
108
+ private _updatePendingAction;
109
+ }
110
+ declare const FileLoader_base: {
111
+ new (): import("@ckeditor/ckeditor5-utils").Observable;
112
+ prototype: import("@ckeditor/ckeditor5-utils").Observable;
113
+ };
114
+ /**
115
+ * File loader class.
116
+ *
117
+ * It is used to control the process of reading the file and uploading it using the specified upload adapter.
118
+ */
119
+ declare class FileLoader extends FileLoader_base {
120
+ /**
121
+ * Unique id of FileLoader instance.
122
+ *
123
+ * @readonly
124
+ */
125
+ readonly id: string;
126
+ /**
127
+ * Additional wrapper over the initial file promise passed to this loader.
128
+ */
129
+ private _filePromiseWrapper;
130
+ /**
131
+ * Adapter instance associated with this file loader.
132
+ */
133
+ private _adapter;
134
+ /**
135
+ * FileReader used by FileLoader.
136
+ */
137
+ private _reader;
138
+ /**
139
+ * Current status of FileLoader. It can be one of the following:
140
+ *
141
+ * * 'idle',
142
+ * * 'reading',
143
+ * * 'uploading',
144
+ * * 'aborted',
145
+ * * 'error'.
146
+ *
147
+ * When reading status can change in a following way:
148
+ *
149
+ * `idle` -> `reading` -> `idle`
150
+ * `idle` -> `reading -> `aborted`
151
+ * `idle` -> `reading -> `error`
152
+ *
153
+ * When uploading status can change in a following way:
154
+ *
155
+ * `idle` -> `uploading` -> `idle`
156
+ * `idle` -> `uploading` -> `aborted`
157
+ * `idle` -> `uploading` -> `error`
158
+ *
159
+ * @readonly
160
+ * @observable
161
+ */
162
+ status: 'idle' | 'reading' | 'uploading' | 'aborted' | 'error';
163
+ /**
164
+ * Number of bytes uploaded.
165
+ *
166
+ * @readonly
167
+ * @observable
168
+ */
169
+ uploaded: number;
170
+ /**
171
+ * Number of total bytes to upload.
172
+ *
173
+ * @readonly
174
+ * @observable
175
+ */
176
+ uploadTotal: number | null;
177
+ /**
178
+ * Upload progress in percents.
179
+ *
180
+ * @readonly
181
+ * @observable
182
+ */
183
+ uploadedPercent: number;
184
+ /**
185
+ * Response of the upload.
186
+ *
187
+ * @readonly
188
+ * @observable
189
+ */
190
+ uploadResponse?: UploadResponse | null;
191
+ /**
192
+ * Creates a new instance of `FileLoader`.
193
+ *
194
+ * @param filePromise A promise which resolves to a file instance.
195
+ * @param uploadAdapterCreator The function which returns {@link module:upload/filerepository~UploadAdapter} instance.
196
+ */
197
+ constructor(filePromise: Promise<File>, uploadAdapterCreator: (loader: FileLoader) => UploadAdapter);
198
+ /**
199
+ * A `Promise` which resolves to a `File` instance associated with this file loader.
200
+ */
201
+ get file(): Promise<File | null>;
202
+ /**
203
+ * Returns the file data. To read its data, you need for first load the file
204
+ * by using the {@link module:upload/filerepository~FileLoader#read `read()`} method.
205
+ */
206
+ get data(): string | undefined;
207
+ /**
208
+ * Reads file using {@link module:upload/filereader~FileReader}.
209
+ *
210
+ * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `filerepository-read-wrong-status` when status
211
+ * is different than `idle`.
212
+ *
213
+ * Example usage:
214
+ *
215
+ * ```ts
216
+ * fileLoader.read()
217
+ * .then( data => { ... } )
218
+ * .catch( err => {
219
+ * if ( err === 'aborted' ) {
220
+ * console.log( 'Reading aborted.' );
221
+ * } else {
222
+ * console.log( 'Reading error.', err );
223
+ * }
224
+ * } );
225
+ * ```
226
+ *
227
+ * @returns Returns promise that will be resolved with read data. Promise will be rejected if error
228
+ * occurs or if read process is aborted.
229
+ */
230
+ read(): Promise<string>;
231
+ /**
232
+ * Reads file using the provided {@link module:upload/filerepository~UploadAdapter}.
233
+ *
234
+ * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `filerepository-upload-wrong-status` when status
235
+ * is different than `idle`.
236
+ * Example usage:
237
+ *
238
+ * ```ts
239
+ * fileLoader.upload()
240
+ * .then( data => { ... } )
241
+ * .catch( e => {
242
+ * if ( e === 'aborted' ) {
243
+ * console.log( 'Uploading aborted.' );
244
+ * } else {
245
+ * console.log( 'Uploading error.', e );
246
+ * }
247
+ * } );
248
+ * ```
249
+ *
250
+ * @returns Returns promise that will be resolved with response data. Promise will be rejected if error
251
+ * occurs or if read process is aborted.
252
+ */
253
+ upload(): Promise<UploadResponse>;
254
+ /**
255
+ * Aborts loading process.
256
+ */
257
+ abort(): void;
258
+ /**
259
+ * Performs cleanup.
260
+ *
261
+ * @internal
262
+ */
263
+ _destroy(): void;
264
+ /**
265
+ * Wraps a given file promise into another promise giving additional
266
+ * control (resolving, rejecting, checking if fulfilled) over it.
267
+ *
268
+ * @param filePromise The initial file promise to be wrapped.
269
+ */
270
+ private _createFilePromiseWrapper;
271
+ }
272
+ export type { FileLoader };
273
+ /**
274
+ * Upload adapter interface used by the {@link module:upload/filerepository~FileRepository file repository}
275
+ * to handle file upload. An upload adapter is a bridge between the editor and server that handles file uploads.
276
+ * It should contain a logic necessary to initiate an upload process and monitor its progress.
277
+ *
278
+ * Learn how to develop your own upload adapter for CKEditor 5 in the
279
+ * {@glink framework/deep-dive/upload-adapter "Custom upload adapter"} guide.
280
+ *
281
+ * @interface UploadAdapter
282
+ */
283
+ export interface UploadAdapter {
284
+ /**
285
+ * Executes the upload process.
286
+ * This method should return a promise that will resolve when data will be uploaded to server. Promise should be
287
+ * resolved with an object containing information about uploaded file:
288
+ *
289
+ * ```json
290
+ * {
291
+ * default: 'http://server/default-size.image.png'
292
+ * }
293
+ * ```
294
+ *
295
+ * Additionally, other image sizes can be provided:
296
+ *
297
+ * ```json
298
+ * {
299
+ * default: 'http://server/default-size.image.png',
300
+ * '160': 'http://server/size-160.image.png',
301
+ * '500': 'http://server/size-500.image.png',
302
+ * '1000': 'http://server/size-1000.image.png',
303
+ * '1052': 'http://server/default-size.image.png'
304
+ * }
305
+ * ```
306
+ *
307
+ * You can also pass additional properties from the server. In this case you need to wrap URLs
308
+ * in the `urls` object and pass additional properties along the `urls` property.
309
+ *
310
+ * ```json
311
+ * {
312
+ * myCustomProperty: 'foo',
313
+ * urls: {
314
+ * default: 'http://server/default-size.image.png',
315
+ * '160': 'http://server/size-160.image.png',
316
+ * '500': 'http://server/size-500.image.png',
317
+ * '1000': 'http://server/size-1000.image.png',
318
+ * '1052': 'http://server/default-size.image.png'
319
+ * }
320
+ * }
321
+ * ```
322
+ *
323
+ * NOTE: When returning multiple images, the widest returned one should equal the default one. It is essential to
324
+ * correctly set `width` attribute of the image. See this discussion:
325
+ * https://github.com/ckeditor/ckeditor5-easy-image/issues/4 for more information.
326
+ *
327
+ * Take a look at {@link module:upload/filerepository~UploadAdapter example Adapter implementation} and
328
+ * {@link module:upload/filerepository~FileRepository#createUploadAdapter createUploadAdapter method}.
329
+ *
330
+ * @returns Promise that should be resolved when data is uploaded.
331
+ */
332
+ upload(): Promise<UploadResponse>;
333
+ /**
334
+ * Aborts the upload process.
335
+ * After aborting it should reject promise returned from {@link #upload upload()}.
336
+ *
337
+ * Take a look at {@link module:upload/filerepository~UploadAdapter example Adapter implementation} and
338
+ * {@link module:upload/filerepository~FileRepository#createUploadAdapter createUploadAdapter method}.
339
+ */
340
+ abort?(): void;
341
+ }
342
+ export type UploadResponse = Record<string, unknown>;
@@ -0,0 +1,13 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
+ */
5
+ /**
6
+ * @module upload
7
+ */
8
+ export { default as FileRepository, type UploadAdapter, type UploadResponse, type FileLoader } from './filerepository.js';
9
+ export { default as FileDialogButtonView } from './ui/filedialogbuttonview.js';
10
+ export { default as Base64UploadAdapter } from './adapters/base64uploadadapter.js';
11
+ export { default as SimpleUploadAdapter } from './adapters/simpleuploadadapter.js';
12
+ export type { SimpleUploadConfig } from './uploadconfig.js';
13
+ import './augmentation.js';
@@ -0,0 +1,83 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
+ */
5
+ /**
6
+ * @module upload/ui/filedialogbuttonview
7
+ */
8
+ import { ButtonView } from '@ckeditor/ckeditor5-ui';
9
+ import type { Locale } from '@ckeditor/ckeditor5-utils';
10
+ /**
11
+ * The file dialog button view.
12
+ *
13
+ * This component provides a button that opens the native file selection dialog.
14
+ * It can be used to implement the UI of a file upload feature.
15
+ *
16
+ * ```ts
17
+ * const view = new FileDialogButtonView( locale );
18
+ *
19
+ * view.set( {
20
+ * acceptedType: 'image/*',
21
+ * allowMultipleFiles: true
22
+ * label: t( 'Insert image' ),
23
+ * icon: imageIcon,
24
+ * tooltip: true
25
+ * } );
26
+ *
27
+ * view.on( 'done', ( evt, files ) => {
28
+ * for ( const file of Array.from( files ) ) {
29
+ * console.log( 'Selected file', file );
30
+ * }
31
+ * } );
32
+ * ```
33
+ */
34
+ export default class FileDialogButtonView extends ButtonView {
35
+ /**
36
+ * The button view of the component.
37
+ *
38
+ * @deprecated
39
+ */
40
+ buttonView: ButtonView;
41
+ /**
42
+ * A hidden `<input>` view used to execute file dialog.
43
+ */
44
+ private _fileInputView;
45
+ /**
46
+ * Accepted file types. Can be provided in form of file extensions, media type or one of:
47
+ * * `audio/*`,
48
+ * * `video/*`,
49
+ * * `image/*`.
50
+ *
51
+ * @observable
52
+ */
53
+ acceptedType: string;
54
+ /**
55
+ * Indicates if multiple files can be selected. Defaults to `true`.
56
+ *
57
+ * @observable
58
+ */
59
+ allowMultipleFiles: boolean;
60
+ /**
61
+ * @inheritDoc
62
+ */
63
+ constructor(locale?: Locale);
64
+ /**
65
+ * @inheritDoc
66
+ */
67
+ render(): void;
68
+ }
69
+ /**
70
+ * Fired when file dialog is closed with file selected.
71
+ *
72
+ * ```ts
73
+ * view.on( 'done', ( evt, files ) => {
74
+ * for ( const file of files ) {
75
+ * console.log( 'Selected file', file );
76
+ * }
77
+ * }
78
+ * ```
79
+ */
80
+ export type FileInputViewDoneEvent = {
81
+ name: 'done';
82
+ args: [files: FileList];
83
+ };
@@ -0,0 +1,90 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
+ */
5
+ /**
6
+ * @module upload/uploadconfig
7
+ */
8
+ /**
9
+ * The configuration of the {@link module:upload/adapters/simpleuploadadapter~SimpleUploadAdapter simple upload adapter}.
10
+ *
11
+ * ```ts
12
+ * ClassicEditor
13
+ * .create( editorElement, {
14
+ * simpleUpload: {
15
+ * // The URL the images are uploaded to.
16
+ * uploadUrl: 'http://example.com',
17
+ *
18
+ * // Headers sent along with the XMLHttpRequest to the upload server.
19
+ * headers: {
20
+ * ...
21
+ * }
22
+ * }
23
+ * } );
24
+ * .then( ... )
25
+ * .catch( ... );
26
+ * ```
27
+ *
28
+ * See the {@glink features/images/image-upload/simple-upload-adapter "Simple upload adapter"} guide to learn more.
29
+ *
30
+ * See {@link module:core/editor/editorconfig~EditorConfig all editor configuration options}.
31
+ */
32
+ export interface SimpleUploadConfig {
33
+ /**
34
+ * The path (URL) to the server (application) which handles the file upload. When specified, enables the automatic
35
+ * upload of resources (images) inserted into the editor content.
36
+ *
37
+ * Learn more about the server application requirements in the
38
+ * {@glink features/images/image-upload/simple-upload-adapter#server-side-configuration "Server-side configuration"} section
39
+ * of the feature guide.
40
+ */
41
+ uploadUrl: string;
42
+ /**
43
+ * An object that defines additional [headers](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers) sent with
44
+ * the request to the server during the upload. This is the right place to implement security mechanisms like
45
+ * authentication and [CSRF](https://developer.mozilla.org/en-US/docs/Glossary/CSRF) protection.
46
+ *
47
+ * ```ts
48
+ * ClassicEditor
49
+ * .create( editorElement, {
50
+ * simpleUpload: {
51
+ * headers: {
52
+ * 'X-CSRF-TOKEN': 'CSRF-Token',
53
+ * Authorization: 'Bearer <JSON Web Token>'
54
+ * }
55
+ * }
56
+ * } );
57
+ * .then( ... )
58
+ * .catch( ... );
59
+ * ```
60
+ *
61
+ * Learn more about the server application requirements in the
62
+ * {@glink features/images/image-upload/simple-upload-adapter#server-side-configuration "Server-side configuration"} section
63
+ * of the feature guide.
64
+ */
65
+ headers?: Record<string, string>;
66
+ /**
67
+ * This flag enables the
68
+ * [`withCredentials`](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/withCredentials)
69
+ * property of the request sent to the server during the upload. It affects cross-site requests only and, for instance,
70
+ * allows credentials such as cookies to be sent along with the request.
71
+ *
72
+ * ```ts
73
+ * ClassicEditor
74
+ * .create( editorElement, {
75
+ * simpleUpload: {
76
+ * withCredentials: true
77
+ * }
78
+ * } );
79
+ * .then( ... )
80
+ * .catch( ... );
81
+ * ```
82
+ *
83
+ * Learn more about the server application requirements in the
84
+ * {@glink features/images/image-upload/simple-upload-adapter#server-side-configuration "Server-side configuration"} section
85
+ * of the feature guide.
86
+ *
87
+ * @default false
88
+ */
89
+ withCredentials?: boolean;
90
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ckeditor/ckeditor5-upload",
3
- "version": "41.2.0",
3
+ "version": "41.3.0-alpha.0",
4
4
  "description": "Upload feature for CKEditor 5.",
5
5
  "keywords": [
6
6
  "ckeditor",
@@ -12,9 +12,9 @@
12
12
  "type": "module",
13
13
  "main": "src/index.js",
14
14
  "dependencies": {
15
- "@ckeditor/ckeditor5-core": "41.2.0",
16
- "@ckeditor/ckeditor5-utils": "41.2.0",
17
- "@ckeditor/ckeditor5-ui": "41.2.0"
15
+ "@ckeditor/ckeditor5-core": "41.3.0-alpha.0",
16
+ "@ckeditor/ckeditor5-utils": "41.3.0-alpha.0",
17
+ "@ckeditor/ckeditor5-ui": "41.3.0-alpha.0"
18
18
  },
19
19
  "author": "CKSource (http://cksource.com/)",
20
20
  "license": "GPL-2.0-or-later",
@@ -26,6 +26,7 @@
26
26
  "directory": "packages/ckeditor5-upload"
27
27
  },
28
28
  "files": [
29
+ "dist",
29
30
  "lang",
30
31
  "src/**/*.js",
31
32
  "src/**/*.d.ts",