@ckeditor/ckeditor5-upload 41.4.2 → 42.0.0-alpha.0

Sign up to get free protection for your applications and to get access to all the features.
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 };