From c7303e16ed6bbdf8942d624303cd47feab9a4151 Mon Sep 17 00:00:00 2001 From: slaveeks Date: Thu, 4 Jul 2024 19:25:32 +0300 Subject: [PATCH 01/17] feat: added custom downloader --- README.md | 52 ++++++++++++++++++++++++++++++++++++++++++++++- src/downloader.js | 51 ++++++++++++++++++++++++++++++++++++++++++++++ src/index.js | 42 ++++++++++++++++++++++++++++++++++++-- src/ui.js | 1 - 4 files changed, 142 insertions(+), 4 deletions(-) create mode 100644 src/downloader.js diff --git a/README.md b/README.md index a0d59f39..e186a86a 100644 --- a/README.md +++ b/README.md @@ -82,6 +82,7 @@ Image Tool supports these configuration parameters: | captionPlaceholder | `string` | (default: `Caption`) Placeholder for Caption input | | buttonContent | `string` | Allows to override HTML content of «Select file» button | | uploader | `{{uploadByFile: function, uploadByUrl: function}}` | Optional custom uploading methods. See details below. | +| downloader | `{{download: function}}` | Optional custom downloading method. See details below. | | actions | `array` | Array with custom actions to show in the tool's settings menu. See details below. | Note that if you don't implement your custom uploader methods, the `endpoints` param is required. @@ -178,7 +179,7 @@ The response of your uploader **should** cover the following format: **success** - uploading status. 1 for successful, 0 for failed -**file** - uploaded file data. **Must** contain an `url` field with full public path to the uploaded image. +**file** - uploaded file data. **Must** contain an `url` field with full public path to the uploaded image or data key for using it in custom downloader. Also, can contain any additional fields you want to store. For example, width, height, id etc. All additional fields will be saved at the `file` object of output data. @@ -281,3 +282,52 @@ var editor = EditorJS({ ... }); ``` + +## Providing custom downloading method + +As mentioned at the Config Params section, you have an ability to provide own custom downloading method. +It is a quite simple: implement `download` method and pass it via `downloader` config param. +Method must return a Promise that resolves with url, which we can pass to the element and show it + + +| Method | Arguments | Return value | Description | +| -------------- | --------- | ------------- | ------------| +| download | `fileData`| `{Promise.}` | Download file by file data convert it and return valid file url | + +Example: + +```js +import ImageTool from '@editorjs/image'; + +var editor = EditorJS({ + ... + + tools: { + ... + image: { + class: ImageTool, + config: { + /** + * Custom downloader + */ + downloader: { + /** + * Download file from the server using file data. + * @param {string} fileData - data required for downloading + * @return {Promise.} - valid url + */ + uploadByU + download(fileData) { + // your ajax request for downloading + return MyAjax.download(fileData).then((data) => { + return URL.createObjectURL(data); + }) + } + } + } + } + } + + ... +}); +``` \ No newline at end of file diff --git a/src/downloader.js b/src/downloader.js new file mode 100644 index 00000000..c1020c4b --- /dev/null +++ b/src/downloader.js @@ -0,0 +1,51 @@ +import isPromise from './utils/isPromise'; + +/** + * Module for file downloading. Handle case, when you have to use custom downloading method + */ +export default class Downloader { + /** + * @param {object} params - downloader module params + * @param {ImageConfig} params.config - image tool config + * @param {Function} params.onDownload - callback which is called, when file is downloaded + * @param {Function} params.onError - callback for downloading errors + */ + constructor({ config, onDownload, onError }) { + this.config = config; + this.onDownload = onDownload + this.onError = onError; + } + + /** + * Try to download file data and fill it using stored data + * + * @param {string} fileData - may be some key for custom downloading or url + */ + download(fileData) { + /** + * Check that custom downloader passed + */ + if (this.config.downloader && typeof this.config.downloader.download === 'function') { + const downloadData = this.config.downloader.download(fileData); + + if (!isPromise(downloadData)) { + console.warn('Custom downloader method download should return a Promise'); + } + + downloadData.then((response) => { + /** + * Call callback for successful downloading with url + */ + this.onDownload(response); + }).catch((error) => { + this.onError(error); + }); + } else { + /** + * If there is no custom download method, fileData is correct url + * We only need to call callback + */ + this.onDownload(fileData); + } + } +} diff --git a/src/index.js b/src/index.js index ff00b214..c4273c10 100644 --- a/src/index.js +++ b/src/index.js @@ -11,6 +11,7 @@ * 2) uploader.js — module that has methods for sending files via AJAX: from device, by URL or File pasting * 3) ui.js — module for UI manipulations: render, showing preloader, etc * 4) tunes.js — working with Block Tunes: render buttons, handle clicks + * 5) downloader.js - module, which helps to use custom downloader using stored file data key * * For debug purposes there is a testing server * that can save uploaded files and return a Response {@link UploadResponseFormat} @@ -41,6 +42,7 @@ * @property {string} file.url — image URL */ +import Downloader from './downloader'; import './index.css'; import Ui from './ui'; @@ -61,6 +63,7 @@ import { IconAddBorder, IconStretch, IconAddBackground, IconPicture } from '@cod * @property {object} additionalRequestHeaders - allows to pass custom headers with Request * @property {string} buttonContent - overrides for Select File button * @property {object} [uploader] - optional custom uploader + * @property {object} [downloader] - optional custom downloader * @property {function(File): Promise.} [uploader.uploadByFile] - method that upload image by File * @property {function(string): Promise.} [uploader.uploadByUrl] - method that upload image by URL */ @@ -72,7 +75,7 @@ import { IconAddBorder, IconStretch, IconAddBackground, IconPicture } from '@cod * @property {object} file - Object with file data. * 'url' is required, * also can contain any additional data that will be saved and passed back - * @property {string} file.url - [Required] image source URL + * @property {string} file.url - [Required] image source URL or file data key to load it via custom downloader */ export default class ImageTool { /** @@ -152,6 +155,7 @@ export default class ImageTool { buttonContent: config.buttonContent || '', uploader: config.uploader || undefined, actions: config.actions || [], + downloader: config.downloader || undefined }; /** @@ -179,6 +183,15 @@ export default class ImageTool { readOnly, }); + /** + * Module for file downloading + */ + this.downloader = new Downloader({ + config: this.config, + onDownload: (url) => this.onDownload(url), + onError: this.downloadingFileError, + }) + /** * Set saved state */ @@ -383,7 +396,7 @@ export default class ImageTool { this._data.file = file || {}; if (file && file.url) { - this.ui.fillImage(file.url); + this.downloader.download(file.url) } } @@ -420,6 +433,31 @@ export default class ImageTool { this.ui.hidePreloader(); } + /** + * Handle downloader errors + * + * @private + * @param {string} errorText - downloading error text + * @returns {void} + */ + downloadingFileError(errorText) { + console.log('Image Tool: downloading failed because of', errorText); + + this.api.notifier.show({ + message: this.api.i18n.t('Couldn’t download image. Please try another.'), + style: 'error', + }); + } + + /** + * File downloading callback, fills file data into image + * + * @param {*} url - file url after downloading + */ + onDownload(url) { + this.ui.fillImage(url) + } + /** * Callback fired when Block Tune is activated * diff --git a/src/ui.js b/src/ui.js index 8609ef21..d63cfe08 100644 --- a/src/ui.js +++ b/src/ui.js @@ -188,7 +188,6 @@ export default class Ui { */ eventName = 'loadeddata'; } - /** * Compose tag with defined attributes * From fa0d4c90692c3a69f34a75cf0cd34f06590512b9 Mon Sep 17 00:00:00 2001 From: slaveeks Date: Thu, 4 Jul 2024 20:15:19 +0300 Subject: [PATCH 02/17] fix: eslint --- src/downloader.js | 2 +- src/index.js | 13 +++++++------ src/ui.js | 1 - src/uploader.js | 1 - 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/downloader.js b/src/downloader.js index c1020c4b..4cfa4e78 100644 --- a/src/downloader.js +++ b/src/downloader.js @@ -12,7 +12,7 @@ export default class Downloader { */ constructor({ config, onDownload, onError }) { this.config = config; - this.onDownload = onDownload + this.onDownload = onDownload; this.onError = onError; } diff --git a/src/index.js b/src/index.js index c4273c10..d700f637 100644 --- a/src/index.js +++ b/src/index.js @@ -63,9 +63,10 @@ import { IconAddBorder, IconStretch, IconAddBackground, IconPicture } from '@cod * @property {object} additionalRequestHeaders - allows to pass custom headers with Request * @property {string} buttonContent - overrides for Select File button * @property {object} [uploader] - optional custom uploader - * @property {object} [downloader] - optional custom downloader * @property {function(File): Promise.} [uploader.uploadByFile] - method that upload image by File * @property {function(string): Promise.} [uploader.uploadByUrl] - method that upload image by URL + * @property {object} [downloader] - optional custom downloader + * @property {function(string): Promise.} [downloader.download] - method that download image by data key */ /** @@ -155,7 +156,7 @@ export default class ImageTool { buttonContent: config.buttonContent || '', uploader: config.uploader || undefined, actions: config.actions || [], - downloader: config.downloader || undefined + downloader: config.downloader || undefined, }; /** @@ -190,7 +191,7 @@ export default class ImageTool { config: this.config, onDownload: (url) => this.onDownload(url), onError: this.downloadingFileError, - }) + }); /** * Set saved state @@ -396,7 +397,7 @@ export default class ImageTool { this._data.file = file || {}; if (file && file.url) { - this.downloader.download(file.url) + this.downloader.download(file.url); } } @@ -451,11 +452,11 @@ export default class ImageTool { /** * File downloading callback, fills file data into image - * + * * @param {*} url - file url after downloading */ onDownload(url) { - this.ui.fillImage(url) + this.ui.fillImage(url); } /** diff --git a/src/ui.js b/src/ui.js index d63cfe08..9676a071 100644 --- a/src/ui.js +++ b/src/ui.js @@ -249,4 +249,3 @@ export default class Ui { this.nodes.wrapper.classList.toggle(`${this.CSS.wrapper}--${tuneName}`, status); } } - diff --git a/src/uploader.js b/src/uploader.js index bfa6e2a5..d42e96d4 100644 --- a/src/uploader.js +++ b/src/uploader.js @@ -176,4 +176,3 @@ export default class Uploader { }); } } - From c30e4c62b0705ae68ddfeeb5f5c0336b2a0abc58 Mon Sep 17 00:00:00 2001 From: Vyacheslav Chernyshev <81693471+slaveeks@users.noreply.github.com> Date: Thu, 4 Jul 2024 22:11:33 +0300 Subject: [PATCH 03/17] Apply suggestions from code review Co-authored-by: Peter Savchenko --- src/downloader.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/downloader.js b/src/downloader.js index 4cfa4e78..ccad0949 100644 --- a/src/downloader.js +++ b/src/downloader.js @@ -3,7 +3,7 @@ import isPromise from './utils/isPromise'; /** * Module for file downloading. Handle case, when you have to use custom downloading method */ -export default class Downloader { +export default class ImageResolver { /** * @param {object} params - downloader module params * @param {ImageConfig} params.config - image tool config @@ -21,7 +21,7 @@ export default class Downloader { * * @param {string} fileData - may be some key for custom downloading or url */ - download(fileData) { + resolveUrlByFileData(fileData) { /** * Check that custom downloader passed */ From 4f6544ba4edfdb0fcbc61004ba51e86a46a59a6a Mon Sep 17 00:00:00 2001 From: slaveeks Date: Thu, 4 Jul 2024 22:48:46 +0300 Subject: [PATCH 04/17] downloader -> imageResolver --- README.md | 23 ++++++++++---------- src/downloader.js | 51 -------------------------------------------- src/imageResolver.js | 51 ++++++++++++++++++++++++++++++++++++++++++++ src/index.js | 41 ++++++++++++++++++----------------- 4 files changed, 83 insertions(+), 83 deletions(-) delete mode 100644 src/downloader.js create mode 100644 src/imageResolver.js diff --git a/README.md b/README.md index e186a86a..340e8038 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ Image Tool supports these configuration parameters: | captionPlaceholder | `string` | (default: `Caption`) Placeholder for Caption input | | buttonContent | `string` | Allows to override HTML content of «Select file» button | | uploader | `{{uploadByFile: function, uploadByUrl: function}}` | Optional custom uploading methods. See details below. | -| downloader | `{{download: function}}` | Optional custom downloading method. See details below. | +| imageResolver | `{{resolveUrlByFileData: function}}` | Optional custom image resolving method. See details below. | | actions | `array` | Array with custom actions to show in the tool's settings menu. See details below. | Note that if you don't implement your custom uploader methods, the `endpoints` param is required. @@ -179,7 +179,7 @@ The response of your uploader **should** cover the following format: **success** - uploading status. 1 for successful, 0 for failed -**file** - uploaded file data. **Must** contain an `url` field with full public path to the uploaded image or data key for using it in custom downloader. +**file** - uploaded file data. **Must** contain an `url` field with full public path to the uploaded image or data key for using it in custom image resolver. Also, can contain any additional fields you want to store. For example, width, height, id etc. All additional fields will be saved at the `file` object of output data. @@ -285,14 +285,14 @@ var editor = EditorJS({ ## Providing custom downloading method -As mentioned at the Config Params section, you have an ability to provide own custom downloading method. -It is a quite simple: implement `download` method and pass it via `downloader` config param. +As mentioned at the Config Params section, you have an ability to provide own custom image resolving method. +It is a quite simple: implement `resolveUrlByFileData` method and pass it via `imageResolver` config param. Method must return a Promise that resolves with url, which we can pass to the element and show it | Method | Arguments | Return value | Description | | -------------- | --------- | ------------- | ------------| -| download | `fileData`| `{Promise.}` | Download file by file data convert it and return valid file url | +| resolveUrlByFileData | `fileData`| `{Promise.}` | Resolve image url by file data | Example: @@ -308,17 +308,16 @@ var editor = EditorJS({ class: ImageTool, config: { /** - * Custom downloader + * Custom image resolver */ - downloader: { + imageResolver: { /** - * Download file from the server using file data. - * @param {string} fileData - data required for downloading + * Resolve image url by file data. + * @param {string} fileData - data required for image url resolving * @return {Promise.} - valid url */ - uploadByU - download(fileData) { - // your ajax request for downloading + resolveUrlByFileData(fileData) { + // your ajax request for image url resolving return MyAjax.download(fileData).then((data) => { return URL.createObjectURL(data); }) diff --git a/src/downloader.js b/src/downloader.js deleted file mode 100644 index ccad0949..00000000 --- a/src/downloader.js +++ /dev/null @@ -1,51 +0,0 @@ -import isPromise from './utils/isPromise'; - -/** - * Module for file downloading. Handle case, when you have to use custom downloading method - */ -export default class ImageResolver { - /** - * @param {object} params - downloader module params - * @param {ImageConfig} params.config - image tool config - * @param {Function} params.onDownload - callback which is called, when file is downloaded - * @param {Function} params.onError - callback for downloading errors - */ - constructor({ config, onDownload, onError }) { - this.config = config; - this.onDownload = onDownload; - this.onError = onError; - } - - /** - * Try to download file data and fill it using stored data - * - * @param {string} fileData - may be some key for custom downloading or url - */ - resolveUrlByFileData(fileData) { - /** - * Check that custom downloader passed - */ - if (this.config.downloader && typeof this.config.downloader.download === 'function') { - const downloadData = this.config.downloader.download(fileData); - - if (!isPromise(downloadData)) { - console.warn('Custom downloader method download should return a Promise'); - } - - downloadData.then((response) => { - /** - * Call callback for successful downloading with url - */ - this.onDownload(response); - }).catch((error) => { - this.onError(error); - }); - } else { - /** - * If there is no custom download method, fileData is correct url - * We only need to call callback - */ - this.onDownload(fileData); - } - } -} diff --git a/src/imageResolver.js b/src/imageResolver.js new file mode 100644 index 00000000..b126410d --- /dev/null +++ b/src/imageResolver.js @@ -0,0 +1,51 @@ +import isPromise from './utils/isPromise'; + +/** + * Module for file image resolving. Handle case, when you have to use custom image resolving method + */ +export default class ImageResolver { + /** + * @param {object} params - downloader module params + * @param {ImageConfig} params.config - image tool config + * @param {Function} params.onResolve - callback which is called, when file is resolved + * @param {Function} params.onError - callback for resolving errors + */ + constructor({ config, onResolve, onError }) { + this.config = config; + this.onResolve = onResolve; + this.onError = onError; + } + + /** + * Try to resolve image url by file data and fill it using stored data + * + * @param {string} fileData - file data from custom image resolving + */ + resolveUrlByFileData(fileData) { + /** + * Check that custom downloader passed + */ + if (this.config.imageResolver && typeof this.config.imageResolver.resolveUrlByFileData === 'function') { + const resolveFileData = this.config.imageResolver.resolveUrlByFileData(fileData); + + if (!isPromise(resolveFileData)) { + console.warn('Custom downloader method download should return a Promise'); + } + + resolveFileData.then((response) => { + /** + * Call callback for successful resolving with url + */ + this.onResolve(response); + }).catch((error) => { + this.onError(error); + }); + } else { + /** + * If there is no custom resolve method, fileData is correct url + * We only need to call callback + */ + this.onResolve(fileData); + } + } +} diff --git a/src/index.js b/src/index.js index d700f637..608629d1 100644 --- a/src/index.js +++ b/src/index.js @@ -11,7 +11,7 @@ * 2) uploader.js — module that has methods for sending files via AJAX: from device, by URL or File pasting * 3) ui.js — module for UI manipulations: render, showing preloader, etc * 4) tunes.js — working with Block Tunes: render buttons, handle clicks - * 5) downloader.js - module, which helps to use custom downloader using stored file data key + * 5) imageResolver.js - module, which helps to use custom image resolver via stored file data key * * For debug purposes there is a testing server * that can save uploaded files and return a Response {@link UploadResponseFormat} @@ -42,7 +42,8 @@ * @property {string} file.url — image URL */ -import Downloader from './downloader'; +import ImageResolver from './imageResolver'; +import Downloader from './imageResolver'; import './index.css'; import Ui from './ui'; @@ -65,8 +66,8 @@ import { IconAddBorder, IconStretch, IconAddBackground, IconPicture } from '@cod * @property {object} [uploader] - optional custom uploader * @property {function(File): Promise.} [uploader.uploadByFile] - method that upload image by File * @property {function(string): Promise.} [uploader.uploadByUrl] - method that upload image by URL - * @property {object} [downloader] - optional custom downloader - * @property {function(string): Promise.} [downloader.download] - method that download image by data key + * @property {object} [imageResolver] - optional custom image data resolver + * @property {function(string): Promise.} [imageResolver.resolveUrlByFileData] - method that resolves image by file data */ /** @@ -76,7 +77,7 @@ import { IconAddBorder, IconStretch, IconAddBackground, IconPicture } from '@cod * @property {object} file - Object with file data. * 'url' is required, * also can contain any additional data that will be saved and passed back - * @property {string} file.url - [Required] image source URL or file data key to load it via custom downloader + * @property {string} file.url - [Required] image source URL or file data key to resolve it via custom image resolver */ export default class ImageTool { /** @@ -156,11 +157,11 @@ export default class ImageTool { buttonContent: config.buttonContent || '', uploader: config.uploader || undefined, actions: config.actions || [], - downloader: config.downloader || undefined, + imageResolver: config.imageResolver || undefined, }; /** - * Module for file uploading + * Module for image uploading */ this.uploader = new Uploader({ config: this.config, @@ -185,12 +186,12 @@ export default class ImageTool { }); /** - * Module for file downloading + * Module for image resolving */ - this.downloader = new Downloader({ + this.imageResolver = new ImageResolver({ config: this.config, - onDownload: (url) => this.onDownload(url), - onError: this.downloadingFileError, + onResolve: (url) => this.onResolve(url), + onError: this.resolvingFileError, }); /** @@ -397,7 +398,7 @@ export default class ImageTool { this._data.file = file || {}; if (file && file.url) { - this.downloader.download(file.url); + this.imageResolver.resolveUrlByFileData(file.url); } } @@ -435,27 +436,27 @@ export default class ImageTool { } /** - * Handle downloader errors + * Handle image resolver errors * * @private - * @param {string} errorText - downloading error text + * @param {string} errorText - resolving error text * @returns {void} */ - downloadingFileError(errorText) { - console.log('Image Tool: downloading failed because of', errorText); + resolvingFileError(errorText) { + console.log('Image Tool: resolving failed because of', errorText); this.api.notifier.show({ - message: this.api.i18n.t('Couldn’t download image. Please try another.'), + message: this.api.i18n.t('Couldn’t resolve image. Please try another.'), style: 'error', }); } /** - * File downloading callback, fills file data into image + * Image resolving callback, fills file data into image * - * @param {*} url - file url after downloading + * @param {*} url - file url after resolving */ - onDownload(url) { + onResolve(url) { this.ui.fillImage(url); } From e26aa80937526262071fcb3456d1dd2ac7776080 Mon Sep 17 00:00:00 2001 From: slaveeks Date: Thu, 4 Jul 2024 22:50:38 +0300 Subject: [PATCH 05/17] fix: eslint --- src/index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/index.js b/src/index.js index 608629d1..4a0ef61d 100644 --- a/src/index.js +++ b/src/index.js @@ -43,7 +43,6 @@ */ import ImageResolver from './imageResolver'; -import Downloader from './imageResolver'; import './index.css'; import Ui from './ui'; From 532b312ec667d76d454c9bd4239df6ff92bac7e7 Mon Sep 17 00:00:00 2001 From: slaveeks Date: Thu, 4 Jul 2024 22:51:35 +0300 Subject: [PATCH 06/17] change readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 340e8038..b52fff17 100644 --- a/README.md +++ b/README.md @@ -210,7 +210,7 @@ Response of your uploader should be at the same format as described at «[Upload Your backend will accept file as FormData object in field name, specified by `config.field` (by default, «`image`»). You should save it and return the same response format as described above. -## Providing custom uploading methods +## Providing custom image url resolving methods As mentioned at the Config Params section, you have an ability to provide own custom uploading methods. It is a quite simple: implement `uploadByFile` and `uploadByUrl` methods and pass them via `uploader` config param. From 9ee60d75474f4ac2f29a4000e71753c3f37f33bf Mon Sep 17 00:00:00 2001 From: slaveeks Date: Thu, 4 Jul 2024 22:52:28 +0300 Subject: [PATCH 07/17] fix: rednme --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b52fff17..6f2bdf45 100644 --- a/README.md +++ b/README.md @@ -210,7 +210,7 @@ Response of your uploader should be at the same format as described at «[Upload Your backend will accept file as FormData object in field name, specified by `config.field` (by default, «`image`»). You should save it and return the same response format as described above. -## Providing custom image url resolving methods +## Providing custom uploading methods As mentioned at the Config Params section, you have an ability to provide own custom uploading methods. It is a quite simple: implement `uploadByFile` and `uploadByUrl` methods and pass them via `uploader` config param. @@ -283,7 +283,7 @@ var editor = EditorJS({ }); ``` -## Providing custom downloading method +## Providing custom image url resolving methods As mentioned at the Config Params section, you have an ability to provide own custom image resolving method. It is a quite simple: implement `resolveUrlByFileData` method and pass it via `imageResolver` config param. From 35e9d63cfbdb06024bdffdbb69fa11290ccdb6a7 Mon Sep 17 00:00:00 2001 From: slaveeks Date: Thu, 4 Jul 2024 22:53:51 +0300 Subject: [PATCH 08/17] fix: imageResolver docs --- src/imageResolver.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/imageResolver.js b/src/imageResolver.js index b126410d..41249cdf 100644 --- a/src/imageResolver.js +++ b/src/imageResolver.js @@ -5,7 +5,7 @@ import isPromise from './utils/isPromise'; */ export default class ImageResolver { /** - * @param {object} params - downloader module params + * @param {object} params - image resolver module params * @param {ImageConfig} params.config - image tool config * @param {Function} params.onResolve - callback which is called, when file is resolved * @param {Function} params.onError - callback for resolving errors From 19652a3bd43281df9f9deff6b4ef470f33567e9b Mon Sep 17 00:00:00 2001 From: slaveeks Date: Thu, 4 Jul 2024 22:54:58 +0300 Subject: [PATCH 09/17] fix: fix comment --- src/imageResolver.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/imageResolver.js b/src/imageResolver.js index 41249cdf..cd7cb854 100644 --- a/src/imageResolver.js +++ b/src/imageResolver.js @@ -23,7 +23,7 @@ export default class ImageResolver { */ resolveUrlByFileData(fileData) { /** - * Check that custom downloader passed + * Check that custom url resolver passed */ if (this.config.imageResolver && typeof this.config.imageResolver.resolveUrlByFileData === 'function') { const resolveFileData = this.config.imageResolver.resolveUrlByFileData(fileData); From c2f3d1b7e4473937665d6aeec7f679b2c2bb64a1 Mon Sep 17 00:00:00 2001 From: slaveeks Date: Thu, 4 Jul 2024 22:56:04 +0300 Subject: [PATCH 10/17] fix comment --- src/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.js b/src/index.js index 4a0ef61d..852933f4 100644 --- a/src/index.js +++ b/src/index.js @@ -160,7 +160,7 @@ export default class ImageTool { }; /** - * Module for image uploading + * Module for file uploading */ this.uploader = new Uploader({ config: this.config, From e8da2c3b9e9e8fed3a96b398e43bfced7972b654 Mon Sep 17 00:00:00 2001 From: slaveeks Date: Thu, 4 Jul 2024 22:58:05 +0300 Subject: [PATCH 11/17] fix: fixed doc --- src/imageResolver.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/imageResolver.js b/src/imageResolver.js index cd7cb854..61d146d9 100644 --- a/src/imageResolver.js +++ b/src/imageResolver.js @@ -19,7 +19,7 @@ export default class ImageResolver { /** * Try to resolve image url by file data and fill it using stored data * - * @param {string} fileData - file data from custom image resolving + * @param {string} fileData - file data, from which file url need to be resolved */ resolveUrlByFileData(fileData) { /** From 19388f7515bac7131ea78cd1740a965ae7632d15 Mon Sep 17 00:00:00 2001 From: Vyacheslav Chernyshev <81693471+slaveeks@users.noreply.github.com> Date: Thu, 4 Jul 2024 23:17:15 +0300 Subject: [PATCH 12/17] Apply suggestions from code review Co-authored-by: Peter Savchenko --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6f2bdf45..3017067d 100644 --- a/README.md +++ b/README.md @@ -287,12 +287,12 @@ var editor = EditorJS({ As mentioned at the Config Params section, you have an ability to provide own custom image resolving method. It is a quite simple: implement `resolveUrlByFileData` method and pass it via `imageResolver` config param. -Method must return a Promise that resolves with url, which we can pass to the element and show it +Method must return a Promise that resolves with url, which we can pass to the image element and show it | Method | Arguments | Return value | Description | | -------------- | --------- | ------------- | ------------| -| resolveUrlByFileData | `fileData`| `{Promise.}` | Resolve image url by file data | +| resolveUrlByFileData | `fileData`| `Promise.` | Resolve image url by file data | Example: From e9a655d54f52f253fd55a9b71ae0ef3baf2ecea5 Mon Sep 17 00:00:00 2001 From: Vyacheslav Chernyshev <81693471+slaveeks@users.noreply.github.com> Date: Thu, 4 Jul 2024 23:18:07 +0300 Subject: [PATCH 13/17] Apply suggestions from code review Co-authored-by: Peter Savchenko --- src/imageResolver.js | 2 +- src/index.js | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/imageResolver.js b/src/imageResolver.js index 61d146d9..b80e261b 100644 --- a/src/imageResolver.js +++ b/src/imageResolver.js @@ -7,7 +7,7 @@ export default class ImageResolver { /** * @param {object} params - image resolver module params * @param {ImageConfig} params.config - image tool config - * @param {Function} params.onResolve - callback which is called, when file is resolved + * @param {(fileUploadingResponse: any) => string} params.onResolve - callback which is called, when file is resolved * @param {Function} params.onError - callback for resolving errors */ constructor({ config, onResolve, onError }) { diff --git a/src/index.js b/src/index.js index 852933f4..b2b20307 100644 --- a/src/index.js +++ b/src/index.js @@ -397,7 +397,9 @@ export default class ImageTool { this._data.file = file || {}; if (file && file.url) { - this.imageResolver.resolveUrlByFileData(file.url); + const url = await this.imageResolver.resolveUrlByFileData(file); + + this.ui.fillImage(url) } } From 0be89a46850ec6edf1a2fe50fd1752d007387f2d Mon Sep 17 00:00:00 2001 From: slaveeks Date: Fri, 5 Jul 2024 03:23:17 +0300 Subject: [PATCH 14/17] review changes --- src/imageResolver.js | 25 +++++++++++++------------ src/index.js | 41 +++++++++++++++-------------------------- 2 files changed, 28 insertions(+), 38 deletions(-) diff --git a/src/imageResolver.js b/src/imageResolver.js index b80e261b..a0754852 100644 --- a/src/imageResolver.js +++ b/src/imageResolver.js @@ -7,21 +7,19 @@ export default class ImageResolver { /** * @param {object} params - image resolver module params * @param {ImageConfig} params.config - image tool config - * @param {(fileUploadingResponse: any) => string} params.onResolve - callback which is called, when file is resolved * @param {Function} params.onError - callback for resolving errors */ constructor({ config, onResolve, onError }) { this.config = config; - this.onResolve = onResolve; this.onError = onError; } /** * Try to resolve image url by file data and fill it using stored data * - * @param {string} fileData - file data, from which file url need to be resolved + * @param {any} fileData - file data, from which file url need to be resolved */ - resolveUrlByFileData(fileData) { + async resolveUrlByFileData(fileData) { /** * Check that custom url resolver passed */ @@ -32,20 +30,23 @@ export default class ImageResolver { console.warn('Custom downloader method download should return a Promise'); } - resolveFileData.then((response) => { + try { /** - * Call callback for successful resolving with url + * Return resolver url */ - this.onResolve(response); - }).catch((error) => { + return await resolveFileData; + } catch (error) { this.onError(error); - }); + } } else { /** - * If there is no custom resolve method, fileData is correct url - * We only need to call callback + * If there is no custom resolve method, fileData must have correct url property, which have no need in resolving */ - this.onResolve(fileData); + if (!fileData.url) { + this.onError('Incorrect data: file data should contain url'); + } + + return fileData.url; } } } diff --git a/src/index.js b/src/index.js index b2b20307..944b24b5 100644 --- a/src/index.js +++ b/src/index.js @@ -66,7 +66,7 @@ import { IconAddBorder, IconStretch, IconAddBackground, IconPicture } from '@cod * @property {function(File): Promise.} [uploader.uploadByFile] - method that upload image by File * @property {function(string): Promise.} [uploader.uploadByUrl] - method that upload image by URL * @property {object} [imageResolver] - optional custom image data resolver - * @property {function(string): Promise.} [imageResolver.resolveUrlByFileData] - method that resolves image by file data + * @property {function(any): Promise.} [imageResolver.resolveUrlByFileData] - method that resolves image url by file data */ /** @@ -74,9 +74,10 @@ import { IconAddBorder, IconStretch, IconAddBackground, IconPicture } from '@cod * @description This format expected from backend on file uploading * @property {number} success - 1 for successful uploading, 0 for failure * @property {object} file - Object with file data. - * 'url' is required, + * 'url' exists image url * also can contain any additional data that will be saved and passed back - * @property {string} file.url - [Required] image source URL or file data key to resolve it via custom image resolver + * this data can be used for custom downloading + * @property {string} file.url - image source URL */ export default class ImageTool { /** @@ -159,6 +160,14 @@ export default class ImageTool { imageResolver: config.imageResolver || undefined, }; + /** + * Module for image resolving + */ + this.imageResolver = new ImageResolver({ + config: this.config, + onError: this.resolvingFileError, + }); + /** * Module for file uploading */ @@ -184,15 +193,6 @@ export default class ImageTool { readOnly, }); - /** - * Module for image resolving - */ - this.imageResolver = new ImageResolver({ - config: this.config, - onResolve: (url) => this.onResolve(url), - onError: this.resolvingFileError, - }); - /** * Set saved state */ @@ -219,7 +219,7 @@ export default class ImageTool { * @public */ validate(savedData) { - return savedData.file && savedData.file.url; + return savedData.file; } /** @@ -396,10 +396,8 @@ export default class ImageTool { set image(file) { this._data.file = file || {}; - if (file && file.url) { - const url = await this.imageResolver.resolveUrlByFileData(file); - - this.ui.fillImage(url) + if (file) { + this.imageResolver.resolveUrlByFileData(file).then(url => this.ui.fillImage(url)); } } @@ -452,15 +450,6 @@ export default class ImageTool { }); } - /** - * Image resolving callback, fills file data into image - * - * @param {*} url - file url after resolving - */ - onResolve(url) { - this.ui.fillImage(url); - } - /** * Callback fired when Block Tune is activated * From 2c9a2f74b6fbe2957b43d6d22c1fc7a9f7d2838a Mon Sep 17 00:00:00 2001 From: slaveeks Date: Fri, 5 Jul 2024 03:25:00 +0300 Subject: [PATCH 15/17] update readme --- README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3017067d..ee11d89c 100644 --- a/README.md +++ b/README.md @@ -179,7 +179,8 @@ The response of your uploader **should** cover the following format: **success** - uploading status. 1 for successful, 0 for failed -**file** - uploaded file data. **Must** contain an `url` field with full public path to the uploaded image or data key for using it in custom image resolver. +**file** - uploaded file data. **Must** contain an `url` field with full public path to the uploaded image or data key for using it in custom image resolver, or you +can use additional fields for custom resolving. Also, can contain any additional fields you want to store. For example, width, height, id etc. All additional fields will be saved at the `file` object of output data. @@ -294,6 +295,8 @@ Method must return a Promise that resolves with url, which we can pass to the im | -------------- | --------- | ------------- | ------------| | resolveUrlByFileData | `fileData`| `Promise.` | Resolve image url by file data | +`fileData` - any data, which is needed for resolving url + Example: ```js @@ -313,7 +316,7 @@ var editor = EditorJS({ imageResolver: { /** * Resolve image url by file data. - * @param {string} fileData - data required for image url resolving + * @param {any} fileData - data required for image url resolving * @return {Promise.} - valid url */ resolveUrlByFileData(fileData) { From 1e0b52f93d5453bdfb76c42e2324e0bba98d0ed1 Mon Sep 17 00:00:00 2001 From: slaveeks Date: Fri, 5 Jul 2024 03:26:38 +0300 Subject: [PATCH 16/17] updated docs --- src/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/index.js b/src/index.js index 944b24b5..24e56050 100644 --- a/src/index.js +++ b/src/index.js @@ -74,7 +74,8 @@ import { IconAddBorder, IconStretch, IconAddBackground, IconPicture } from '@cod * @description This format expected from backend on file uploading * @property {number} success - 1 for successful uploading, 0 for failure * @property {object} file - Object with file data. - * 'url' exists image url + * 'url' contains image url + * or you can store file data in additional fields for custom resolver * also can contain any additional data that will be saved and passed back * this data can be used for custom downloading * @property {string} file.url - image source URL From f603c1aa4a24b9dfcda6e2a6509feb206d3978c0 Mon Sep 17 00:00:00 2001 From: slaveeks Date: Fri, 5 Jul 2024 03:32:14 +0300 Subject: [PATCH 17/17] update fileData desc --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ee11d89c..19665815 100644 --- a/README.md +++ b/README.md @@ -295,7 +295,7 @@ Method must return a Promise that resolves with url, which we can pass to the im | -------------- | --------- | ------------- | ------------| | resolveUrlByFileData | `fileData`| `Promise.` | Resolve image url by file data | -`fileData` - any data, which is needed for resolving url +`fileData` - any data, which your server returns after uploading image. Example: