Created
December 25, 2023 17:48
-
-
Save alexisselorm/865812bd0cb6d0391f3eeae7a9e24918 to your computer and use it in GitHub Desktop.
Image Upload Adapter
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { ClassicEditor } from '@ckeditor/ckeditor5-editor-classic'; | |
import { | |
FileLoader, | |
UploadResponse, | |
} from '@ckeditor/ckeditor5-upload/src/filerepository'; | |
// Image Upload | |
export default class MyUploadAdapter { | |
loader: FileLoader; | |
xhr: any; | |
// ... | |
constructor(loader: FileLoader) { | |
// The file loader instance to use during the upload. It sounds scary but do not | |
// worry — the loader will be passed into the adapter later on in this guide. | |
this.loader = loader; | |
} | |
// Starts the upload process. | |
upload(): Promise<UploadResponse> { | |
console.log('Upload was at least hit. Therefore upload adapter works'); | |
return this.loader?.file.then( | |
(file: any) => | |
new Promise((resolve, reject) => { | |
this._initRequest(); | |
this._initListeners(resolve, reject, file); | |
this._sendRequest(file); | |
}) | |
); | |
} | |
// Aborts the upload process. | |
abort() { | |
if (this.xhr) { | |
this.xhr.abort(); | |
} | |
} | |
_initRequest() { | |
console.log('Request was initiated'); | |
const xhr = (this.xhr = new XMLHttpRequest()); | |
// Note that your request may look different. It is up to you and your editor | |
// integration to choose the right communication channel. This example uses | |
// a POST request with JSON as a data structure but your configuration | |
// could be different. | |
xhr.open('POST', 'api/image/upload', true); | |
xhr.responseType = 'json'; | |
} | |
// Initializes XMLHttpRequest listeners. | |
_initListeners(resolve: any, reject: any, file: File) { | |
const xhr = this.xhr; | |
const loader = this.loader; | |
const genericErrorText = `Couldn't upload file: ${file.name}.`; | |
xhr.addEventListener('error', () => reject(genericErrorText)); | |
xhr.addEventListener('abort', () => reject()); | |
xhr.addEventListener('load', () => { | |
const response = xhr.response; | |
console.log('response: ' + JSON.stringify(response)); | |
// This example assumes the XHR server's "response" object will come with | |
// an "error" which has its own "message" that can be passed to reject() | |
// in the upload promise. | |
// | |
// Your integration may handle upload errors in a different way so make sure | |
// it is done properly. The reject() function must be called when the upload fails. | |
if (!response || response.error) { | |
return reject( | |
response && response.error ? response.error.message : genericErrorText | |
); | |
} | |
// If the upload is successful, resolve the upload promise with an object containing | |
// at least the "default" URL, pointing to the image on the server. | |
// This URL will be used to display the image in the content. Learn more in the | |
// UploadAdapter#upload documentation. | |
resolve({ | |
default: response.url, | |
}); | |
}); | |
// Upload progress when it is supported. The file loader has the #uploadTotal and #uploaded | |
// properties which are used e.g. to display the upload progress bar in the editor | |
// user interface. | |
if (xhr.upload) { | |
console.log('Progress event', xhr); | |
xhr.upload.addEventListener('progress', (evt: ProgressEvent) => { | |
if (evt.lengthComputable) { | |
loader.uploadTotal = evt.total; | |
loader.uploaded = evt.loaded; | |
} | |
}); | |
} | |
} | |
// Prepares the data and sends the request. | |
_sendRequest(file: File) { | |
console.log('Send file request', file); | |
// Prepare the form data. | |
const data = new FormData(); | |
data.append('upload', file); | |
console.log(data); | |
// Important note: This is the right place to implement security mechanisms | |
// like authentication and CSRF protection. For instance, you can use | |
// XMLHttpRequest.setRequestHeader() to set the request headers containing | |
// the CSRF token generated earlier by your application. | |
// Send the request. | |
this.xhr.send(data); | |
} | |
// ... | |
} | |
// Upload ADAPTOR | |
export function MyCustomUploadAdapterPlugin(editor: any) { | |
editor.plugins.get('FileRepository').createUploadAdapter = ( | |
loader: FileLoader | |
) => { | |
// Configure the URL to the upload script in your back-end here! | |
return new MyUploadAdapter(loader); | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment