@ckeditor/ckeditor5-upload 41.4.2 → 42.0.0-alpha.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/dist/index.js CHANGED
@@ -3,27 +3,49 @@
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
4
  */
5
5
  import { Plugin, PendingActions } from '@ckeditor/ckeditor5-core/dist/index.js';
6
- import { ObservableMixin, CKEditorError, uid, logWarning, Collection } from '@ckeditor/ckeditor5-utils/dist/index.js';
6
+ import { ObservableMixin, Collection, logWarning, uid, CKEditorError } from '@ckeditor/ckeditor5-utils/dist/index.js';
7
7
 
8
- class FileReader extends ObservableMixin() {
8
+ /**
9
+ * Wrapper over the native `FileReader`.
10
+ */ class FileReader extends /* #__PURE__ */ ObservableMixin() {
11
+ total;
12
+ /**
13
+ * Instance of native FileReader.
14
+ */ _reader;
15
+ /**
16
+ * Holds the data of an already loaded file. The file must be first loaded
17
+ * by using {@link module:upload/filereader~FileReader#read `read()`}.
18
+ */ _data;
19
+ /**
20
+ * Creates an instance of the FileReader.
21
+ */ constructor(){
22
+ super();
23
+ const reader = new window.FileReader();
24
+ this._reader = reader;
25
+ this._data = undefined;
26
+ this.set('loaded', 0);
27
+ reader.onprogress = (evt)=>{
28
+ this.loaded = evt.loaded;
29
+ };
30
+ }
9
31
  /**
10
- * Returns error that occurred during file reading.
11
- */ get error() {
32
+ * Returns error that occurred during file reading.
33
+ */ get error() {
12
34
  return this._reader.error;
13
35
  }
14
36
  /**
15
- * Holds the data of an already loaded file. The file must be first loaded
16
- * by using {@link module:upload/filereader~FileReader#read `read()`}.
17
- */ get data() {
37
+ * Holds the data of an already loaded file. The file must be first loaded
38
+ * by using {@link module:upload/filereader~FileReader#read `read()`}.
39
+ */ get data() {
18
40
  return this._data;
19
41
  }
20
42
  /**
21
- * Reads the provided file.
22
- *
23
- * @param file Native File object.
24
- * @returns Returns a promise that will be resolved with file's content.
25
- * The promise will be rejected in case of an error or when the reading process is aborted.
26
- */ read(file) {
43
+ * Reads the provided file.
44
+ *
45
+ * @param file Native File object.
46
+ * @returns Returns a promise that will be resolved with file's content.
47
+ * The promise will be rejected in case of an error or when the reading process is aborted.
48
+ */ read(file) {
27
49
  const reader = this._reader;
28
50
  this.total = file.size;
29
51
  return new Promise((resolve, reject)=>{
@@ -42,40 +64,49 @@ class FileReader extends ObservableMixin() {
42
64
  });
43
65
  }
44
66
  /**
45
- * Aborts file reader.
46
- */ abort() {
67
+ * Aborts file reader.
68
+ */ abort() {
47
69
  this._reader.abort();
48
70
  }
49
- /**
50
- * Creates an instance of the FileReader.
51
- */ constructor(){
52
- super();
53
- const reader = new window.FileReader();
54
- this._reader = reader;
55
- this._data = undefined;
56
- this.set('loaded', 0);
57
- reader.onprogress = (evt)=>{
58
- this.loaded = evt.loaded;
59
- };
60
- }
61
71
  }
62
72
 
63
- class FileRepository extends Plugin {
73
+ /**
74
+ * File repository plugin. A central point for managing file upload.
75
+ *
76
+ * To use it, first you need an upload adapter. Upload adapter's job is to handle communication with the server
77
+ * (sending the file and handling server's response). You can use one of the existing plugins introducing upload adapters
78
+ * (e.g. {@link module:easy-image/cloudservicesuploadadapter~CloudServicesUploadAdapter} or
79
+ * {@link module:adapter-ckfinder/uploadadapter~CKFinderUploadAdapter}) or write your own one – see
80
+ * the {@glink framework/deep-dive/upload-adapter Custom image upload adapter deep-dive} guide.
81
+ *
82
+ * Then, you can use {@link module:upload/filerepository~FileRepository#createLoader `createLoader()`} and the returned
83
+ * {@link module:upload/filerepository~FileLoader} instance to load and upload files.
84
+ */ class FileRepository extends Plugin {
85
+ /**
86
+ * Collection of loaders associated with this repository.
87
+ */ loaders = new Collection();
88
+ /**
89
+ * Loaders mappings used to retrieve loaders references.
90
+ */ _loadersMap = new Map();
64
91
  /**
65
- * @inheritDoc
66
- */ static get pluginName() {
92
+ * Reference to a pending action registered in a {@link module:core/pendingactions~PendingActions} plugin
93
+ * while upload is in progress. When there is no upload then value is `null`.
94
+ */ _pendingAction = null;
95
+ /**
96
+ * @inheritDoc
97
+ */ static get pluginName() {
67
98
  return 'FileRepository';
68
99
  }
69
100
  /**
70
- * @inheritDoc
71
- */ static get requires() {
101
+ * @inheritDoc
102
+ */ static get requires() {
72
103
  return [
73
104
  PendingActions
74
105
  ];
75
106
  }
76
107
  /**
77
- * @inheritDoc
78
- */ init() {
108
+ * @inheritDoc
109
+ */ init() {
79
110
  // Keeps upload in a sync with pending actions.
80
111
  this.loaders.on('change', ()=>this._updatePendingAction());
81
112
  this.set('uploaded', 0);
@@ -85,45 +116,48 @@ class FileRepository extends Plugin {
85
116
  });
86
117
  }
87
118
  /**
88
- * Returns the loader associated with specified file or promise.
89
- *
90
- * To get loader by id use `fileRepository.loaders.get( id )`.
91
- *
92
- * @param fileOrPromise Native file or promise handle.
93
- */ getLoader(fileOrPromise) {
119
+ * Returns the loader associated with specified file or promise.
120
+ *
121
+ * To get loader by id use `fileRepository.loaders.get( id )`.
122
+ *
123
+ * @param fileOrPromise Native file or promise handle.
124
+ */ getLoader(fileOrPromise) {
94
125
  return this._loadersMap.get(fileOrPromise) || null;
95
126
  }
96
127
  /**
97
- * Creates a loader instance for the given file.
98
- *
99
- * Requires {@link #createUploadAdapter} factory to be defined.
100
- *
101
- * @param fileOrPromise Native File object or native Promise object which resolves to a File.
102
- */ createLoader(fileOrPromise) {
128
+ * Creates a loader instance for the given file.
129
+ *
130
+ * Requires {@link #createUploadAdapter} factory to be defined.
131
+ *
132
+ * @param fileOrPromise Native File object or native Promise object which resolves to a File.
133
+ */ createLoader(fileOrPromise) {
103
134
  if (!this.createUploadAdapter) {
104
135
  /**
105
- * You need to enable an upload adapter in order to be able to upload files.
106
- *
107
- * This warning shows up when {@link module:upload/filerepository~FileRepository} is being used
108
- * without {@link module:upload/filerepository~FileRepository#createUploadAdapter defining an upload adapter}.
109
- *
110
- * **If you see this warning when using one of the {@glink installation/getting-started/predefined-builds
111
- * CKEditor 5 Builds}**
112
- * it means that you did not configure any of the upload adapters available by default in those builds.
113
- *
114
- * See the {@glink features/images/image-upload/image-upload comprehensive "Image upload overview"} to learn which upload
115
- * adapters are available in the builds and how to configure them.
116
- *
117
- * **If you see this warning when using a custom build** there is a chance that you enabled
118
- * a feature like {@link module:image/imageupload~ImageUpload},
119
- * or {@link module:image/imageupload/imageuploadui~ImageUploadUI} but you did not enable any upload adapter.
120
- * You can choose one of the existing upload adapters listed in the
121
- * {@glink features/images/image-upload/image-upload "Image upload overview"}.
122
- *
123
- * You can also implement your {@glink framework/deep-dive/upload-adapter own image upload adapter}.
124
- *
125
- * @error filerepository-no-upload-adapter
126
- */ logWarning('filerepository-no-upload-adapter');
136
+ * You need to enable an upload adapter in order to be able to upload files.
137
+ *
138
+ * This warning shows up when {@link module:upload/filerepository~FileRepository} is being used
139
+ * without {@link module:upload/filerepository~FileRepository#createUploadAdapter defining an upload adapter}.
140
+ *
141
+ * **If you see this warning when using one of the {@glink getting-started/legacy/installation-methods/predefined-builds
142
+ * CKEditor 5 Builds}**
143
+ * it means that you did not configure any of the upload adapters available by default in those builds.
144
+ *
145
+ * Predefined builds are a deprecated solution and we strongly advise
146
+ * {@glink updating/new-installation-methods migrating to new installation methods}.
147
+ *
148
+ * See the {@glink features/images/image-upload/image-upload comprehensive "Image upload overview"} to learn which upload
149
+ * adapters are available in the builds and how to configure them.
150
+ *
151
+ * Otherwise, if you see this warning, there is a chance that you enabled
152
+ * a feature like {@link module:image/imageupload~ImageUpload},
153
+ * or {@link module:image/imageupload/imageuploadui~ImageUploadUI} but you did not enable any upload adapter.
154
+ * You can choose one of the existing upload adapters listed in the
155
+ * {@glink features/images/image-upload/image-upload "Image upload overview"}.
156
+ *
157
+ * You can also implement your {@glink framework/deep-dive/upload-adapter own image upload adapter}.
158
+ *
159
+ * @error filerepository-no-upload-adapter
160
+ */ logWarning('filerepository-no-upload-adapter');
127
161
  return null;
128
162
  }
129
163
  const loader = new FileLoader(Promise.resolve(fileOrPromise), this.createUploadAdapter);
@@ -157,10 +191,10 @@ class FileRepository extends Plugin {
157
191
  return loader;
158
192
  }
159
193
  /**
160
- * Destroys the given loader.
161
- *
162
- * @param fileOrPromiseOrLoader File or Promise associated with that loader or loader itself.
163
- */ destroyLoader(fileOrPromiseOrLoader) {
194
+ * Destroys the given loader.
195
+ *
196
+ * @param fileOrPromiseOrLoader File or Promise associated with that loader or loader itself.
197
+ */ destroyLoader(fileOrPromiseOrLoader) {
164
198
  const loader = fileOrPromiseOrLoader instanceof FileLoader ? fileOrPromiseOrLoader : this.getLoader(fileOrPromiseOrLoader);
165
199
  loader._destroy();
166
200
  this.loaders.remove(loader);
@@ -171,8 +205,8 @@ class FileRepository extends Plugin {
171
205
  });
172
206
  }
173
207
  /**
174
- * Registers or deregisters pending action bound with upload progress.
175
- */ _updatePendingAction() {
208
+ * Registers or deregisters pending action bound with upload progress.
209
+ */ _updatePendingAction() {
176
210
  const pendingActions = this.editor.plugins.get(PendingActions);
177
211
  if (this.loaders.length) {
178
212
  if (!this._pendingAction) {
@@ -186,28 +220,48 @@ class FileRepository extends Plugin {
186
220
  this._pendingAction = null;
187
221
  }
188
222
  }
189
- constructor(){
190
- super(...arguments);
191
- /**
192
- * Collection of loaders associated with this repository.
193
- */ this.loaders = new Collection();
194
- /**
195
- * Loaders mappings used to retrieve loaders references.
196
- */ this._loadersMap = new Map();
197
- /**
198
- * Reference to a pending action registered in a {@link module:core/pendingactions~PendingActions} plugin
199
- * while upload is in progress. When there is no upload then value is `null`.
200
- */ this._pendingAction = null;
201
- }
202
223
  }
203
224
  /**
204
225
  * File loader class.
205
226
  *
206
227
  * It is used to control the process of reading the file and uploading it using the specified upload adapter.
207
- */ class FileLoader extends ObservableMixin() {
228
+ */ class FileLoader extends /* #__PURE__ */ ObservableMixin() {
229
+ /**
230
+ * Unique id of FileLoader instance.
231
+ *
232
+ * @readonly
233
+ */ id;
234
+ /**
235
+ * Additional wrapper over the initial file promise passed to this loader.
236
+ */ _filePromiseWrapper;
237
+ /**
238
+ * Adapter instance associated with this file loader.
239
+ */ _adapter;
240
+ /**
241
+ * FileReader used by FileLoader.
242
+ */ _reader;
243
+ /**
244
+ * Creates a new instance of `FileLoader`.
245
+ *
246
+ * @param filePromise A promise which resolves to a file instance.
247
+ * @param uploadAdapterCreator The function which returns {@link module:upload/filerepository~UploadAdapter} instance.
248
+ */ constructor(filePromise, uploadAdapterCreator){
249
+ super();
250
+ this.id = uid();
251
+ this._filePromiseWrapper = this._createFilePromiseWrapper(filePromise);
252
+ this._adapter = uploadAdapterCreator(this);
253
+ this._reader = new FileReader();
254
+ this.set('status', 'idle');
255
+ this.set('uploaded', 0);
256
+ this.set('uploadTotal', null);
257
+ this.bind('uploadedPercent').to(this, 'uploaded', this, 'uploadTotal', (uploaded, total)=>{
258
+ return total ? uploaded / total * 100 : 0;
259
+ });
260
+ this.set('uploadResponse', null);
261
+ }
208
262
  /**
209
- * A `Promise` which resolves to a `File` instance associated with this file loader.
210
- */ get file() {
263
+ * A `Promise` which resolves to a `File` instance associated with this file loader.
264
+ */ get file() {
211
265
  if (!this._filePromiseWrapper) {
212
266
  // Loader was destroyed, return promise which resolves to null.
213
267
  return Promise.resolve(null);
@@ -224,40 +278,40 @@ class FileRepository extends Plugin {
224
278
  }
225
279
  }
226
280
  /**
227
- * Returns the file data. To read its data, you need for first load the file
228
- * by using the {@link module:upload/filerepository~FileLoader#read `read()`} method.
229
- */ get data() {
281
+ * Returns the file data. To read its data, you need for first load the file
282
+ * by using the {@link module:upload/filerepository~FileLoader#read `read()`} method.
283
+ */ get data() {
230
284
  return this._reader.data;
231
285
  }
232
286
  /**
233
- * Reads file using {@link module:upload/filereader~FileReader}.
234
- *
235
- * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `filerepository-read-wrong-status` when status
236
- * is different than `idle`.
237
- *
238
- * Example usage:
239
- *
240
- * ```ts
241
- * fileLoader.read()
242
- * .then( data => { ... } )
243
- * .catch( err => {
244
- * if ( err === 'aborted' ) {
245
- * console.log( 'Reading aborted.' );
246
- * } else {
247
- * console.log( 'Reading error.', err );
248
- * }
249
- * } );
250
- * ```
251
- *
252
- * @returns Returns promise that will be resolved with read data. Promise will be rejected if error
253
- * occurs or if read process is aborted.
254
- */ read() {
287
+ * Reads file using {@link module:upload/filereader~FileReader}.
288
+ *
289
+ * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `filerepository-read-wrong-status` when status
290
+ * is different than `idle`.
291
+ *
292
+ * Example usage:
293
+ *
294
+ * ```ts
295
+ * fileLoader.read()
296
+ * .then( data => { ... } )
297
+ * .catch( err => {
298
+ * if ( err === 'aborted' ) {
299
+ * console.log( 'Reading aborted.' );
300
+ * } else {
301
+ * console.log( 'Reading error.', err );
302
+ * }
303
+ * } );
304
+ * ```
305
+ *
306
+ * @returns Returns promise that will be resolved with read data. Promise will be rejected if error
307
+ * occurs or if read process is aborted.
308
+ */ read() {
255
309
  if (this.status != 'idle') {
256
310
  /**
257
- * You cannot call read if the status is different than idle.
258
- *
259
- * @error filerepository-read-wrong-status
260
- */ throw new CKEditorError('filerepository-read-wrong-status', this);
311
+ * You cannot call read if the status is different than idle.
312
+ *
313
+ * @error filerepository-read-wrong-status
314
+ */ throw new CKEditorError('filerepository-read-wrong-status', this);
261
315
  }
262
316
  this.status = 'reading';
263
317
  return this.file.then((file)=>this._reader.read(file)).then((data)=>{
@@ -278,33 +332,33 @@ class FileRepository extends Plugin {
278
332
  });
279
333
  }
280
334
  /**
281
- * Reads file using the provided {@link module:upload/filerepository~UploadAdapter}.
282
- *
283
- * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `filerepository-upload-wrong-status` when status
284
- * is different than `idle`.
285
- * Example usage:
286
- *
287
- * ```ts
288
- * fileLoader.upload()
289
- * .then( data => { ... } )
290
- * .catch( e => {
291
- * if ( e === 'aborted' ) {
292
- * console.log( 'Uploading aborted.' );
293
- * } else {
294
- * console.log( 'Uploading error.', e );
295
- * }
296
- * } );
297
- * ```
298
- *
299
- * @returns Returns promise that will be resolved with response data. Promise will be rejected if error
300
- * occurs or if read process is aborted.
301
- */ upload() {
335
+ * Reads file using the provided {@link module:upload/filerepository~UploadAdapter}.
336
+ *
337
+ * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `filerepository-upload-wrong-status` when status
338
+ * is different than `idle`.
339
+ * Example usage:
340
+ *
341
+ * ```ts
342
+ * fileLoader.upload()
343
+ * .then( data => { ... } )
344
+ * .catch( e => {
345
+ * if ( e === 'aborted' ) {
346
+ * console.log( 'Uploading aborted.' );
347
+ * } else {
348
+ * console.log( 'Uploading error.', e );
349
+ * }
350
+ * } );
351
+ * ```
352
+ *
353
+ * @returns Returns promise that will be resolved with response data. Promise will be rejected if error
354
+ * occurs or if read process is aborted.
355
+ */ upload() {
302
356
  if (this.status != 'idle') {
303
357
  /**
304
- * You cannot call upload if the status is different than idle.
305
- *
306
- * @error filerepository-upload-wrong-status
307
- */ throw new CKEditorError('filerepository-upload-wrong-status', this);
358
+ * You cannot call upload if the status is different than idle.
359
+ *
360
+ * @error filerepository-upload-wrong-status
361
+ */ throw new CKEditorError('filerepository-upload-wrong-status', this);
308
362
  }
309
363
  this.status = 'uploading';
310
364
  return this.file.then(()=>this._adapter.upload()).then((data)=>{
@@ -320,8 +374,8 @@ class FileRepository extends Plugin {
320
374
  });
321
375
  }
322
376
  /**
323
- * Aborts loading process.
324
- */ abort() {
377
+ * Aborts loading process.
378
+ */ abort() {
325
379
  const status = this.status;
326
380
  this.status = 'aborted';
327
381
  if (!this._filePromiseWrapper.isFulfilled) {
@@ -338,21 +392,21 @@ class FileRepository extends Plugin {
338
392
  this._destroy();
339
393
  }
340
394
  /**
341
- * Performs cleanup.
342
- *
343
- * @internal
344
- */ _destroy() {
395
+ * Performs cleanup.
396
+ *
397
+ * @internal
398
+ */ _destroy() {
345
399
  this._filePromiseWrapper = undefined;
346
400
  this._reader = undefined;
347
401
  this._adapter = undefined;
348
402
  this.uploadResponse = undefined;
349
403
  }
350
404
  /**
351
- * Wraps a given file promise into another promise giving additional
352
- * control (resolving, rejecting, checking if fulfilled) over it.
353
- *
354
- * @param filePromise The initial file promise to be wrapped.
355
- */ _createFilePromiseWrapper(filePromise) {
405
+ * Wraps a given file promise into another promise giving additional
406
+ * control (resolving, rejecting, checking if fulfilled) over it.
407
+ *
408
+ * @param filePromise The initial file promise to be wrapped.
409
+ */ _createFilePromiseWrapper(filePromise) {
356
410
  const wrapper = {};
357
411
  wrapper.promise = new Promise((resolve, reject)=>{
358
412
  wrapper.rejecter = reject;
@@ -367,43 +421,33 @@ class FileRepository extends Plugin {
367
421
  });
368
422
  return wrapper;
369
423
  }
370
- /**
371
- * Creates a new instance of `FileLoader`.
372
- *
373
- * @param filePromise A promise which resolves to a file instance.
374
- * @param uploadAdapterCreator The function which returns {@link module:upload/filerepository~UploadAdapter} instance.
375
- */ constructor(filePromise, uploadAdapterCreator){
376
- super();
377
- this.id = uid();
378
- this._filePromiseWrapper = this._createFilePromiseWrapper(filePromise);
379
- this._adapter = uploadAdapterCreator(this);
380
- this._reader = new FileReader();
381
- this.set('status', 'idle');
382
- this.set('uploaded', 0);
383
- this.set('uploadTotal', null);
384
- this.bind('uploadedPercent').to(this, 'uploaded', this, 'uploadTotal', (uploaded, total)=>{
385
- return total ? uploaded / total * 100 : 0;
386
- });
387
- this.set('uploadResponse', null);
388
- }
389
424
  }
390
425
 
391
- class Base64UploadAdapter extends Plugin {
426
+ /**
427
+ * A plugin that converts images inserted into the editor into [Base64 strings](https://en.wikipedia.org/wiki/Base64)
428
+ * in the {@glink getting-started/setup/getting-and-setting-data editor output}.
429
+ *
430
+ * This kind of image upload does not require server processing – images are stored with the rest of the text and
431
+ * displayed by the web browser without additional requests.
432
+ *
433
+ * Check out the {@glink features/images/image-upload/image-upload comprehensive "Image upload overview"} to learn about
434
+ * other ways to upload images into CKEditor 5.
435
+ */ class Base64UploadAdapter extends Plugin {
392
436
  /**
393
- * @inheritDoc
394
- */ static get requires() {
437
+ * @inheritDoc
438
+ */ static get requires() {
395
439
  return [
396
440
  FileRepository
397
441
  ];
398
442
  }
399
443
  /**
400
- * @inheritDoc
401
- */ static get pluginName() {
444
+ * @inheritDoc
445
+ */ static get pluginName() {
402
446
  return 'Base64UploadAdapter';
403
447
  }
404
448
  /**
405
- * @inheritDoc
406
- */ init() {
449
+ * @inheritDoc
450
+ */ init() {
407
451
  this.editor.plugins.get(FileRepository).createUploadAdapter = (loader)=>new Adapter$1(loader);
408
452
  }
409
453
  }
@@ -411,10 +455,19 @@ class Base64UploadAdapter extends Plugin {
411
455
  * The upload adapter that converts images inserted into the editor into Base64 strings.
412
456
  */ let Adapter$1 = class Adapter {
413
457
  /**
414
- * Starts the upload process.
415
- *
416
- * @see module:upload/filerepository~UploadAdapter#upload
417
- */ upload() {
458
+ * `FileLoader` instance to use during the upload.
459
+ */ loader;
460
+ reader;
461
+ /**
462
+ * Creates a new adapter instance.
463
+ */ constructor(loader){
464
+ this.loader = loader;
465
+ }
466
+ /**
467
+ * Starts the upload process.
468
+ *
469
+ * @see module:upload/filerepository~UploadAdapter#upload
470
+ */ upload() {
418
471
  return new Promise((resolve, reject)=>{
419
472
  const reader = this.reader = new window.FileReader();
420
473
  reader.addEventListener('load', ()=>{
@@ -434,47 +487,66 @@ class Base64UploadAdapter extends Plugin {
434
487
  });
435
488
  }
436
489
  /**
437
- * Aborts the upload process.
438
- *
439
- * @see module:upload/filerepository~UploadAdapter#abort
440
- */ abort() {
490
+ * Aborts the upload process.
491
+ *
492
+ * @see module:upload/filerepository~UploadAdapter#abort
493
+ */ abort() {
441
494
  this.reader.abort();
442
495
  }
443
- /**
444
- * Creates a new adapter instance.
445
- */ constructor(loader){
446
- this.loader = loader;
447
- }
448
496
  };
449
497
 
450
- class SimpleUploadAdapter extends Plugin {
498
+ /**
499
+ * The Simple upload adapter allows uploading images to an application running on your server using
500
+ * the [`XMLHttpRequest`](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) API with a
501
+ * minimal {@link module:upload/uploadconfig~SimpleUploadConfig editor configuration}.
502
+ *
503
+ * ```ts
504
+ * ClassicEditor
505
+ * .create( document.querySelector( '#editor' ), {
506
+ * simpleUpload: {
507
+ * uploadUrl: 'http://example.com',
508
+ * headers: {
509
+ * ...
510
+ * }
511
+ * }
512
+ * } )
513
+ * .then( ... )
514
+ * .catch( ... );
515
+ * ```
516
+ *
517
+ * See the {@glink features/images/image-upload/simple-upload-adapter "Simple upload adapter"} guide to learn how to
518
+ * learn more about the feature (configuration, server–side requirements, etc.).
519
+ *
520
+ * Check out the {@glink features/images/image-upload/image-upload comprehensive "Image upload overview"} to learn about
521
+ * other ways to upload images into CKEditor 5.
522
+ */ class SimpleUploadAdapter extends Plugin {
451
523
  /**
452
- * @inheritDoc
453
- */ static get requires() {
524
+ * @inheritDoc
525
+ */ static get requires() {
454
526
  return [
455
527
  FileRepository
456
528
  ];
457
529
  }
458
530
  /**
459
- * @inheritDoc
460
- */ static get pluginName() {
531
+ * @inheritDoc
532
+ */ static get pluginName() {
461
533
  return 'SimpleUploadAdapter';
462
534
  }
463
535
  /**
464
- * @inheritDoc
465
- */ init() {
536
+ * @inheritDoc
537
+ */ init() {
466
538
  const options = this.editor.config.get('simpleUpload');
467
539
  if (!options) {
468
540
  return;
469
541
  }
470
542
  if (!options.uploadUrl) {
471
543
  /**
472
- * The {@link module:upload/uploadconfig~SimpleUploadConfig#uploadUrl `config.simpleUpload.uploadUrl`}
473
- * configuration required by the {@link module:upload/adapters/simpleuploadadapter~SimpleUploadAdapter `SimpleUploadAdapter`}
474
- * is missing. Make sure the correct URL is specified for the image upload to work properly.
475
- *
476
- * @error simple-upload-adapter-missing-uploadurl
477
- */ logWarning('simple-upload-adapter-missing-uploadurl');
544
+ * The {@link module:upload/uploadconfig~SimpleUploadConfig#uploadUrl `config.simpleUpload.uploadUrl`}
545
+ * configuration required by the {@link module:upload/adapters/simpleuploadadapter~SimpleUploadAdapter `SimpleUploadAdapter`}
546
+ * is missing. Make sure the correct URL is specified for the image upload to work properly.
547
+ *
548
+ * @error simple-upload-adapter-missing-uploadurl
549
+ */ logWarning('simple-upload-adapter-missing-uploadurl');
478
550
  return;
479
551
  }
480
552
  this.editor.plugins.get(FileRepository).createUploadAdapter = (loader)=>{
@@ -486,10 +558,23 @@ class SimpleUploadAdapter extends Plugin {
486
558
  * Upload adapter.
487
559
  */ class Adapter {
488
560
  /**
489
- * Starts the upload process.
490
- *
491
- * @see module:upload/filerepository~UploadAdapter#upload
492
- */ upload() {
561
+ * FileLoader instance to use during the upload.
562
+ */ loader;
563
+ /**
564
+ * The configuration of the adapter.
565
+ */ options;
566
+ xhr;
567
+ /**
568
+ * Creates a new adapter instance.
569
+ */ constructor(loader, options){
570
+ this.loader = loader;
571
+ this.options = options;
572
+ }
573
+ /**
574
+ * Starts the upload process.
575
+ *
576
+ * @see module:upload/filerepository~UploadAdapter#upload
577
+ */ upload() {
493
578
  return this.loader.file.then((file)=>new Promise((resolve, reject)=>{
494
579
  this._initRequest();
495
580
  this._initListeners(resolve, reject, file);
@@ -497,30 +582,30 @@ class SimpleUploadAdapter extends Plugin {
497
582
  }));
498
583
  }
499
584
  /**
500
- * Aborts the upload process.
501
- *
502
- * @see module:upload/filerepository~UploadAdapter#abort
503
- */ abort() {
585
+ * Aborts the upload process.
586
+ *
587
+ * @see module:upload/filerepository~UploadAdapter#abort
588
+ */ abort() {
504
589
  if (this.xhr) {
505
590
  this.xhr.abort();
506
591
  }
507
592
  }
508
593
  /**
509
- * Initializes the `XMLHttpRequest` object using the URL specified as
510
- * {@link module:upload/uploadconfig~SimpleUploadConfig#uploadUrl `simpleUpload.uploadUrl`} in the editor's
511
- * configuration.
512
- */ _initRequest() {
594
+ * Initializes the `XMLHttpRequest` object using the URL specified as
595
+ * {@link module:upload/uploadconfig~SimpleUploadConfig#uploadUrl `simpleUpload.uploadUrl`} in the editor's
596
+ * configuration.
597
+ */ _initRequest() {
513
598
  const xhr = this.xhr = new XMLHttpRequest();
514
599
  xhr.open('POST', this.options.uploadUrl, true);
515
600
  xhr.responseType = 'json';
516
601
  }
517
602
  /**
518
- * Initializes XMLHttpRequest listeners
519
- *
520
- * @param resolve Callback function to be called when the request is successful.
521
- * @param reject Callback function to be called when the request cannot be completed.
522
- * @param file Native File object.
523
- */ _initListeners(resolve, reject, file) {
603
+ * Initializes XMLHttpRequest listeners
604
+ *
605
+ * @param resolve Callback function to be called when the request is successful.
606
+ * @param reject Callback function to be called when the request cannot be completed.
607
+ * @param file Native File object.
608
+ */ _initListeners(resolve, reject, file) {
524
609
  const xhr = this.xhr;
525
610
  const loader = this.loader;
526
611
  const genericErrorText = `Couldn't upload file: ${file.name}.`;
@@ -552,10 +637,10 @@ class SimpleUploadAdapter extends Plugin {
552
637
  }
553
638
  }
554
639
  /**
555
- * Prepares the data and sends the request.
556
- *
557
- * @param file File instance to be uploaded.
558
- */ _sendRequest(file) {
640
+ * Prepares the data and sends the request.
641
+ *
642
+ * @param file File instance to be uploaded.
643
+ */ _sendRequest(file) {
559
644
  // Set headers if specified.
560
645
  const headers = this.options.headers || {};
561
646
  // Use the withCredentials flag if specified.
@@ -570,12 +655,6 @@ class SimpleUploadAdapter extends Plugin {
570
655
  // Send the request.
571
656
  this.xhr.send(data);
572
657
  }
573
- /**
574
- * Creates a new adapter instance.
575
- */ constructor(loader, options){
576
- this.loader = loader;
577
- this.options = options;
578
- }
579
658
  }
580
659
 
581
660
  export { Base64UploadAdapter, FileRepository, SimpleUploadAdapter };