From e5996085b52f1cdce510e1b75edbdfd3fefb78c7 Mon Sep 17 00:00:00 2001 From: zhaojianhuang Date: Tue, 3 Sep 2024 15:29:58 +0800 Subject: [PATCH] Make it work with CKEditor5 version 43.0.0 --- fileupload.js | 25 +- package-lock.json | 970 ++++++++++++++++++++++++++++++--- package.json | 12 +- src/fileuploadcommand.js | 67 ++- src/fileuploadediting.js | 455 ++++++++-------- src/fileuploadprogress.js | 152 +++--- src/fileuploadui.js | 79 ++- src/mimeTypes.js | 14 +- src/simplefileuploadadapter.js | 220 ++++---- src/utils.js | 107 ++-- theme/progressbarview.js | 123 ++--- 11 files changed, 1504 insertions(+), 720 deletions(-) diff --git a/fileupload.js b/fileupload.js index e46d37d..d37518f 100644 --- a/fileupload.js +++ b/fileupload.js @@ -1,17 +1,16 @@ -import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; -import FileUploadEditing from "./src/fileuploadediting"; -import FileUploadUI from "./src/fileuploadui"; +import { Plugin } from 'ckeditor5' +import FileUploadEditing from './src/fileuploadediting' +import FileUploadUI from './src/fileuploadui' export default class FileUpload extends Plugin { + static get requires () { + return [FileUploadEditing, FileUploadUI] + } - static get requires() { - return [ FileUploadEditing, FileUploadUI ]; - } - - /** - * @inheritDoc - */ - static get pluginName() { - return 'fileUpload'; - } + /** + * @inheritDoc + */ + static get pluginName () { + return 'fileUpload' + } } diff --git a/package-lock.json b/package-lock.json index 0d5a76c..1351dec 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,82 +1,900 @@ { "name": "@emagtechlabs/ckeditor5-file-upload", - "version": "1.0.0", - "lockfileVersion": 1, + "version": "1.1.0", + "lockfileVersion": 3, "requires": true, - "dependencies": { - "@ckeditor/ckeditor5-clipboard": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-clipboard/-/ckeditor5-clipboard-17.0.0.tgz", - "integrity": "sha512-ltUmytwI94dqcReHxsJmB1U9pxLKCxOdLPqltffC409INXa5d9O3mGrB0eBCh3ACKR783IzRRkbtElFASGznrg==", - "requires": { - "@ckeditor/ckeditor5-core": "17.0.0", - "@ckeditor/ckeditor5-engine": "17.0.0", - "@ckeditor/ckeditor5-utils": "17.0.0" - } - }, - "@ckeditor/ckeditor5-core": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-core/-/ckeditor5-core-17.0.0.tgz", - "integrity": "sha512-exgZOMd3YMJky++ytiAQ1fMtqtKyvEc1xikNBVwAeP38ekZcZSLLi2gP8X8ge2yZTFPmO0TiB8fiU//pLQpeJg==", - "requires": { - "@ckeditor/ckeditor5-engine": "17.0.0", - "@ckeditor/ckeditor5-utils": "17.0.0", - "lodash-es": "4.17.15" - } - }, - "@ckeditor/ckeditor5-engine": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-engine/-/ckeditor5-engine-17.0.0.tgz", - "integrity": "sha512-3+m7Hc1QCn97JHLjJWRYg2GcI9hTcU3XGSZnsLeolyPgwBbEnkvfUGId2K5O91Bg3SKkSP4vgvydZE9JM2Q7Mg==", - "requires": { - "@ckeditor/ckeditor5-utils": "17.0.0", - "lodash-es": "4.17.15" - } - }, - "@ckeditor/ckeditor5-ui": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-ui/-/ckeditor5-ui-17.0.0.tgz", - "integrity": "sha512-ceM0IlBNscyDOeeGyU4n5Xp9YHdc4hdv2dmDgV/hECSaYzePVr5h1HDoF2Juv4SP5azACSLJr6JZs3uXP8iLCg==", - "requires": { - "@ckeditor/ckeditor5-core": "17.0.0", - "@ckeditor/ckeditor5-utils": "17.0.0", - "lodash-es": "4.17.15" - } - }, - "@ckeditor/ckeditor5-upload": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-upload/-/ckeditor5-upload-17.0.0.tgz", - "integrity": "sha512-Kl1srRnm9XvaJ3ivWf4sNMvkMC9ArbRsCWZ5h2m2LFu2O3v6ZEx8F6viUjTmBLD2dkK9D0cN6+DTUQht2KbR4g==", - "requires": { - "@ckeditor/ckeditor5-core": "17.0.0", - "@ckeditor/ckeditor5-ui": "17.0.0", - "@ckeditor/ckeditor5-utils": "17.0.0" - } - }, - "@ckeditor/ckeditor5-utils": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-utils/-/ckeditor5-utils-17.0.0.tgz", - "integrity": "sha512-La9Au5pvafUi4uN3Zxjb6HLdacZLMkC+KerWQEohPhZYHRmy8OusaGB+X74gYRKb6O+vGfxpbgSA93e3VoE3fQ==", - "requires": { - "lodash-es": "4.17.15" - } - }, - "@ckeditor/ckeditor5-widget": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-widget/-/ckeditor5-widget-17.0.0.tgz", - "integrity": "sha512-NOPkim9TNq2TPYf8Sa2trEuRVg58n/a+0iGisomXM8HGy8aOxaBQShK3oKdDliwjrlm/MU9mV8rNunwLGtUB/g==", - "requires": { - "@ckeditor/ckeditor5-core": "17.0.0", - "@ckeditor/ckeditor5-engine": "17.0.0", - "@ckeditor/ckeditor5-ui": "17.0.0", - "@ckeditor/ckeditor5-utils": "17.0.0", - "lodash-es": "4.17.15" - } - }, - "lodash-es": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.15.tgz", - "integrity": "sha512-rlrc3yU3+JNOpZ9zj5pQtxnx2THmvRykwL4Xlxoa8I9lHBlVbbyPhgyPMioxVZ4NqyxaVVtaJnzsyOidQIhyyQ==" + "packages": { + "": { + "name": "@emagtechlabs/ckeditor5-file-upload", + "version": "1.1.0", + "license": "GPL-3.0", + "dependencies": { + "ckeditor5": "43.0.0" + }, + "devDependencies": {} + }, + "node_modules/@ckeditor/ckeditor5-adapter-ckfinder": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-adapter-ckfinder/-/ckeditor5-adapter-ckfinder-43.0.0.tgz", + "integrity": "sha512-pwhr46NNLOEyF2Qob/x4+Mwt6Bqi9i/j/4JaI5fSdhml8CZQHw5levJB3NRrOUX1zOw4cjZXQDU+j4TAN+l3xw==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.0.0", + "@ckeditor/ckeditor5-upload": "43.0.0", + "ckeditor5": "43.0.0" + } + }, + "node_modules/@ckeditor/ckeditor5-alignment": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-alignment/-/ckeditor5-alignment-43.0.0.tgz", + "integrity": "sha512-GxLw0l/l+CnqDavcHciegjmKsR4nZCMlrIdlvxPrQXAZOU2/EEEQE95UPVwbJCvIX4BB3LgF31FBbiDMWT3jbg==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.0.0", + "@ckeditor/ckeditor5-ui": "43.0.0", + "@ckeditor/ckeditor5-utils": "43.0.0", + "ckeditor5": "43.0.0" + } + }, + "node_modules/@ckeditor/ckeditor5-autoformat": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-autoformat/-/ckeditor5-autoformat-43.0.0.tgz", + "integrity": "sha512-wCPNWhgnUQctU7c8JdDVbf9m8Ai1dugvnFnR7xTLY3SLh7LvUCF0q0QQ4CysHdNVGSoGVJBmdjU7Qg3qNwD9Ng==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.0.0", + "@ckeditor/ckeditor5-engine": "43.0.0", + "@ckeditor/ckeditor5-typing": "43.0.0", + "@ckeditor/ckeditor5-utils": "43.0.0", + "ckeditor5": "43.0.0" + } + }, + "node_modules/@ckeditor/ckeditor5-autosave": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-autosave/-/ckeditor5-autosave-43.0.0.tgz", + "integrity": "sha512-tqOH9ihcSpErDD9tYCDuIBnWNkAlti3b9gknpNj1cc3JSFbIcyX9KAsSFP49qMgaA1An95UyNTo7YunZgOp5sw==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.0.0", + "@ckeditor/ckeditor5-utils": "43.0.0", + "ckeditor5": "43.0.0", + "lodash-es": "4.17.21" + } + }, + "node_modules/@ckeditor/ckeditor5-basic-styles": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-basic-styles/-/ckeditor5-basic-styles-43.0.0.tgz", + "integrity": "sha512-L3kMP+uDvmkoAtkZO/cvJz4zvbnES1OQYmSipkq2YKZfyAtajj2FWHJ9Xy58D6TRN7RlgoN4WeM4jA0VghNcXQ==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.0.0", + "@ckeditor/ckeditor5-typing": "43.0.0", + "@ckeditor/ckeditor5-ui": "43.0.0", + "ckeditor5": "43.0.0" + } + }, + "node_modules/@ckeditor/ckeditor5-block-quote": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-block-quote/-/ckeditor5-block-quote-43.0.0.tgz", + "integrity": "sha512-FispEZZOZTpau6L3ft+hbpOqi1nDSrPRdEl4oObcHXdisHEYrTdfPXUtGDlcCcaU5mekNzVt4BNRikx2wNP9oQ==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.0.0", + "@ckeditor/ckeditor5-enter": "43.0.0", + "@ckeditor/ckeditor5-typing": "43.0.0", + "@ckeditor/ckeditor5-ui": "43.0.0", + "@ckeditor/ckeditor5-utils": "43.0.0", + "ckeditor5": "43.0.0" + } + }, + "node_modules/@ckeditor/ckeditor5-ckbox": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-ckbox/-/ckeditor5-ckbox-43.0.0.tgz", + "integrity": "sha512-dvTgYbn1+EObVoW93rOrLJHlIwAy0/4trLibTTIuwjhKU3IeVW1vH4/UIgXV8Q45CCi5vypLBxzU5V9/bzzcDg==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.0.0", + "@ckeditor/ckeditor5-engine": "43.0.0", + "@ckeditor/ckeditor5-ui": "43.0.0", + "@ckeditor/ckeditor5-upload": "43.0.0", + "@ckeditor/ckeditor5-utils": "43.0.0", + "blurhash": "2.0.5", + "ckeditor5": "43.0.0", + "lodash-es": "4.17.21" + } + }, + "node_modules/@ckeditor/ckeditor5-ckfinder": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-ckfinder/-/ckeditor5-ckfinder-43.0.0.tgz", + "integrity": "sha512-YZv2AO9my3HBv/J6pOSjkMgVxl6fkUuT7Ify6Wp6ixQFCy1nPPR7s3W3WQX4+d0BPEXcz602A1PylCESYWwFfA==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.0.0", + "@ckeditor/ckeditor5-ui": "43.0.0", + "@ckeditor/ckeditor5-utils": "43.0.0", + "ckeditor5": "43.0.0" + } + }, + "node_modules/@ckeditor/ckeditor5-clipboard": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-clipboard/-/ckeditor5-clipboard-43.0.0.tgz", + "integrity": "sha512-z0A800Acmd1bfY2bi69OB2xBVNZFeqRNRfWyIX+kdP3+kA+tkb6ypMhAc0XMC2cstBcTKUSPEk7HufgD0k8gTw==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.0.0", + "@ckeditor/ckeditor5-engine": "43.0.0", + "@ckeditor/ckeditor5-ui": "43.0.0", + "@ckeditor/ckeditor5-utils": "43.0.0", + "@ckeditor/ckeditor5-widget": "43.0.0", + "lodash-es": "4.17.21" + } + }, + "node_modules/@ckeditor/ckeditor5-cloud-services": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-cloud-services/-/ckeditor5-cloud-services-43.0.0.tgz", + "integrity": "sha512-cJ0nwSZNRyX69Ky0M8xIjLzxTJz7E1JJ52TBkzGogV1D2XogiC2eXUMHZDi6zoiBP5KyB84d4trBIxUs0ElaEQ==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.0.0", + "@ckeditor/ckeditor5-utils": "43.0.0", + "ckeditor5": "43.0.0" + } + }, + "node_modules/@ckeditor/ckeditor5-code-block": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-code-block/-/ckeditor5-code-block-43.0.0.tgz", + "integrity": "sha512-gQJaMQdEvHtqG7KsCpWawSnVJeH+aLzgETYEuiWxWkJPXqKpE/gzq/XSRxqoyIoda6YWz2gfxCDZckVAHXa9Pg==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-clipboard": "43.0.0", + "@ckeditor/ckeditor5-core": "43.0.0", + "@ckeditor/ckeditor5-engine": "43.0.0", + "@ckeditor/ckeditor5-enter": "43.0.0", + "@ckeditor/ckeditor5-ui": "43.0.0", + "@ckeditor/ckeditor5-utils": "43.0.0", + "ckeditor5": "43.0.0" + } + }, + "node_modules/@ckeditor/ckeditor5-core": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-core/-/ckeditor5-core-43.0.0.tgz", + "integrity": "sha512-UbOnWwB8RIjipDTuFCPVqJtSnIhuCf5DCUa+05JqMdKzlqj3pJC+iBsvGbxtk6DdzSr8q1CUHwhJxlXfs3BSLg==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-engine": "43.0.0", + "@ckeditor/ckeditor5-utils": "43.0.0", + "@ckeditor/ckeditor5-watchdog": "43.0.0", + "lodash-es": "4.17.21" + } + }, + "node_modules/@ckeditor/ckeditor5-easy-image": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-easy-image/-/ckeditor5-easy-image-43.0.0.tgz", + "integrity": "sha512-iT+g9lrBvKreHjRP7tc8P/LrzHEtipBQ488eJdtmaNvMUIQvFnjhZOIcYd7Lr+a4M7+qJl8tSwJOQvM/KiXDeQ==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.0.0", + "@ckeditor/ckeditor5-upload": "43.0.0", + "@ckeditor/ckeditor5-utils": "43.0.0", + "ckeditor5": "43.0.0" + } + }, + "node_modules/@ckeditor/ckeditor5-editor-balloon": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-editor-balloon/-/ckeditor5-editor-balloon-43.0.0.tgz", + "integrity": "sha512-D8tJ/ZKezsc0m75/kzSS783VB8tRiWabmzJUOtlFGss8RwD3QZqHCabP/boZW95vEm/sk5UZt2COL43jlNN4TA==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.0.0", + "@ckeditor/ckeditor5-engine": "43.0.0", + "@ckeditor/ckeditor5-ui": "43.0.0", + "@ckeditor/ckeditor5-utils": "43.0.0", + "ckeditor5": "43.0.0", + "lodash-es": "4.17.21" + } + }, + "node_modules/@ckeditor/ckeditor5-editor-classic": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-editor-classic/-/ckeditor5-editor-classic-43.0.0.tgz", + "integrity": "sha512-VUewScFqwQxm5tu2YPMNzX6pVb3HaXGyEL1PbKo8gBtmo8eimsfNS6WbW2gn4RhQKyu2BzFKXeaNi9Dj0aTZLA==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.0.0", + "@ckeditor/ckeditor5-engine": "43.0.0", + "@ckeditor/ckeditor5-ui": "43.0.0", + "@ckeditor/ckeditor5-utils": "43.0.0", + "ckeditor5": "43.0.0", + "lodash-es": "4.17.21" + } + }, + "node_modules/@ckeditor/ckeditor5-editor-decoupled": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-editor-decoupled/-/ckeditor5-editor-decoupled-43.0.0.tgz", + "integrity": "sha512-BVrMPXCrHMDaxxEuLiUhma4Kx2huSnp7u5EoWaDxAVOXjpb3ZRlboGV5smpt87BmjP5Zt58SrUsDoHnLPfN6eA==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.0.0", + "@ckeditor/ckeditor5-engine": "43.0.0", + "@ckeditor/ckeditor5-ui": "43.0.0", + "@ckeditor/ckeditor5-utils": "43.0.0", + "ckeditor5": "43.0.0", + "lodash-es": "4.17.21" + } + }, + "node_modules/@ckeditor/ckeditor5-editor-inline": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-editor-inline/-/ckeditor5-editor-inline-43.0.0.tgz", + "integrity": "sha512-II77SDB23t02Kbapf74W0gR8QpNCeVm7g7IT6NvGF1OW3RlTwDJQsfdyOgvHQoU4FkdRoOIEOoeFbJxgToJORw==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.0.0", + "@ckeditor/ckeditor5-engine": "43.0.0", + "@ckeditor/ckeditor5-ui": "43.0.0", + "@ckeditor/ckeditor5-utils": "43.0.0", + "ckeditor5": "43.0.0", + "lodash-es": "4.17.21" + } + }, + "node_modules/@ckeditor/ckeditor5-editor-multi-root": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-editor-multi-root/-/ckeditor5-editor-multi-root-43.0.0.tgz", + "integrity": "sha512-9J48bxr8H0iD98QYEdBrfyIGXcX1v0jQN3w9kuT2Una/GgnBRM+EiN2N9vM+xu6arBSA30aZCqU5u0mv2DPAGg==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.0.0", + "@ckeditor/ckeditor5-engine": "43.0.0", + "@ckeditor/ckeditor5-ui": "43.0.0", + "@ckeditor/ckeditor5-utils": "43.0.0", + "ckeditor5": "43.0.0", + "lodash-es": "4.17.21" + } + }, + "node_modules/@ckeditor/ckeditor5-engine": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-engine/-/ckeditor5-engine-43.0.0.tgz", + "integrity": "sha512-0CcNbxxNjrmxytBPjh49ZELwyoE8lFSCFx+44CGRicY+GYeg45+sIUiyY0rWiBaxukfVajl1sYlctDVGezP9Bg==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-utils": "43.0.0", + "lodash-es": "4.17.21" + } + }, + "node_modules/@ckeditor/ckeditor5-enter": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-enter/-/ckeditor5-enter-43.0.0.tgz", + "integrity": "sha512-E6ay1zfYOThTQoBISXL3Ez13dKsJXWz6AZV1z5tAq77N+pD0hBjX4uwwxhQ95Yto56Ifhy3l4zwNJTjePAD1TA==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.0.0", + "@ckeditor/ckeditor5-engine": "43.0.0", + "@ckeditor/ckeditor5-utils": "43.0.0" + } + }, + "node_modules/@ckeditor/ckeditor5-essentials": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-essentials/-/ckeditor5-essentials-43.0.0.tgz", + "integrity": "sha512-UGXxAhmod1QSM6t5ZEPklqBpoAHFqS2ZWXhGZdQaEVzt13MR+tZanug/+3XTs46yhM5401jKT7BGhfkUZwQnVA==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-clipboard": "43.0.0", + "@ckeditor/ckeditor5-core": "43.0.0", + "@ckeditor/ckeditor5-enter": "43.0.0", + "@ckeditor/ckeditor5-select-all": "43.0.0", + "@ckeditor/ckeditor5-typing": "43.0.0", + "@ckeditor/ckeditor5-ui": "43.0.0", + "@ckeditor/ckeditor5-undo": "43.0.0", + "ckeditor5": "43.0.0" + } + }, + "node_modules/@ckeditor/ckeditor5-find-and-replace": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-find-and-replace/-/ckeditor5-find-and-replace-43.0.0.tgz", + "integrity": "sha512-/kD4gypGzuPqtun9IWA0ywNKJKJ9sllurqjRHOXagU5L19pakBr+KpuD7vKNN+NYN3gzyI9REMP6CEXSBb+c3A==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.0.0", + "@ckeditor/ckeditor5-ui": "43.0.0", + "@ckeditor/ckeditor5-utils": "43.0.0", + "ckeditor5": "43.0.0", + "lodash-es": "4.17.21" + } + }, + "node_modules/@ckeditor/ckeditor5-font": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-font/-/ckeditor5-font-43.0.0.tgz", + "integrity": "sha512-/B5Txk17+av2AsD3naq+yqOw6vdj2n8jA4+Zm0J8TerCRbwYELRyA9vBCwsGvVKkl56RfjzSNInFD/gKAn5Uzw==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.0.0", + "@ckeditor/ckeditor5-engine": "43.0.0", + "@ckeditor/ckeditor5-ui": "43.0.0", + "@ckeditor/ckeditor5-utils": "43.0.0", + "ckeditor5": "43.0.0" + } + }, + "node_modules/@ckeditor/ckeditor5-heading": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-heading/-/ckeditor5-heading-43.0.0.tgz", + "integrity": "sha512-15h4KH4LmH8h0udTI9Apvw4YuEopjx+srt/++Uxv/AasLfNSOMfZ8lIjhqieuqWjeCGotnV8sG3TPJDi55JOZw==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.0.0", + "@ckeditor/ckeditor5-engine": "43.0.0", + "@ckeditor/ckeditor5-paragraph": "43.0.0", + "@ckeditor/ckeditor5-ui": "43.0.0", + "@ckeditor/ckeditor5-utils": "43.0.0", + "ckeditor5": "43.0.0" + } + }, + "node_modules/@ckeditor/ckeditor5-highlight": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-highlight/-/ckeditor5-highlight-43.0.0.tgz", + "integrity": "sha512-lzlIXS0/lB2eUCygzUJbNOU6YDXiIyAnZoFqx/qw4heU9DL33Omh+cSfBpSkm462OWbExUWoOkqHFtE3R8Qs8g==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.0.0", + "@ckeditor/ckeditor5-ui": "43.0.0", + "ckeditor5": "43.0.0" + } + }, + "node_modules/@ckeditor/ckeditor5-horizontal-line": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-horizontal-line/-/ckeditor5-horizontal-line-43.0.0.tgz", + "integrity": "sha512-yYsfSjEPW0enbXKntf8OA9G4xQGEKp6m+Dph8asuCIakpET21oUkeVYWDgRlf5in0Qabk5Ymv/UkSWdUaPiVew==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.0.0", + "@ckeditor/ckeditor5-ui": "43.0.0", + "@ckeditor/ckeditor5-widget": "43.0.0", + "ckeditor5": "43.0.0" + } + }, + "node_modules/@ckeditor/ckeditor5-html-embed": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-html-embed/-/ckeditor5-html-embed-43.0.0.tgz", + "integrity": "sha512-KWjZkw9leOzO81xYLqHqhJK7DhrW1qxrfQ2blD3XRI4aXcFQXniLCDXugkLOTzjkbWUhXUbyWt6tM3gPqgX1jQ==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.0.0", + "@ckeditor/ckeditor5-ui": "43.0.0", + "@ckeditor/ckeditor5-utils": "43.0.0", + "@ckeditor/ckeditor5-widget": "43.0.0", + "ckeditor5": "43.0.0" + } + }, + "node_modules/@ckeditor/ckeditor5-html-support": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-html-support/-/ckeditor5-html-support-43.0.0.tgz", + "integrity": "sha512-Ji5zaG17wgJRSpXe3FNBD1rEmqLb6Jh1+RJX2/+rIV3ph0ZhP5FKESz8PPw48bPjns5sjd5RCdalv9UIKpz5eQ==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.0.0", + "@ckeditor/ckeditor5-engine": "43.0.0", + "@ckeditor/ckeditor5-enter": "43.0.0", + "@ckeditor/ckeditor5-utils": "43.0.0", + "@ckeditor/ckeditor5-widget": "43.0.0", + "ckeditor5": "43.0.0", + "lodash-es": "4.17.21" + } + }, + "node_modules/@ckeditor/ckeditor5-image": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-image/-/ckeditor5-image-43.0.0.tgz", + "integrity": "sha512-UeO1yaDigz1md+xBt9wP1pp9ncotVL8TFkx3nxXvOqVG8FxWS+HdHZ5JwdG+yCrYiIJOPDJt2YiZ6HSkktF/6A==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-clipboard": "43.0.0", + "@ckeditor/ckeditor5-core": "43.0.0", + "@ckeditor/ckeditor5-engine": "43.0.0", + "@ckeditor/ckeditor5-typing": "43.0.0", + "@ckeditor/ckeditor5-ui": "43.0.0", + "@ckeditor/ckeditor5-undo": "43.0.0", + "@ckeditor/ckeditor5-upload": "43.0.0", + "@ckeditor/ckeditor5-utils": "43.0.0", + "@ckeditor/ckeditor5-widget": "43.0.0", + "ckeditor5": "43.0.0", + "lodash-es": "4.17.21" + } + }, + "node_modules/@ckeditor/ckeditor5-indent": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-indent/-/ckeditor5-indent-43.0.0.tgz", + "integrity": "sha512-GnG9LsVWXE8Otyxt3ZN4Ild4yYNHy06sQwcRSuByPePKzFb34l/0AfH8IqLJv8SQT/z35Tb7K64zKOriZFX53g==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.0.0", + "@ckeditor/ckeditor5-engine": "43.0.0", + "@ckeditor/ckeditor5-ui": "43.0.0", + "@ckeditor/ckeditor5-utils": "43.0.0", + "ckeditor5": "43.0.0" + } + }, + "node_modules/@ckeditor/ckeditor5-language": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-language/-/ckeditor5-language-43.0.0.tgz", + "integrity": "sha512-NcVmgB9YXyrHqbj5QUpKJZztj/eEN5k1RkLOhQNA4IDw6UvNp5uSkum5AxtpwcjDaE10UHQIYDBQIwGSRAUL5g==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.0.0", + "@ckeditor/ckeditor5-ui": "43.0.0", + "@ckeditor/ckeditor5-utils": "43.0.0", + "ckeditor5": "43.0.0" + } + }, + "node_modules/@ckeditor/ckeditor5-link": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-link/-/ckeditor5-link-43.0.0.tgz", + "integrity": "sha512-BAkjg+bfiYCPOvK7WLLlqL2Hy0tcNVgspWLRNr3RJWhCSZMEbtgF8DR97mRA/vWkzTR/htNGKXlbp7OOmBk2Pw==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-clipboard": "43.0.0", + "@ckeditor/ckeditor5-core": "43.0.0", + "@ckeditor/ckeditor5-engine": "43.0.0", + "@ckeditor/ckeditor5-typing": "43.0.0", + "@ckeditor/ckeditor5-ui": "43.0.0", + "@ckeditor/ckeditor5-utils": "43.0.0", + "@ckeditor/ckeditor5-widget": "43.0.0", + "ckeditor5": "43.0.0", + "lodash-es": "4.17.21" + } + }, + "node_modules/@ckeditor/ckeditor5-list": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-list/-/ckeditor5-list-43.0.0.tgz", + "integrity": "sha512-pBEI7UNNmO8egc97f1oNHZZvDzZn0TAVzxpYifQcUsVwnsobFk9pojQIpEdJjKoPWcIMJO6SfHe+DYvrB2kqPg==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-clipboard": "43.0.0", + "@ckeditor/ckeditor5-core": "43.0.0", + "@ckeditor/ckeditor5-engine": "43.0.0", + "@ckeditor/ckeditor5-enter": "43.0.0", + "@ckeditor/ckeditor5-typing": "43.0.0", + "@ckeditor/ckeditor5-ui": "43.0.0", + "@ckeditor/ckeditor5-utils": "43.0.0", + "ckeditor5": "43.0.0" + } + }, + "node_modules/@ckeditor/ckeditor5-markdown-gfm": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-markdown-gfm/-/ckeditor5-markdown-gfm-43.0.0.tgz", + "integrity": "sha512-4TjnTugDEMoxLej/dmiUxqKEwGqmPACuwU1SnSR15E5X7MR+0SHAdXg/sQfJcbmwrjle/6tSp4NVK7XKPi7Sug==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-clipboard": "43.0.0", + "@ckeditor/ckeditor5-core": "43.0.0", + "@ckeditor/ckeditor5-engine": "43.0.0", + "ckeditor5": "43.0.0", + "marked": "4.0.12", + "turndown": "7.2.0", + "turndown-plugin-gfm": "1.0.2" + } + }, + "node_modules/@ckeditor/ckeditor5-media-embed": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-media-embed/-/ckeditor5-media-embed-43.0.0.tgz", + "integrity": "sha512-l+BlHpS88yZ0J25KqfXADgb3AYXuAt5yTzYwN8XCMQ0/HbjKmgb/Hkppo5Bcd/hzSBG+LUh1dygP1F2lkc5N/A==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-clipboard": "43.0.0", + "@ckeditor/ckeditor5-core": "43.0.0", + "@ckeditor/ckeditor5-engine": "43.0.0", + "@ckeditor/ckeditor5-typing": "43.0.0", + "@ckeditor/ckeditor5-ui": "43.0.0", + "@ckeditor/ckeditor5-undo": "43.0.0", + "@ckeditor/ckeditor5-utils": "43.0.0", + "@ckeditor/ckeditor5-widget": "43.0.0", + "ckeditor5": "43.0.0" + } + }, + "node_modules/@ckeditor/ckeditor5-mention": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-mention/-/ckeditor5-mention-43.0.0.tgz", + "integrity": "sha512-B5DNmfj1JbLLx5+6vnneoK+C0BLPjiM+5x1qdpLVAMIWkbr6qJCthZfe5gnGD7WoGpRILIE//cskm42eP26wcQ==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.0.0", + "@ckeditor/ckeditor5-typing": "43.0.0", + "@ckeditor/ckeditor5-ui": "43.0.0", + "@ckeditor/ckeditor5-utils": "43.0.0", + "ckeditor5": "43.0.0", + "lodash-es": "4.17.21" + } + }, + "node_modules/@ckeditor/ckeditor5-minimap": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-minimap/-/ckeditor5-minimap-43.0.0.tgz", + "integrity": "sha512-2C59bqoVBOTnbccsgpCyie+sGKTl/J5nIt5Wu1oyINYPT+j+VjUtiSh5yZKPRXTF+Cyba6NyFU/56BJLBnPurQ==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.0.0", + "@ckeditor/ckeditor5-engine": "43.0.0", + "@ckeditor/ckeditor5-ui": "43.0.0", + "@ckeditor/ckeditor5-utils": "43.0.0", + "ckeditor5": "43.0.0" + } + }, + "node_modules/@ckeditor/ckeditor5-page-break": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-page-break/-/ckeditor5-page-break-43.0.0.tgz", + "integrity": "sha512-oSHGAPBHrs2pRwAp36ldVn3fy2xySzDmMXNArnpiRbwIScQOZHuf/iqAIPeeZkO27Gfo9bfh/oWbGcUfPBzF6A==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.0.0", + "@ckeditor/ckeditor5-ui": "43.0.0", + "@ckeditor/ckeditor5-widget": "43.0.0", + "ckeditor5": "43.0.0" + } + }, + "node_modules/@ckeditor/ckeditor5-paragraph": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-paragraph/-/ckeditor5-paragraph-43.0.0.tgz", + "integrity": "sha512-xt8x4E6Vh0dmFxbCtv89KdKoSM+xB6B8s7q+Mvf/a/gtnV/x1OJgMBBTUj81FRYtMVB5LyQsE8Wo8jNLYzHmTQ==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.0.0", + "@ckeditor/ckeditor5-ui": "43.0.0", + "@ckeditor/ckeditor5-utils": "43.0.0" + } + }, + "node_modules/@ckeditor/ckeditor5-paste-from-office": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-paste-from-office/-/ckeditor5-paste-from-office-43.0.0.tgz", + "integrity": "sha512-VMONY8JUdSfWQ0GNjtpjqWvA1BGunIqhDp4dIvbSyiAoK/3p7QQfjdAm9OOxHIwyns5gO5+sBiEHC5GZadgSMg==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-clipboard": "43.0.0", + "@ckeditor/ckeditor5-core": "43.0.0", + "@ckeditor/ckeditor5-engine": "43.0.0", + "ckeditor5": "43.0.0" + } + }, + "node_modules/@ckeditor/ckeditor5-remove-format": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-remove-format/-/ckeditor5-remove-format-43.0.0.tgz", + "integrity": "sha512-q27Zqie8WJXk9XGp5CFaGZ8JMyLczhdGU/kyeeX9A5FcCDxpR2nYOgtq0BGgt14XTa2Hr0IKM8NIfdyxA29YNA==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.0.0", + "@ckeditor/ckeditor5-ui": "43.0.0", + "@ckeditor/ckeditor5-utils": "43.0.0", + "ckeditor5": "43.0.0" + } + }, + "node_modules/@ckeditor/ckeditor5-restricted-editing": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-restricted-editing/-/ckeditor5-restricted-editing-43.0.0.tgz", + "integrity": "sha512-zMX3ONNZ1jKKfT41PERvJOr79ciZYxCQjhBkCHQE6xe1VhU5QFfPibvZRj+KEHI6CBhxGrwo0In0YaLLIHbUuQ==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.0.0", + "@ckeditor/ckeditor5-engine": "43.0.0", + "@ckeditor/ckeditor5-ui": "43.0.0", + "@ckeditor/ckeditor5-utils": "43.0.0", + "ckeditor5": "43.0.0" + } + }, + "node_modules/@ckeditor/ckeditor5-select-all": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-select-all/-/ckeditor5-select-all-43.0.0.tgz", + "integrity": "sha512-ABPFd6cVeef5tWXtnv3ZNdCK1WcCEH48Gm8o84S+ZwQ0wW6y3CY3EW6QVCIL1sqBzgLY8NBBCgGvS7Ymn7fv4A==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.0.0", + "@ckeditor/ckeditor5-ui": "43.0.0", + "@ckeditor/ckeditor5-utils": "43.0.0" + } + }, + "node_modules/@ckeditor/ckeditor5-show-blocks": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-show-blocks/-/ckeditor5-show-blocks-43.0.0.tgz", + "integrity": "sha512-KX0nfY1Hhs++fv/mgy4+lJxT78ekOwSecLURpX3Mzs4j7AAek424D7itlP5r1wPK9e7ozPd7+AmUYHCuesSD4w==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.0.0", + "@ckeditor/ckeditor5-ui": "43.0.0", + "ckeditor5": "43.0.0" + } + }, + "node_modules/@ckeditor/ckeditor5-source-editing": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-source-editing/-/ckeditor5-source-editing-43.0.0.tgz", + "integrity": "sha512-Go9lDGoB26d0Rb7D329I54NHO4T28c4grqx6KVjO0R8nmugfcSpITBLdSn/KarDJA1ysIsbN7k/p5guuiVWTMg==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.0.0", + "@ckeditor/ckeditor5-theme-lark": "43.0.0", + "@ckeditor/ckeditor5-ui": "43.0.0", + "@ckeditor/ckeditor5-utils": "43.0.0", + "ckeditor5": "43.0.0" + } + }, + "node_modules/@ckeditor/ckeditor5-special-characters": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-special-characters/-/ckeditor5-special-characters-43.0.0.tgz", + "integrity": "sha512-5l2SdmYEBbid15xUo/L/UjzuxFODNEhNvv4mXIZZOX0tkJ6UNlF1jt5wMjFjWrfFUsZdUwj/aC/7FutotWeHrQ==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.0.0", + "@ckeditor/ckeditor5-typing": "43.0.0", + "@ckeditor/ckeditor5-ui": "43.0.0", + "@ckeditor/ckeditor5-utils": "43.0.0", + "ckeditor5": "43.0.0" + } + }, + "node_modules/@ckeditor/ckeditor5-style": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-style/-/ckeditor5-style-43.0.0.tgz", + "integrity": "sha512-9obmKXVQWsg/Ly25ggXyO92GrHp3lIcJ8vjEkbQU/8PO2pblhEylLJEPIRWSySNKYkw0d2fsSDKjC5c3Brx/Gg==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.0.0", + "@ckeditor/ckeditor5-typing": "43.0.0", + "@ckeditor/ckeditor5-ui": "43.0.0", + "@ckeditor/ckeditor5-utils": "43.0.0", + "ckeditor5": "43.0.0", + "lodash-es": "4.17.21" + } + }, + "node_modules/@ckeditor/ckeditor5-table": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-table/-/ckeditor5-table-43.0.0.tgz", + "integrity": "sha512-yHru16jsCG7Zr71hWVvCFyc08ol2dbUNwV4wAZUmM27sYyW8ue6ATML6NQQUiL+7gwbm1xit/Gm9hxuRBtzz+Q==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-clipboard": "43.0.0", + "@ckeditor/ckeditor5-core": "43.0.0", + "@ckeditor/ckeditor5-engine": "43.0.0", + "@ckeditor/ckeditor5-ui": "43.0.0", + "@ckeditor/ckeditor5-utils": "43.0.0", + "@ckeditor/ckeditor5-widget": "43.0.0", + "ckeditor5": "43.0.0", + "lodash-es": "4.17.21" + } + }, + "node_modules/@ckeditor/ckeditor5-theme-lark": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-theme-lark/-/ckeditor5-theme-lark-43.0.0.tgz", + "integrity": "sha512-cd66o/cdKFDhjMnhabgtrsl1K1cyRYzsQnS2459Ly7ApxreOF5w8MRQuGIfr7NmjDwu7xTo4CXowCxmRoxf3JQ==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-ui": "43.0.0" + } + }, + "node_modules/@ckeditor/ckeditor5-typing": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-typing/-/ckeditor5-typing-43.0.0.tgz", + "integrity": "sha512-OKXpo5NdM2ZAL4hJpL0SXdeEfWzZfcfFwRjmOSFOIhTH06wN2E77OQbdn1E6L3yyup+9iYBanL7BYjDBQL4/cQ==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.0.0", + "@ckeditor/ckeditor5-engine": "43.0.0", + "@ckeditor/ckeditor5-utils": "43.0.0", + "lodash-es": "4.17.21" + } + }, + "node_modules/@ckeditor/ckeditor5-ui": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-ui/-/ckeditor5-ui-43.0.0.tgz", + "integrity": "sha512-R77EeM3vbRWmVdCUPbw5ZfqQlz2UiOIrCnjkXEf1GQVFzn5THNejlUzf9QwL51GS8CquOyH8rg1iRPM9gQiGuw==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.0.0", + "@ckeditor/ckeditor5-utils": "43.0.0", + "color-convert": "2.0.1", + "color-parse": "1.4.2", + "lodash-es": "4.17.21", + "vanilla-colorful": "0.7.2" + } + }, + "node_modules/@ckeditor/ckeditor5-undo": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-undo/-/ckeditor5-undo-43.0.0.tgz", + "integrity": "sha512-FDLyZqxkcMqhodOHrYP/GTQWQuC3e9n1gg25nQYqR0IgEqrDU6TH+wTBMrvo6YHv3pl88IZsfNr2vj5ZnsKThQ==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.0.0", + "@ckeditor/ckeditor5-engine": "43.0.0", + "@ckeditor/ckeditor5-ui": "43.0.0" + } + }, + "node_modules/@ckeditor/ckeditor5-upload": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-upload/-/ckeditor5-upload-43.0.0.tgz", + "integrity": "sha512-IXryGBQFjw2wDz04UM8pbwjJETBxYCmyMz0WW7GJsNA04qO3evxlaCVGczb1nheRbbUb9SBU8wpHKPz05xMQdA==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.0.0", + "@ckeditor/ckeditor5-utils": "43.0.0" + } + }, + "node_modules/@ckeditor/ckeditor5-utils": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-utils/-/ckeditor5-utils-43.0.0.tgz", + "integrity": "sha512-xupNfpUX3EGVVRycijYGOZXTaWEebHPwEMAfI5rduYAUAf63AbTpL4s7sakxFaHp1SS3bQWN+j1QiXh/TBhRAw==", + "license": "GPL-2.0-or-later", + "dependencies": { + "lodash-es": "4.17.21" + } + }, + "node_modules/@ckeditor/ckeditor5-watchdog": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-watchdog/-/ckeditor5-watchdog-43.0.0.tgz", + "integrity": "sha512-sS+mnuWGZWpe04YbpGZWy3MpMzZ2eFDn911jo0+7nGbypuH8cqrFSZBCUZ4DyE7ghsZ2P6CgMTsUtz4G+kjeZw==", + "license": "GPL-2.0-or-later", + "dependencies": { + "lodash-es": "4.17.21" + } + }, + "node_modules/@ckeditor/ckeditor5-widget": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-widget/-/ckeditor5-widget-43.0.0.tgz", + "integrity": "sha512-jjRzj3jkieUxtTF2fGQVZCFi5Oq2gpkiJ77DaXEINNqyDx01d2mdIl/U0FnQbgfK/2bUf+1wp5qnT3Lwf4q5Jw==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.0.0", + "@ckeditor/ckeditor5-engine": "43.0.0", + "@ckeditor/ckeditor5-enter": "43.0.0", + "@ckeditor/ckeditor5-typing": "43.0.0", + "@ckeditor/ckeditor5-ui": "43.0.0", + "@ckeditor/ckeditor5-utils": "43.0.0", + "lodash-es": "4.17.21" + } + }, + "node_modules/@ckeditor/ckeditor5-word-count": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/@ckeditor/ckeditor5-word-count/-/ckeditor5-word-count-43.0.0.tgz", + "integrity": "sha512-AiqeuESUTCsNUPCoPzRq1BDAGqPW6e/9vZpZ0B0esDcshLddJ2oQk0bYyjvkpJ4GDNEwAwJyCN1yI7IYXGEBjw==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.0.0", + "@ckeditor/ckeditor5-ui": "43.0.0", + "@ckeditor/ckeditor5-utils": "43.0.0", + "ckeditor5": "43.0.0", + "lodash-es": "4.17.21" + } + }, + "node_modules/@mixmark-io/domino": { + "version": "2.2.0", + "resolved": "https://registry.npmmirror.com/@mixmark-io/domino/-/domino-2.2.0.tgz", + "integrity": "sha512-Y28PR25bHXUg88kCV7nivXrP2Nj2RueZ3/l/jdx6J9f8J4nsEGcgX0Qe6lt7Pa+J79+kPiJU3LguR6O/6zrLOw==", + "license": "BSD-2-Clause" + }, + "node_modules/blurhash": { + "version": "2.0.5", + "resolved": "https://registry.npmmirror.com/blurhash/-/blurhash-2.0.5.tgz", + "integrity": "sha512-cRygWd7kGBQO3VEhPiTgq4Wc43ctsM+o46urrmPOiuAe+07fzlSB9OJVdpgDL0jPqXUVQ9ht7aq7kxOeJHRK+w==", + "license": "MIT" + }, + "node_modules/ckeditor5": { + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/ckeditor5/-/ckeditor5-43.0.0.tgz", + "integrity": "sha512-7amisPZrSPMuaSDRFVAz/BgplV5OzUpWs6jtFP6MNDh98QK/RLyGvm4vhxjEN5n2MCov/ZURphwYsKwStIX68Q==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-adapter-ckfinder": "43.0.0", + "@ckeditor/ckeditor5-alignment": "43.0.0", + "@ckeditor/ckeditor5-autoformat": "43.0.0", + "@ckeditor/ckeditor5-autosave": "43.0.0", + "@ckeditor/ckeditor5-basic-styles": "43.0.0", + "@ckeditor/ckeditor5-block-quote": "43.0.0", + "@ckeditor/ckeditor5-ckbox": "43.0.0", + "@ckeditor/ckeditor5-ckfinder": "43.0.0", + "@ckeditor/ckeditor5-clipboard": "43.0.0", + "@ckeditor/ckeditor5-cloud-services": "43.0.0", + "@ckeditor/ckeditor5-code-block": "43.0.0", + "@ckeditor/ckeditor5-core": "43.0.0", + "@ckeditor/ckeditor5-easy-image": "43.0.0", + "@ckeditor/ckeditor5-editor-balloon": "43.0.0", + "@ckeditor/ckeditor5-editor-classic": "43.0.0", + "@ckeditor/ckeditor5-editor-decoupled": "43.0.0", + "@ckeditor/ckeditor5-editor-inline": "43.0.0", + "@ckeditor/ckeditor5-editor-multi-root": "43.0.0", + "@ckeditor/ckeditor5-engine": "43.0.0", + "@ckeditor/ckeditor5-enter": "43.0.0", + "@ckeditor/ckeditor5-essentials": "43.0.0", + "@ckeditor/ckeditor5-find-and-replace": "43.0.0", + "@ckeditor/ckeditor5-font": "43.0.0", + "@ckeditor/ckeditor5-heading": "43.0.0", + "@ckeditor/ckeditor5-highlight": "43.0.0", + "@ckeditor/ckeditor5-horizontal-line": "43.0.0", + "@ckeditor/ckeditor5-html-embed": "43.0.0", + "@ckeditor/ckeditor5-html-support": "43.0.0", + "@ckeditor/ckeditor5-image": "43.0.0", + "@ckeditor/ckeditor5-indent": "43.0.0", + "@ckeditor/ckeditor5-language": "43.0.0", + "@ckeditor/ckeditor5-link": "43.0.0", + "@ckeditor/ckeditor5-list": "43.0.0", + "@ckeditor/ckeditor5-markdown-gfm": "43.0.0", + "@ckeditor/ckeditor5-media-embed": "43.0.0", + "@ckeditor/ckeditor5-mention": "43.0.0", + "@ckeditor/ckeditor5-minimap": "43.0.0", + "@ckeditor/ckeditor5-page-break": "43.0.0", + "@ckeditor/ckeditor5-paragraph": "43.0.0", + "@ckeditor/ckeditor5-paste-from-office": "43.0.0", + "@ckeditor/ckeditor5-remove-format": "43.0.0", + "@ckeditor/ckeditor5-restricted-editing": "43.0.0", + "@ckeditor/ckeditor5-select-all": "43.0.0", + "@ckeditor/ckeditor5-show-blocks": "43.0.0", + "@ckeditor/ckeditor5-source-editing": "43.0.0", + "@ckeditor/ckeditor5-special-characters": "43.0.0", + "@ckeditor/ckeditor5-style": "43.0.0", + "@ckeditor/ckeditor5-table": "43.0.0", + "@ckeditor/ckeditor5-theme-lark": "43.0.0", + "@ckeditor/ckeditor5-typing": "43.0.0", + "@ckeditor/ckeditor5-ui": "43.0.0", + "@ckeditor/ckeditor5-undo": "43.0.0", + "@ckeditor/ckeditor5-upload": "43.0.0", + "@ckeditor/ckeditor5-utils": "43.0.0", + "@ckeditor/ckeditor5-watchdog": "43.0.0", + "@ckeditor/ckeditor5-widget": "43.0.0", + "@ckeditor/ckeditor5-word-count": "43.0.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/color-parse": { + "version": "1.4.2", + "resolved": "https://registry.npmmirror.com/color-parse/-/color-parse-1.4.2.tgz", + "integrity": "sha512-RI7s49/8yqDj3fECFZjUI1Yi0z/Gq1py43oNJivAIIDSyJiOZLfYCRQEgn8HEVAj++PcRe8AnL2XF0fRJ3BTnA==", + "license": "MIT", + "dependencies": { + "color-name": "^1.0.0" + } + }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmmirror.com/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", + "license": "MIT" + }, + "node_modules/marked": { + "version": "4.0.12", + "resolved": "https://registry.npmmirror.com/marked/-/marked-4.0.12.tgz", + "integrity": "sha512-hgibXWrEDNBWgGiK18j/4lkS6ihTe9sxtV4Q1OQppb/0zzyPSzoFANBa5MfsG/zgsWklmNnhm0XACZOH/0HBiQ==", + "license": "MIT", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/turndown": { + "version": "7.2.0", + "resolved": "https://registry.npmmirror.com/turndown/-/turndown-7.2.0.tgz", + "integrity": "sha512-eCZGBN4nNNqM9Owkv9HAtWRYfLA4h909E/WGAWWBpmB275ehNhZyk87/Tpvjbp0jjNl9XwCsbe6bm6CqFsgD+A==", + "license": "MIT", + "dependencies": { + "@mixmark-io/domino": "^2.2.0" + } + }, + "node_modules/turndown-plugin-gfm": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/turndown-plugin-gfm/-/turndown-plugin-gfm-1.0.2.tgz", + "integrity": "sha512-vwz9tfvF7XN/jE0dGoBei3FXWuvll78ohzCZQuOb+ZjWrs3a0XhQVomJEb2Qh4VHTPNRO4GPZh0V7VRbiWwkRg==", + "license": "MIT" + }, + "node_modules/vanilla-colorful": { + "version": "0.7.2", + "resolved": "https://registry.npmmirror.com/vanilla-colorful/-/vanilla-colorful-0.7.2.tgz", + "integrity": "sha512-z2YZusTFC6KnLERx1cgoIRX2CjPRP0W75N+3CC6gbvdX5Ch47rZkEMGO2Xnf+IEmi3RiFLxS18gayMA27iU7Kg==", + "license": "MIT" } } } diff --git a/package.json b/package.json index 2099075..dcc5d24 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,8 @@ { "name": "@emagtechlabs/ckeditor5-file-upload", - "version": "1.0.4", + "version": "1.1.0", "description": "Classic File Upload Tool for CKEditor5", - "main": "src/fileupload.js", + "main": "fileupload.js", "keywords": [ "ckeditor5", "classic", @@ -11,13 +11,7 @@ "plugin" ], "dependencies": { - "@ckeditor/ckeditor5-core": "^17.0.0", - "@ckeditor/ckeditor5-upload": "^17.0.0", - "@ckeditor/ckeditor5-ui": "^17.0.0", - "@ckeditor/ckeditor5-clipboard": "^17.0.0", - "@ckeditor/ckeditor5-engine": "^17.0.0", - "@ckeditor/ckeditor5-utils": "^17.0.0", - "@ckeditor/ckeditor5-widget": "^17.0.0" + "ckeditor5": "43.0.0" }, "repository": { "type": "git", diff --git a/src/fileuploadcommand.js b/src/fileuploadcommand.js index a78eacb..2e1edd7 100755 --- a/src/fileuploadcommand.js +++ b/src/fileuploadcommand.js @@ -1,35 +1,34 @@ -import FileRepository from '@ckeditor/ckeditor5-upload/src/filerepository'; -import Command from '@ckeditor/ckeditor5-core/src/command'; -import { insertFileLink, isFileAllowed } from './utils'; +import { FileRepository, Command } from 'ckeditor5' +import { insertFileLink } from './utils' export default class FileUploadCommand extends Command { - /** - * @inheritDoc - */ - refresh() { - this.isEnabled = true; - } + /** + * @inheritDoc + */ + refresh () { + this.isEnabled = true + } - /** - * Executes the command. - * - * @fires execute - * @param {Object} options Options for the executed command. - * @param {File|Array.} options.file The file or an array of files to upload. - */ - execute( options ) { - const editor = this.editor; - const model = editor.model; + /** + * Executes the command. + * + * @fires execute + * @param {Object} options Options for the executed command. + * @param {File|Array.} options.file The file or an array of files to upload. + */ + execute (options) { + const editor = this.editor + const model = editor.model - const fileRepository = editor.plugins.get( FileRepository ); + const fileRepository = editor.plugins.get(FileRepository) - model.change( writer => { - const filesToUpload = options.file; - for ( const file of filesToUpload ) { - uploadFile( writer, model, fileRepository, file ); - } - } ); - } + model.change(writer => { + const filesToUpload = options.file + for (const file of filesToUpload) { + uploadFile(writer, model, fileRepository, file) + } + }) + } } /** @@ -39,13 +38,13 @@ export default class FileUploadCommand extends Command { * @param {module:engine/model/model~Model} model * @param {File} file */ -function uploadFile( writer, model, fileRepository, file ) { - const loader = fileRepository.createLoader( file ); +function uploadFile (writer, model, fileRepository, file) { + const loader = fileRepository.createLoader(file) - // Do not throw when upload adapter is not set. FileRepository will log an error anyway. - if ( !loader ) { - return; - } + // Do not throw when upload adapter is not set. FileRepository will log an error anyway. + if (!loader) { + return + } - insertFileLink( writer, model, {linkHref: "", uploadId: loader.id }, file ); + insertFileLink(writer, model, { linkHref: '', uploadId: loader.id }, file) } diff --git a/src/fileuploadediting.js b/src/fileuploadediting.js index 4e0a1e7..a260667 100755 --- a/src/fileuploadediting.js +++ b/src/fileuploadediting.js @@ -1,13 +1,6 @@ - -import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; -import FileRepository from '@ckeditor/ckeditor5-upload/src/filerepository'; -import Notification from '@ckeditor/ckeditor5-ui/src/notification/notification'; -import Clipboard from '@ckeditor/ckeditor5-clipboard/src/clipboard'; -import UpcastWriter from '@ckeditor/ckeditor5-engine/src/view/upcastwriter'; - -import { fetchLocalFile, isLocalFile } from './utils'; -import { createFileTypeRegExp } from './utils'; -import FileUploadCommand from "./fileuploadcommand"; +import { Plugin, FileRepository, Notification, Clipboard, UpcastWriter } from 'ckeditor5' +import { fetchLocalFile, isLocalFile, createFileTypeRegExp } from './utils' +import FileUploadCommand from './fileuploadcommand' /** * The editing part of the file upload feature. It registers the `'fileUpload'` command. @@ -15,234 +8,232 @@ import FileUploadCommand from "./fileuploadcommand"; * @extends module:core/plugin~Plugin */ export default class FileUploadEditing extends Plugin { - /** - * @inheritDoc - */ - static get requires() { - return [ FileRepository, Notification, Clipboard ]; - } - - static get pluginName() { - return 'FileUploadEditing'; - } - - /** - * @inheritDoc - */ - constructor( editor ) { - super( editor ); - } - - /** - * @inheritDoc - */ - init() { - const editor = this.editor; - const doc = editor.model.document; - const schema = editor.model.schema; - const conversion = editor.conversion; - const fileRepository = editor.plugins.get( FileRepository ); - - const fileTypes = createFileTypeRegExp(editor.config.get( 'simpleFileUpload.fileTypes' )); - - // Setup schema to allow uploadId and uploadStatus for files. - schema.extend( '$text', { - allowAttributes: [ - 'uploadId', - 'uploadStatus' - ] - } ); - - // Register fileUpload command. - editor.commands.add( 'fileUpload', new FileUploadCommand( editor ) ); - - // Register upcast converter for uploadId. - conversion.for( 'upcast' ) - .attributeToAttribute( { - view: { - name: 'a', - key: 'uploadId' - }, - model: 'uploadId' - } ); - - this.listenTo( editor.editing.view.document, 'clipboardInput', ( evt, data ) => { - // Skip if non empty HTML data is included. - // https://github.com/ckeditor/ckeditor5-upload/issues/68 - if ( isHtmlIncluded( data.dataTransfer ) ) { - return; - } - - const files = Array.from( data.dataTransfer.files ).filter( file => { - if ( !file ) { - return false; - } - return fileTypes.test( file.type ); - } ); - - const ranges = data.targetRanges.map( viewRange => editor.editing.mapper.toModelRange( viewRange ) ); - - editor.model.change( writer => { - // Set selection to paste target. - writer.setSelection( ranges ); - - if ( files.length ) { - evt.stop(); - - // Upload files after the selection has changed in order to ensure the command's state is refreshed. - editor.model.enqueueChange( 'default', () => { - editor.execute( 'fileUpload', { file: files } ); - } ); - } - } ); - } ); - - this.listenTo( editor.plugins.get( Clipboard ), 'inputTransformation', ( evt, data ) => { - const fetchableFiles = Array.from( editor.editing.view.createRangeIn( data.content ) ) - .filter( value => isLocalFile( value.item ) && !value.item.getAttribute( 'uploadProcessed' ) ) - .map( value => { return { promise: fetchLocalFile( value.item ), fileElement: value.item }; } ); - - if ( !fetchableFiles.length ) { - return; - } - - const writer = new UpcastWriter(); - - for ( const fetchableFile of fetchableFiles ) { - // Set attribute marking that the file was processed already. - writer.setAttribute( 'uploadProcessed', true, fetchableFile.fileElement ); - - const loader = fileRepository.createLoader( fetchableFile.promise ); - - if ( loader ) { - writer.setAttribute( 'href', '', fetchableFile.fileElement ); - writer.setAttribute( 'uploadId', loader.id, fetchableFile.fileElement ); - } - } - } ); - - // Prevents from the browser redirecting to the dropped file. - editor.editing.view.document.on( 'dragover', ( evt, data ) => { - data.preventDefault(); - } ); - - // Upload placeholder files that appeared in the model. - doc.on( 'change', () => { - const changes = doc.differ.getChanges( { includeChangesInGraveyard: true } ); - for ( const entry of changes ) { - if ( entry.type == 'insert') { - const item = entry.position.nodeAfter; - if (item) { - const isInGraveyard = entry.position.root.rootName == '$graveyard'; - for ( const file of getFileLinksFromChangeItem( editor, item ) ) { - // Check if the file element still has upload id. - const uploadId = file.getAttribute( 'uploadId' ); - if ( !uploadId ) { - continue; - } - - // Check if the file is loaded on this client. - const loader = fileRepository.loaders.get( uploadId ); - - if ( !loader ) { - continue; - } - - if ( isInGraveyard ) { - // If the file was inserted to the graveyard - abort the loading process. - loader.abort(); - } else if ( loader.status == 'idle' ) { - // If the file was inserted into content and has not been loaded yet, start loading it. - this._readAndUpload( loader, file ); - } - } - } - - } - } - } ); - } - - /** - * Reads and uploads a file. - * - * @protected - * @param {module:upload/filerepository~FileLoader} loader - * @param {module:engine/model/element~Element} fileElement - * @returns {Promise} - */ - _readAndUpload( loader, fileElement ) { - const editor = this.editor; - const model = editor.model; - const t = editor.locale.t; - const fileRepository = editor.plugins.get( FileRepository ); - const notification = editor.plugins.get( Notification ); - - model.enqueueChange( 'transparent', writer => { - writer.setAttribute( 'uploadStatus', 'reading', fileElement ); - } ); - - return loader.read() - .then( () => { - const promise = loader.upload(); - - model.enqueueChange( 'transparent', writer => { - writer.setAttribute( 'uploadStatus', 'uploading', fileElement ); - } ); - - return promise; - } ) - .then( data => { - model.enqueueChange( 'transparent', writer => { - writer.setAttributes( { uploadStatus: 'complete', linkHref: data.resourceUrl }, fileElement ); - } ); - - clean(); - } ) - .catch( error => { - // If status is not 'error' nor 'aborted' - throw error because it means that something else went wrong, - // it might be generic error and it would be real pain to find what is going on. - if ( loader.status !== 'error' && loader.status !== 'aborted' ) { - throw error; - } - - // Might be 'aborted'. - if ( loader.status == 'error' && error ) { - notification.showWarning( error, { - title: t( 'Upload failed' ), - namespace: 'upload' - } ); - } - - clean(); - - // Permanently remove file from insertion batch. - model.enqueueChange( 'transparent', writer => { - writer.remove( fileElement ); - } ); - } ); - - function clean() { - model.enqueueChange( 'transparent', writer => { - writer.removeAttribute( 'uploadId', fileElement ); - writer.removeAttribute( 'uploadStatus', fileElement ); - } ); - - fileRepository.destroyLoader( loader ); - } - } + /** + * @inheritDoc + */ + static get requires () { + return [FileRepository, Notification, Clipboard] + } + + static get pluginName () { + return 'FileUploadEditing' + } + + /** + * @inheritDoc + */ + constructor (editor) { + super(editor) + } + + /** + * @inheritDoc + */ + init () { + const editor = this.editor + const doc = editor.model.document + const schema = editor.model.schema + const conversion = editor.conversion + const fileRepository = editor.plugins.get(FileRepository) + + const fileTypes = createFileTypeRegExp(editor.config.get('simpleFileUpload.fileTypes')) + + // Setup schema to allow uploadId and uploadStatus for files. + schema.extend('$text', { + allowAttributes: ['uploadId', 'uploadStatus'] + }) + + // Register fileUpload command. + editor.commands.add('fileUpload', new FileUploadCommand(editor)) + + // Register upcast converter for uploadId. + conversion.for('upcast').attributeToAttribute({ + view: { + name: 'a', + key: 'uploadId' + }, + model: 'uploadId' + }) + + this.listenTo(editor.editing.view.document, 'clipboardInput', (evt, data) => { + // Skip if non empty HTML data is included. + // https://github.com/ckeditor/ckeditor5-upload/issues/68 + if (isHtmlIncluded(data.dataTransfer)) { + return + } + + const files = Array.from(data.dataTransfer.files).filter(file => { + if (!file) { + return false + } + return fileTypes.test(file.type) + }) + + const ranges = data.targetRanges.map(viewRange => editor.editing.mapper.toModelRange(viewRange)) + + editor.model.change(writer => { + // Set selection to paste target. + writer.setSelection(ranges) + + if (files.length) { + evt.stop() + + // Upload files after the selection has changed in order to ensure the command's state is refreshed. + editor.model.enqueueChange('default', () => { + editor.execute('fileUpload', { file: files }) + }) + } + }) + }) + + this.listenTo(editor.plugins.get(Clipboard), 'inputTransformation', (evt, data) => { + const fetchableFiles = Array.from(editor.editing.view.createRangeIn(data.content)) + .filter(value => isLocalFile(value.item) && !value.item.getAttribute('uploadProcessed')) + .map(value => { + return { promise: fetchLocalFile(value.item), fileElement: value.item } + }) + + if (!fetchableFiles.length) { + return + } + + const writer = new UpcastWriter() + + for (const fetchableFile of fetchableFiles) { + // Set attribute marking that the file was processed already. + writer.setAttribute('uploadProcessed', true, fetchableFile.fileElement) + + const loader = fileRepository.createLoader(fetchableFile.promise) + + if (loader) { + writer.setAttribute('href', '', fetchableFile.fileElement) + writer.setAttribute('uploadId', loader.id, fetchableFile.fileElement) + } + } + }) + + // Prevents from the browser redirecting to the dropped file. + editor.editing.view.document.on('dragover', (evt, data) => { + data.preventDefault() + }) + + // Upload placeholder files that appeared in the model. + doc.on('change', () => { + const changes = doc.differ.getChanges({ includeChangesInGraveyard: true }) + for (const entry of changes) { + if (entry.type == 'insert') { + const item = entry.position.nodeAfter + if (item) { + const isInGraveyard = entry.position.root.rootName == '$graveyard' + for (const file of getFileLinksFromChangeItem(editor, item)) { + // Check if the file element still has upload id. + const uploadId = file.getAttribute('uploadId') + if (!uploadId) { + continue + } + + // Check if the file is loaded on this client. + const loader = fileRepository.loaders.get(uploadId) + + if (!loader) { + continue + } + + if (isInGraveyard) { + // If the file was inserted to the graveyard - abort the loading process. + loader.abort() + } else if (loader.status == 'idle') { + // If the file was inserted into content and has not been loaded yet, start loading it. + this._readAndUpload(loader, file) + } + } + } + } + } + }) + } + + /** + * Reads and uploads a file. + * + * @protected + * @param {module:upload/filerepository~FileLoader} loader + * @param {module:engine/model/element~Element} fileElement + * @returns {Promise} + */ + _readAndUpload (loader, fileElement) { + const editor = this.editor + const model = editor.model + const t = editor.locale.t + const fileRepository = editor.plugins.get(FileRepository) + const notification = editor.plugins.get(Notification) + + model.enqueueChange('transparent', writer => { + writer.setAttribute('uploadStatus', 'reading', fileElement) + }) + + return loader + .read() + .then(() => { + const promise = loader.upload() + + model.enqueueChange('transparent', writer => { + writer.setAttribute('uploadStatus', 'uploading', fileElement) + }) + + return promise + }) + .then(data => { + model.enqueueChange('transparent', writer => { + writer.setAttributes({ uploadStatus: 'complete', linkHref: data.resourceUrl }, fileElement) + }) + + clean() + }) + .catch(error => { + // If status is not 'error' nor 'aborted' - throw error because it means that something else went wrong, + // it might be generic error and it would be real pain to find what is going on. + if (loader.status !== 'error' && loader.status !== 'aborted') { + throw error + } + + // Might be 'aborted'. + if (loader.status == 'error' && error) { + notification.showWarning(error, { + title: t('Upload failed'), + namespace: 'upload' + }) + } + + clean() + + // Permanently remove file from insertion batch. + model.enqueueChange('transparent', writer => { + writer.remove(fileElement) + }) + }) + + function clean () { + model.enqueueChange('transparent', writer => { + writer.removeAttribute('uploadId', fileElement) + writer.removeAttribute('uploadStatus', fileElement) + }) + + fileRepository.destroyLoader(loader) + } + } } // Returns `true` if non-empty `text/html` is included in the data transfer. // // @param {module:clipboard/datatransfer~DataTransfer} dataTransfer // @returns {Boolean} -export function isHtmlIncluded( dataTransfer ) { - return Array.from( dataTransfer.types ).includes( 'text/html' ) && dataTransfer.getData( 'text/html' ) !== ''; +export function isHtmlIncluded (dataTransfer) { + return Array.from(dataTransfer.types).includes('text/html') && dataTransfer.getData('text/html') !== '' } -function getFileLinksFromChangeItem( editor, item ) { - return Array.from( editor.model.createRangeOn( item ) ) - .filter( value => value.item.hasAttribute('linkHref')) - .map( value => value.item ); +function getFileLinksFromChangeItem (editor, item) { + return Array.from(editor.model.createRangeOn(item)) + .filter(value => value.item.hasAttribute('linkHref')) + .map(value => value.item) } diff --git a/src/fileuploadprogress.js b/src/fileuploadprogress.js index 7da3069..a279c63 100755 --- a/src/fileuploadprogress.js +++ b/src/fileuploadprogress.js @@ -1,8 +1,7 @@ -import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; -import FileRepository from '@ckeditor/ckeditor5-upload/src/filerepository'; -import ProgressBarView from "../theme/progressbarview"; +import { Plugin, FileRepository } from 'ckeditor5' +import ProgressBarView from '../theme/progressbarview' -import '../theme/fileupload.css'; +import '../theme/fileupload.css' /** * The file upload progress plugin. @@ -11,93 +10,84 @@ import '../theme/fileupload.css'; * @extends module:core/plugin~Plugin */ export default class FileUploadProgress extends Plugin { - - /** - * @inheritDoc - */ - static get pluginName() { - return 'fileUploadProgress'; - } - - /** - * @inheritDoc - */ - init() { - const editor = this.editor; - // Upload status change - update file's view according to that status. - editor.editing.downcastDispatcher.on( - 'attribute:uploadStatus:$text', - ( ...args ) => this.uploadStatusChange( ...args ) - ); - } - - /** - * This method is called each time the file `uploadStatus` attribute is changed. - * - * @param {module:utils/eventinfo~EventInfo} evt An object containing information about the fired event. - * @param {Object} data Additional information about the change. - * @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi - */ - uploadStatusChange( evt, data, conversionApi ) { - const editor = this.editor; - const modelItem = data.item; - - const fileRepository = editor.plugins.get( FileRepository ); - const uploadId = modelItem.getAttribute( 'uploadId' ); - const status = uploadId ? data.attributeNewValue : null - - if ( !conversionApi.consumable.consume( data.item, evt.name ) ) { - return; - } - - // Show progress bar on the top of the file when the file is uploading. - if ( status === 'reading' ) { - const loader = fileRepository.loaders.get( uploadId ); - this.progressBar = _showProgressBar(editor, loader); - - return; - } - - return; - } + /** + * @inheritDoc + */ + static get pluginName () { + return 'fileUploadProgress' + } + + /** + * @inheritDoc + */ + init () { + const editor = this.editor + // Upload status change - update file's view according to that status. + editor.editing.downcastDispatcher.on('attribute:uploadStatus:$text', (...args) => this.uploadStatusChange(...args)) + } + + /** + * This method is called each time the file `uploadStatus` attribute is changed. + * + * @param {module:utils/eventinfo~EventInfo} evt An object containing information about the fired event. + * @param {Object} data Additional information about the change. + * @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi + */ + uploadStatusChange (evt, data, conversionApi) { + const editor = this.editor + const modelItem = data.item + + const fileRepository = editor.plugins.get(FileRepository) + const uploadId = modelItem.getAttribute('uploadId') + const status = uploadId ? data.attributeNewValue : null + + if (!conversionApi.consumable.consume(data.item, evt.name)) { + return + } + + // Show progress bar on the top of the file when the file is uploading. + if (status === 'reading') { + const loader = fileRepository.loaders.get(uploadId) + this.progressBar = _showProgressBar(editor, loader) + } + } } -function _createProgressBar(locale) { - return new ProgressBarView(locale); +function _createProgressBar (locale) { + return new ProgressBarView(locale) } -function _showProgressBar(editor, loader) { - const progressBar = _createProgressBar(editor.locale); - const toolbar = editor.ui.view.stickyPanel; - progressBar.render(); +function _showProgressBar (editor, loader) { + const progressBar = _createProgressBar(editor.locale) + const toolbar = editor.ui.view.stickyPanel + progressBar.render() - toolbar.element.append(progressBar.element); + toolbar.element.append(progressBar.element) - progressBar.on( 'cancel', () => { - try { - loader.abort(); - } catch { - console.warn('Loader already aborted.') - } + progressBar.on('cancel', () => { + try { + loader.abort() + } catch { + console.warn('Loader already aborted.') + } - _removeProgressBar(toolbar, progressBar); - } ); + _removeProgressBar(toolbar, progressBar) + }) - loader.on( 'change:uploadedPercent', ( evt, name, value ) => { - progressBar.set('customWidth', value); - } ); + loader.on('change:uploadedPercent', (evt, name, value) => { + progressBar.set('customWidth', value) + }) - loader.on( 'change:uploadResponse', ( evt, name, value ) => { - if (value) { - _removeProgressBar(toolbar, progressBar); - } - } ); + loader.on('change:uploadResponse', (evt, name, value) => { + if (value) { + _removeProgressBar(toolbar, progressBar) + } + }) - return progressBar; + return progressBar } -function _removeProgressBar(toolbar, progressBar) { - toolbar.element.removeChild(progressBar.element); - progressBar.destroy(); +function _removeProgressBar (toolbar, progressBar) { + toolbar.element.removeChild(progressBar.element) + progressBar.destroy() } - diff --git a/src/fileuploadui.js b/src/fileuploadui.js index f94ea4c..40dcb33 100755 --- a/src/fileuploadui.js +++ b/src/fileuploadui.js @@ -1,6 +1,5 @@ -import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; -import FileDialogButtonView from '@ckeditor/ckeditor5-upload/src/ui/filedialogbuttonview'; -import fileUploadIcon from '../theme/icons/fileupload.svg'; +import { Plugin, FileDialogButtonView } from 'ckeditor5' +import fileUploadIcon from '../theme/icons/fileupload.svg?raw' /** * The file upload button plugin. @@ -10,41 +9,41 @@ import fileUploadIcon from '../theme/icons/fileupload.svg'; * @extends module:core/plugin~Plugin */ export default class FileUploadUI extends Plugin { - /** - * @inheritDoc - */ - init() { - const editor = this.editor; - const t = editor.t; - - // Setup `fileUpload` button. - editor.ui.componentFactory.add( 'fileUpload', locale => { - const view = new FileDialogButtonView( locale ); - const command = editor.commands.get( 'fileUpload' ); - const fileTypes = editor.config.get( 'simpleFileUpload.fileTypes' ); - - view.set( { - acceptedType: fileTypes.map(type => `${ type }`).join(','), - allowMultipleFiles: false - } ); - - view.buttonView.set( { - label: t( 'Insert file' ), - icon: fileUploadIcon, - tooltip: true - } ); - - view.buttonView.bind( 'isEnabled' ).to( command ); - - view.on( 'done', ( evt, file ) => { - const fileToUpload = file; - - if ( fileToUpload.length ) { - editor.execute( 'fileUpload', { file: fileToUpload } ); - } - } ); - - return view; - } ); - } + /** + * @inheritDoc + */ + init () { + const editor = this.editor + const t = editor.t + + // Setup `fileUpload` button. + editor.ui.componentFactory.add('fileUpload', locale => { + const view = new FileDialogButtonView(locale) + const command = editor.commands.get('fileUpload') + const fileTypes = editor.config.get('simpleFileUpload.fileTypes') + + view.set({ + acceptedType: fileTypes.map(type => `${type}`).join(','), + allowMultipleFiles: false + }) + + view.buttonView.set({ + label: t('Insert file'), + icon: fileUploadIcon, + tooltip: true + }) + + view.buttonView.bind('isEnabled').to(command) + + view.on('done', (evt, file) => { + const fileToUpload = file + + if (fileToUpload.length) { + editor.execute('fileUpload', { file: fileToUpload }) + } + }) + + return view + }) + } } diff --git a/src/mimeTypes.js b/src/mimeTypes.js index a1f65eb..f687822 100644 --- a/src/mimeTypes.js +++ b/src/mimeTypes.js @@ -1,7 +1,7 @@ -export let mimeTypes = { - 'pdf' : 'pdf', - 'doc' : 'msword', - 'docx' : 'msword', - 'xls' : 'vnd.ms-excel', - 'xlsx' : 'vnd.openxmlformats-officedocument.spreadsheetml.sheet' -} \ No newline at end of file +export const mimeTypes = { + pdf: 'pdf', + doc: 'msword', + docx: 'msword', + xls: 'vnd.ms-excel', + xlsx: 'vnd.openxmlformats-officedocument.spreadsheetml.sheet' +} diff --git a/src/simplefileuploadadapter.js b/src/simplefileuploadadapter.js index 3e189dd..549d4a6 100644 --- a/src/simplefileuploadadapter.js +++ b/src/simplefileuploadadapter.js @@ -1,128 +1,130 @@ -import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; -import FileRepository from '@ckeditor/ckeditor5-upload/src/filerepository'; -import { attachLinkToDocumentation } from '@ckeditor/ckeditor5-utils/src/ckeditorerror'; +import { Plugin, FileRepository, logWarning } from 'ckeditor5' export default class SimpleFileUploadAdapter extends Plugin { - /** - * @inheritDoc - */ - static get requires() { - return [ FileRepository ]; + /** + * @inheritDoc + */ + static get requires () { + return [FileRepository] + } + + /** + * @inheritDoc + */ + static get pluginName () { + return 'SimpleFileUploadAdapter' + } + + /** + * @inheritDoc + */ + init () { + const options = this.editor.config.get('simpleFileUpload') + + if (!options) { + return } - /** - * @inheritDoc - */ - static get pluginName() { - return 'SimpleFileUploadAdapter'; - } - - /** - * @inheritDoc - */ - init() { - const options = this.editor.config.get( 'simpleFileUpload' ); - - if ( !options ) { - return; - } + if (!options.url) { + console.warn( + logWarning( + 'simple-upload-adapter-missing-uploadUrl: Missing the "uploadUrl" property in the "simpleUpload" editor configuration.' + ) + ) - if ( !options.url ) { - console.warn( attachLinkToDocumentation( - 'simple-upload-adapter-missing-uploadUrl: Missing the "uploadUrl" property in the "simpleUpload" editor configuration.' - ) ); - - return; - } + return + } - this.editor.plugins.get( FileRepository ).createUploadAdapter = loader => { - return new FileUploadAdapter( loader, options ); - }; + this.editor.plugins.get(FileRepository).createUploadAdapter = loader => { + return new FileUploadAdapter(loader, options) } + } } class FileUploadAdapter { - constructor( loader, options ) { - // The file loader instance to use during the upload. - this.loader = loader; - this.options = options; - } - - // Starts the upload process. - upload() { - return this.loader.file - .then( file => new Promise( ( resolve, reject ) => { - this._initRequest(); - this._initListeners( resolve, reject, file ); - this._sendRequest( file ); - } ) ); + constructor (loader, options) { + // The file loader instance to use during the upload. + this.loader = loader + this.options = options + } + + // Starts the upload process. + upload () { + return this.loader.file.then( + file => + 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() } - - // Aborts the upload process. - abort() { - if ( this.xhr ) { - this.xhr.abort(); + } + + // Initializes the XMLHttpRequest object using the URL passed to the constructor. + _initRequest () { + const xhr = (this.xhr = new XMLHttpRequest()) + + xhr.open('POST', this.options.url, true) + xhr.responseType = 'json' + } + + // Initializes XMLHttpRequest listeners. + _initListeners (resolve, reject, 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 + + if (!response || response.error) { + return reject(response && response.error ? response.error.message : genericErrorText) + } + + resolve({ + resourceUrl: response.url + }) + }) + + if (xhr.upload) { + xhr.upload.addEventListener('progress', evt => { + if (evt.lengthComputable) { + loader.uploadTotal = evt.total + loader.uploaded = evt.loaded } + }) } + } - // Initializes the XMLHttpRequest object using the URL passed to the constructor. - _initRequest() { - const xhr = this.xhr = new XMLHttpRequest(); + // Prepares the data and sends the request. + _sendRequest (file) { + // set header request + const headers = this.options.headers || {} - xhr.open( 'POST', this.options.url, true ); - xhr.responseType = 'json'; - } + // Use the withCredentials if exist. + const withCredentials = this.options.withCredentials || false - // Initializes XMLHttpRequest listeners. - _initListeners( resolve, reject, 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; - - if ( !response || response.error ) { - return reject( response && response.error ? response.error.message : genericErrorText ); - } - - resolve( { - resourceUrl: response.url - } ); - } ); - - if ( xhr.upload ) { - xhr.upload.addEventListener( 'progress', evt => { - if ( evt.lengthComputable ) { - loader.uploadTotal = evt.total; - loader.uploaded = evt.loaded; - } - } ); - } + for (const headerName of Object.keys(headers)) { + this.xhr.setRequestHeader(headerName, headers[headerName]) } - // Prepares the data and sends the request. - _sendRequest( file ) { - // set header request - const headers = this.options.headers || {}; - - // Use the withCredentials if exist. - const withCredentials = this.options.withCredentials || false; - - for ( const headerName of Object.keys( headers ) ) { - this.xhr.setRequestHeader( headerName, headers[ headerName ] ); - } - - this.xhr.withCredentials = withCredentials; - - // Prepare the form data. - const data = new FormData(); - - data.append( 'upload', file ); - - // Send the request. - this.xhr.send( data ); - } + this.xhr.withCredentials = withCredentials + + // Prepare the form data. + const data = new FormData() + + data.append('upload', file) + + // Send the request. + this.xhr.send(data) + } } diff --git a/src/utils.js b/src/utils.js index 4d968a4..00a60da 100755 --- a/src/utils.js +++ b/src/utils.js @@ -1,5 +1,5 @@ -import {findOptimalInsertionRange} from '@ckeditor/ckeditor5-widget/src/utils'; -import {mimeTypes} from './mimeTypes'; +import { findOptimalInsertionRange } from 'ckeditor5' +import { mimeTypes } from './mimeTypes' /* global fetch, File */ @@ -9,10 +9,10 @@ import {mimeTypes} from './mimeTypes'; * @param {Array.} types * @returns {RegExp} */ -export function createFileTypeRegExp( types ) { - // Sanitize the MIME type name which may include: "+", "-" or ".". - const regExpSafeNames = Object.values(mimeTypes).map( type => type.replace( '+', '\\+' ) ); - return new RegExp( `^application\\/(${ regExpSafeNames.join( '|' ) })$` ); +export function createFileTypeRegExp (types) { + // Sanitize the MIME type name which may include: "+", "-" or ".". + const regExpSafeNames = Object.values(mimeTypes).map(type => type.replace('+', '\\+')) + return new RegExp(`^application\\/(${regExpSafeNames.join('|')})$`) } /** @@ -20,46 +20,45 @@ export function createFileTypeRegExp( types ) { * @returns {Promise.} A promise which resolves when an image source is fetched and converted to a `File` instance. * It resolves with a `File` object. If there were any errors during file processing, the promise will be rejected. */ -export function fetchLocalFile( link ) { - return new Promise( ( resolve, reject ) => { - const linkHref = link.getAttribute( 'href' ); +export function fetchLocalFile (link) { + return new Promise((resolve, reject) => { + const linkHref = link.getAttribute('href') - // Fetch works asynchronously and so does not block browser UI when processing data. - fetch( linkHref ) - .then( resource => resource.blob() ) - .then( blob => { - const mimeType = getFileMimeType( blob, linkHref ); - const ext = mimeType.replace( 'file/', '' ); - const filename = `file.${ ext }`; - const file = createFileFromBlob( blob, filename, mimeType ); + // Fetch works asynchronously and so does not block browser UI when processing data. + fetch(linkHref) + .then(resource => resource.blob()) + .then(blob => { + const mimeType = getFileMimeType(blob, linkHref) + const ext = mimeType.replace('file/', '') + const filename = `file.${ext}` + const file = createFileFromBlob(blob, filename, mimeType) - file ? resolve( file ) : reject(); - } ) - .catch( reject ); - } ); + file ? resolve(file) : reject() + }) + .catch(reject) + }) } /** * @param {module:engine/view/node~Node} node The node to check. * @returns {Boolean} */ -export function isLocalFile( node ) { - if ( !node.is( 'element', 'a' ) || !node.getAttribute( 'href' ) ) { - return false; - } +export function isLocalFile (node) { + if (!node.is('element', 'a') || !node.getAttribute('href')) { + return false + } - return node.getAttribute( 'href' ); + return node.getAttribute('href') } - -function getFileMimeType( blob, src ) { - if ( blob.type ) { - return blob.type; - } else if ( src.match( /data:(image\/\w+);base64/ ) ) { - return src.match( /data:(image\/\w+);base64/ )[ 1 ].toLowerCase(); - } else { - throw new Error('Could not retrieve mime type for file.'); - } +function getFileMimeType (blob, src) { + if (blob.type) { + return blob.type + } else if (src.match(/data:(image\/\w+);base64/)) { + return src.match(/data:(image\/\w+);base64/)[1].toLowerCase() + } else { + throw new Error('Could not retrieve mime type for file.') + } } // Creates a `File` instance from the given `Blob` instance using the specified file name. @@ -68,28 +67,26 @@ function getFileMimeType( blob, src ) { // @param {String} filename The file name used during the file creation. // @param {String} mimeType The file MIME type. // @returns {File|null} The `File` instance created from the given blob or `null` if `File API` is not available. -function createFileFromBlob( blob, filename, mimeType ) { - try { - return new File( [ blob ], filename, { type: mimeType } ); - } catch ( err ) { - // Edge does not support `File` constructor ATM, see https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/9551546/. - // However, the `File` function is present (so cannot be checked with `!window.File` or `typeof File === 'function'`), but - // calling it with `new File( ... )` throws an error. This try-catch prevents that. Also when the function will - // be implemented correctly in Edge the code will start working without any changes (see #247). - return null; - } +function createFileFromBlob (blob, filename, mimeType) { + try { + return new File([blob], filename, { type: mimeType }) + } catch (err) { + // Edge does not support `File` constructor ATM, see https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/9551546/. + // However, the `File` function is present (so cannot be checked with `!window.File` or `typeof File === 'function'`), but + // calling it with `new File( ... )` throws an error. This try-catch prevents that. Also when the function will + // be implemented correctly in Edge the code will start working without any changes (see #247). + return null + } } -export function insertFileLink( writer, model, attributes = {}, file ) { - const selection = model.document.selection; - const insertAtSelection = findOptimalInsertionRange( selection, model ); +export function insertFileLink (writer, model, attributes = {}, file) { + const selection = model.document.selection + const insertAtSelection = findOptimalInsertionRange(selection, model) - const linkedText = writer.createText(file.name, attributes); - model.insertContent(linkedText, insertAtSelection); + const linkedText = writer.createText(file.name, attributes) + model.insertContent(linkedText, insertAtSelection) - if ( linkedText.parent ) { - writer.setSelection( linkedText, 'on' ); - } + if (linkedText.parent) { + writer.setSelection(linkedText, 'on') + } } - - diff --git a/theme/progressbarview.js b/theme/progressbarview.js index 0ed2b25..3e1a8a6 100644 --- a/theme/progressbarview.js +++ b/theme/progressbarview.js @@ -1,68 +1,63 @@ -import View from "@ckeditor/ckeditor5-ui/src/view"; -import toUnit from '@ckeditor/ckeditor5-utils/src/dom/tounit'; -import ButtonView from "@ckeditor/ckeditor5-ui/src/button/buttonview"; +import { View, ButtonView, cancelIcon, toUnit } from 'ckeditor5' -import cancelIcon from '@ckeditor/ckeditor5-core/theme/icons/cancel.svg'; - -const toPx = toUnit( '%' ); +const toPx = toUnit('%') export default class ProgressBarView extends View { - constructor( locale ) { - super( locale ); - - const bind = this.bindTemplate; - this.cancelButton = this._createCancelButton(locale); - - // Views define their interface (state) using observable attributes. - this.set('width', 100); - this.set('customWidth', 0); - - - this.setTemplate( { - tag: 'div', - - // The element of the view can be defined with its children. - children: [ - { - tag: 'div', - children: [ 'Uploading...' ], - attributes: { - class: ['ck-uploading-progress'], - style: { - width: bind.to('customWidth', toPx), - } - } - }, - this.cancelButton, - ], - attributes: { - class: [ - 'ck-progress-bar', - - // Observable attributes control the state of the view in DOM. - bind.to( 'elementClass' ) - ], - style: { - width: bind.to('width', toPx), - } + constructor (locale) { + super(locale) + + const bind = this.bindTemplate + this.cancelButton = this._createCancelButton(locale) + + // Views define their interface (state) using observable attributes. + this.set('width', 100) + this.set('customWidth', 0) + + this.setTemplate({ + tag: 'div', + + // The element of the view can be defined with its children. + children: [ + { + tag: 'div', + children: ['Uploading...'], + attributes: { + class: ['ck-uploading-progress'], + style: { + width: bind.to('customWidth', toPx) } - } ); - } - - _createCancelButton(locale) { - const view = new ButtonView( locale ); - view.set( { - icon: cancelIcon, - tooltip: true, - label: 'Cancel', - attributes: { - class: ['ck', 'ck-button', 'ck-off', 'ck-button-cancel', 'ck-uploading-cancel'] - } - } ); - - view.on('execute', () => { - this.fire( 'cancel' ) - }); - return view; - } -} \ No newline at end of file + } + }, + this.cancelButton + ], + attributes: { + class: [ + 'ck-progress-bar', + + // Observable attributes control the state of the view in DOM. + bind.to('elementClass') + ], + style: { + width: bind.to('width', toPx) + } + } + }) + } + + _createCancelButton (locale) { + const view = new ButtonView(locale) + view.set({ + icon: cancelIcon, + tooltip: true, + label: 'Cancel', + attributes: { + class: ['ck', 'ck-button', 'ck-off', 'ck-button-cancel', 'ck-uploading-cancel'] + } + }) + + view.on('execute', () => { + this.fire('cancel') + }) + return view + } +}