@ckeditor/ckeditor5-ckbox 34.2.0
Sign up to get free protection for your applications and to get access to all the features.
- package/LICENSE.md +17 -0
- package/README.md +19 -0
- package/build/ckbox.js +5 -0
- package/ckeditor5-metadata.json +38 -0
- package/lang/contexts.json +4 -0
- package/lang/translations/en.po +25 -0
- package/package.json +58 -0
- package/src/ckbox.js +243 -0
- package/src/ckboxcommand.js +406 -0
- package/src/ckboxediting.js +466 -0
- package/src/ckboxui.js +62 -0
- package/src/ckboxuploadadapter.js +395 -0
- package/src/index.js +12 -0
- package/src/utils.js +134 -0
- package/theme/icons/browse-files.svg +1 -0
package/LICENSE.md
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
Software License Agreement
|
2
|
+
==========================
|
3
|
+
|
4
|
+
**CKEditor 5 CKBox feature** – https://github.com/ckeditor/ckeditor5-ckbox <br>
|
5
|
+
Copyright (c) 2003-2022, [CKSource Holding sp. z o.o.](http://cksource.com) All rights reserved.
|
6
|
+
|
7
|
+
Licensed under the terms of [GNU General Public License Version 2 or later](http://www.gnu.org/licenses/gpl.html).
|
8
|
+
|
9
|
+
Sources of Intellectual Property Included in CKEditor
|
10
|
+
-----------------------------------------------------
|
11
|
+
|
12
|
+
Where not otherwise indicated, all CKEditor content is authored by CKSource engineers and consists of CKSource-owned intellectual property. In some specific instances, CKEditor will incorporate work done by developers outside of CKSource with their express permission.
|
13
|
+
|
14
|
+
Trademarks
|
15
|
+
----------
|
16
|
+
|
17
|
+
**CKEditor** is a trademark of [CKSource Holding sp. z o.o.](http://cksource.com) All other brand and product names are trademarks, registered trademarks or service marks of their respective holders.
|
package/README.md
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
CKEditor 5 CKBox integration
|
2
|
+
=========================================
|
3
|
+
|
4
|
+
[![npm version](https://badge.fury.io/js/%40ckeditor%2Fckeditor5-ckbox.svg)](https://www.npmjs.com/package/@ckeditor/ckeditor5-ckbox)
|
5
|
+
[![Coverage Status](https://coveralls.io/repos/github/ckeditor/ckeditor5/badge.svg?branch=master)](https://coveralls.io/github/ckeditor/ckeditor5?branch=master)
|
6
|
+
[![Build Status](https://travis-ci.com/ckeditor/ckeditor5.svg?branch=master)](https://app.travis-ci.com/github/ckeditor/ckeditor5)
|
7
|
+
![Dependency Status](https://img.shields.io/librariesio/release/npm/@ckeditor/ckeditor5-ckbox)
|
8
|
+
|
9
|
+
This package implements the [CKBox feature](https://ckeditor.com/docs/ckeditor5/latest/features/ckbox.html). This feature allows you to easily insert images as well as links to files into the editor content. It is a bridge between CKEditor 5 WYSIWYG editor and CKBox file manager and uploader.
|
10
|
+
|
11
|
+
## Documentation
|
12
|
+
|
13
|
+
See the [CKBox integration guide](https://ckeditor.com/docs/ckeditor5/latest/features/ckbox.html) and the [plugin documentation](https://ckeditor.com/docs/ckeditor5/latest/api/ckbox.html) to learn more about the integration.
|
14
|
+
|
15
|
+
Check out the [comprehensive Image upload guide](https://ckeditor.com/docs/ckeditor5/latest/features/image-upload.html) to learn about other ways to upload images into CKEditor 5.
|
16
|
+
|
17
|
+
## License
|
18
|
+
|
19
|
+
Licensed under the terms of [GNU General Public License Version 2 or later](http://www.gnu.org/licenses/gpl.html). For full details about the license, please check the `LICENSE.md` file or [https://ckeditor.com/legal/ckeditor-oss-license](https://ckeditor.com/legal/ckeditor-oss-license).
|
package/build/ckbox.js
ADDED
@@ -0,0 +1,5 @@
|
|
1
|
+
!function(e){const t=e.en=e.en||{};t.dictionary=Object.assign(t.dictionary||{},{"Cannot determine a category for the uploaded file.":"Cannot determine a category for the uploaded file.","Open file manager":"Open file manager"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={})),
|
2
|
+
/*!
|
3
|
+
* @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
|
4
|
+
* For licensing, see LICENSE.md.
|
5
|
+
*/(()=>{var e={704:(e,t,i)=>{e.exports=i(79)("./src/core.js")},492:(e,t,i)=>{e.exports=i(79)("./src/engine.js")},273:(e,t,i)=>{e.exports=i(79)("./src/ui.js")},448:(e,t,i)=>{e.exports=i(79)("./src/upload.js")},209:(e,t,i)=>{e.exports=i(79)("./src/utils.js")},79:e=>{"use strict";e.exports=CKEditor5.dll}},t={};function i(n){var o=t[n];if(void 0!==o)return o.exports;var r=t[n]={exports:{}};return e[n](r,r.exports,i),r.exports}i.d=(e,t)=>{for(var n in t)i.o(t,n)&&!i.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},i.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),i.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var n={};(()=>{"use strict";i.r(n),i.d(n,{CKBox:()=>I,CKBoxEditing:()=>f,CKBoxUI:()=>o});var e=i(704),t=i(273);class o extends e.Plugin{static get pluginName(){return"CKBoxUI"}afterInit(){const e=this.editor;if(!e.commands.get("ckbox"))return;const i=e.t;e.ui.componentFactory.add("ckbox",(n=>{const o=e.commands.get("ckbox"),r=new t.ButtonView(n);return r.set({label:i("Open file manager"),icon:'<svg viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="M11.627 16.5zm5.873-.196zm0-7.001V8h-13v8.5h4.341c.191.54.457 1.044.785 1.5H2a1.5 1.5 0 0 1-1.5-1.5v-13A1.5 1.5 0 0 1 2 2h4.5a1.5 1.5 0 0 1 1.06.44L9.122 4H16a1.5 1.5 0 0 1 1.5 1.5v1A1.5 1.5 0 0 1 19 8v2.531a6.027 6.027 0 0 0-1.5-1.228zM16 6.5v-1H8.5l-2-2H2v13h1V8a1.5 1.5 0 0 1 1.5-1.5H16z"/><path d="M14.5 19.5a5 5 0 1 1 0-10 5 5 0 0 1 0 10zM15 14v-2h-1v2h-2v1h2v2h1v-2h2v-1h-2z"/></svg>',tooltip:!0}),r.bind("isOn","isEnabled").to(o,"value","isEnabled"),r.on("execute",(()=>{e.execute("ckbox")})),r}))}}var r=i(492),s=i(209);function a({token:e,id:t,origin:i,width:n,extension:o}){const r=c(e),s=function(e){const t=[10*e/100,80],i=Math.floor(Math.max(...t)),n=[Math.min(e,4e3)];let o=n[0];for(;o-i>=i;)o-=i,n.unshift(o);return n}(n),a=function(e){if("bmp"===e||"tiff"===e||"jpg"===e)return"jpeg";return e}(o);return{imageFallbackUrl:d({environmentId:r,id:t,origin:i,width:n,extension:a}),imageSources:[{srcset:s.map((e=>`${d({environmentId:r,id:t,origin:i,width:e,extension:"webp"})} ${e}w`)).join(","),sizes:`(max-width: ${n}px) 100vw, ${n}px`,type:"image/webp"}]}}function c(e){const[,t]=e.value.split(".");return JSON.parse(atob(t)).aud}function d({environmentId:e,id:t,origin:i,width:n,extension:o}){return new URL(`${e}/assets/${t}/images/${n}.${o}`,i).toString()}class l extends e.Command{constructor(e){super(e),this._chosenAssets=new Set,this._wrapper=null,this._initListeners()}refresh(){this.value=this._getValue(),this.isEnabled=this._checkEnabled()}execute(){this.fire("ckbox:open")}_getValue(){return null!==this._wrapper}_checkEnabled(){const e=this.editor.commands.get("insertImage"),t=this.editor.commands.get("link");return!(!e.isEnabled&&!t.isEnabled)}_prepareOptions(){const e=this.editor.config.get("ckbox");return{theme:e.theme,language:e.language,tokenUrl:e.tokenUrl,serviceOrigin:e.serviceOrigin,assetsOrigin:e.assetsOrigin,dialog:{onClose:()=>this.fire("ckbox:close")},assets:{onChoose:e=>this.fire("ckbox:choose",e)}}}_initListeners(){const e=this.editor,t=e.model,i=!e.config.get("ckbox.ignoreDataId");this.on("ckbox",(()=>{this.refresh()}),{priority:"low"}),this.on("ckbox:open",(()=>{this.isEnabled&&!this.value&&(this._wrapper=(0,s.createElement)(document,"div",{class:"ck ckbox-wrapper"}),document.body.appendChild(this._wrapper),window.CKBox.mount(this._wrapper,this._prepareOptions()))})),this.on("ckbox:close",(()=>{this.value&&(this._wrapper.remove(),this._wrapper=null)})),this.on("ckbox:choose",((n,o)=>{if(!this.isEnabled)return;const r=e.commands.get("insertImage"),s=e.commands.get("link"),a=e.plugins.get("CKBoxEditing"),c=function({assets:e,origin:t,token:i,isImageAllowed:n,isLinkAllowed:o}){return e.map((e=>({id:e.data.id,type:g(e)?"image":"link",attributes:u(e,i,t)}))).filter((e=>"image"===e.type?n:o))}({assets:o,origin:e.config.get("ckbox.assetsOrigin"),token:a.getToken(),isImageAllowed:r.isEnabled,isLinkAllowed:s.isEnabled});0!==c.length&&t.change((e=>{for(const t of c){const n=t===c[c.length-1];this._insertAsset(t,n,e),i&&(setTimeout((()=>this._chosenAssets.delete(t)),1e3),this._chosenAssets.add(t))}}))})),this.listenTo(e,"destroy",(()=>{this.fire("ckbox:close"),this._chosenAssets.clear()}))}_insertAsset(e,t,i){const n=this.editor.model.document.selection;i.removeSelectionAttribute("linkHref"),"image"===e.type?this._insertImage(e):this._insertLink(e,i),t||i.setSelection(n.getLastPosition())}_insertImage(e){const t=this.editor,{imageFallbackUrl:i,imageSources:n,imageTextAlternative:o}=e.attributes;t.execute("insertImage",{source:{src:i,sources:n,alt:o}})}_insertLink(e,t){const i=this.editor,n=i.model,o=n.document.selection,{linkName:r,linkHref:a}=e.attributes;if(o.isCollapsed){const e=(0,s.toMap)(o.getAttributes()),i=t.createText(r,e),a=n.insertContent(i);t.setSelection(a)}i.execute("link",a)}}function u(e,t,i){if(g(e)){const{imageFallbackUrl:n,imageSources:o}=a({token:t,origin:i,id:e.data.id,width:e.data.metadata.width,extension:e.data.extension});return{imageFallbackUrl:n,imageSources:o,imageTextAlternative:e.data.metadata.description||""}}return{linkName:e.data.name,linkHref:m(e,t,i)}}function g(e){const t=e.data.metadata;return!!t&&(t.width&&t.height)}function m(e,t,i){const n=c(t),o=new URL(`${n}/assets/${e.data.id}/file`,i);return o.searchParams.set("download","true"),o.toString()}var h=i(448);class b extends e.Plugin{static get requires(){return["ImageUploadEditing","ImageUploadProgress",h.FileRepository,f]}static get pluginName(){return"CKBoxUploadAdapter"}async afterInit(){const e=this.editor,t=!!e.config.get("ckbox"),i=!!window.CKBox;if(!t&&!i)return;const n=e.plugins.get(h.FileRepository),o=e.plugins.get(f);n.createUploadAdapter=t=>new p(t,o.getToken(),e);const r=!e.config.get("ckbox.ignoreDataId"),s=e.plugins.get("ImageUploadEditing");r&&s.on("uploadComplete",((t,{imageElement:i,data:n})=>{e.model.change((e=>{e.setAttribute("ckboxImageId",n.ckboxImageId,i)}))}))}}class p{constructor(e,t,i){this.loader=e,this.token=t,this.editor=i,this.controller=new AbortController,this.serviceOrigin=i.config.get("ckbox.serviceOrigin"),this.assetsOrigin=i.config.get("ckbox.assetsOrigin")}async getAvailableCategories(e=0){const t=new URL("categories",this.serviceOrigin);return t.searchParams.set("limit",50..toString()),t.searchParams.set("offset",e.toString()),this._sendHttpRequest({url:t}).then((async t=>{if(t.totalCount-(e+50)>0){const i=await this.getAvailableCategories(e+50);return[...t.items,...i]}return t.items})).catch((()=>{this.controller.signal.throwIfAborted(),(0,s.logError)("ckbox-fetch-category-http-error")}))}async getCategoryIdForFile(e){const t=k(e.name),i=await this.getAvailableCategories();if(!i)return null;const n=this.editor.config.get("ckbox.defaultUploadCategories");if(n){const e=Object.keys(n).find((e=>n[e].includes(t)));if(e){const t=i.find((t=>t.id===e||t.name===e));return t?t.id:null}}const o=i.find((e=>e.extensions.includes(t)));return o?o.id:null}async upload(){const e=this.editor.t,t=e("Cannot determine a category for the uploaded file."),i=await this.loader.file,n=await this.getCategoryIdForFile(i);if(!n)return Promise.reject(t);const o=new URL("assets",this.serviceOrigin),r=new FormData;r.append("categoryId",n),r.append("file",i);const s={method:"POST",url:o,data:r,onUploadProgress:e=>{e.lengthComputable&&(this.loader.uploadTotal=e.total,this.loader.uploaded=e.loaded)}};return this._sendHttpRequest(s).then((async e=>{const t=await this._getImageWidth(),n=k(i.name),o=a({token:this.token,id:e.id,origin:this.assetsOrigin,width:t,extension:n});return{ckboxImageId:e.id,default:o.imageFallbackUrl,sources:o.imageSources}})).catch((()=>{const t=e("Cannot upload file:")+` ${i.name}.`;return Promise.reject(t)}))}abort(){this.controller.abort()}_sendHttpRequest(e){const{url:t,data:i,onUploadProgress:n}=e,o=e.method||"GET",r=this.controller.signal,s=new XMLHttpRequest;s.open(o,t.toString(),!0),s.setRequestHeader("Authorization",this.token.value),s.setRequestHeader("CKBox-Version","CKEditor 5"),s.responseType="json";const a=()=>{s.abort()};return new Promise(((e,t)=>{r.addEventListener("abort",a),s.addEventListener("loadstart",(()=>{r.addEventListener("abort",a)})),s.addEventListener("loadend",(()=>{r.removeEventListener("abort",a)})),s.addEventListener("error",(()=>{t()})),s.addEventListener("abort",(()=>{t()})),s.addEventListener("load",(async()=>{const i=s.response;return!i||i.statusCode>=400?t(i&&i.message):e(i)})),n&&s.upload.addEventListener("progress",(e=>{n(e)})),s.send(i)}))}_getImageWidth(){return new Promise((e=>{const t=new Image;t.onload=()=>{URL.revokeObjectURL(t.src),e(t.width)},t.src=this.loader.data}))}}function k(e){return e.match(/\.(?<ext>[^.]+)$/).groups.ext}class f extends e.Plugin{static get pluginName(){return"CKBoxEditing"}static get requires(){return["CloudServicesCore","LinkEditing","PictureEditing",b]}async init(){const e=this.editor,t=!!e.config.get("ckbox"),i=!!window.CKBox;if(!t&&!i)return;this._initConfig();const n=e.plugins.get("CloudServicesCore"),o=e.config.get("ckbox.tokenUrl"),r=e.config.get("cloudServices.tokenUrl");this._token=o===r?e.plugins.get("CloudServices").token:await n.createToken(o).init(),e.config.get("ckbox.ignoreDataId")||(this._initSchema(),this._initConversion(),this._initFixers()),i&&e.commands.add("ckbox",new l(e))}getToken(){return this._token}_initConfig(){const e=this.editor;e.config.define("ckbox",{serviceOrigin:"https://api.ckbox.io",assetsOrigin:"https://ckbox.cloud",defaultUploadCategories:null,ignoreDataId:!1,language:e.locale.uiLanguage,theme:"default",tokenUrl:e.config.get("cloudServices.tokenUrl")});if(!e.config.get("ckbox.tokenUrl"))throw new s.CKEditorError("ckbox-plugin-missing-token-url",this);e.plugins.has("ImageBlockEditing")||e.plugins.has("ImageInlineEditing")||(0,s.logError)("ckbox-plugin-image-feature-missing",e)}_initSchema(){const e=this.editor.model.schema;e.extend("$text",{allowAttributes:"ckboxLinkId"}),e.isRegistered("imageBlock")&&e.extend("imageBlock",{allowAttributes:["ckboxImageId","ckboxLinkId"]}),e.isRegistered("imageInline")&&e.extend("imageInline",{allowAttributes:["ckboxImageId","ckboxLinkId"]}),e.addAttributeCheck(((e,t)=>{if(!!!e.last.getAttribute("linkHref")&&"ckboxLinkId"===t)return!1}))}_initConversion(){const e=this.editor;e.conversion.for("downcast").add((e=>{e.on("attribute:ckboxLinkId:imageBlock",((e,t,i)=>{const{writer:n,mapper:o,consumable:r}=i;if(!r.consume(t.item,e.name))return;const s=[...o.toViewElement(t.item).getChildren()].find((e=>"a"===e.name));s&&(t.item.hasAttribute("ckboxLinkId")?n.setAttribute("data-ckbox-resource-id",t.item.getAttribute("ckboxLinkId"),s):n.removeAttribute("data-ckbox-resource-id",s))}),{priority:"low"}),e.on("attribute:ckboxLinkId",((e,t,i)=>{const{writer:n,mapper:o,consumable:r}=i;if(r.consume(t.item,e.name)){if(t.attributeOldValue){const e=w(n,t.attributeOldValue);n.unwrap(o.toViewRange(t.range),e)}if(t.attributeNewValue){const e=w(n,t.attributeNewValue);if(t.item.is("selection")){const t=n.document.selection;n.wrap(t.getFirstRange(),e)}else n.wrap(o.toViewRange(t.range),e)}}}),{priority:"low"})})),e.conversion.for("upcast").add((e=>{e.on("element:a",((e,t,i)=>{const{writer:n,consumable:o}=i;if(!t.viewItem.getAttribute("href"))return;if(!o.consume(t.viewItem,{attributes:["data-ckbox-resource-id"]}))return;const r=t.viewItem.getAttribute("data-ckbox-resource-id");if(r)if(t.modelRange)for(let e of t.modelRange.getItems())e.is("$textProxy")&&(e=e.textNode),v(e)&&n.setAttribute("ckboxLinkId",r,e);else{const e=t.modelCursor.nodeBefore||t.modelCursor.parent;n.setAttribute("ckboxLinkId",r,e)}}),{priority:"low"})})),e.conversion.for("downcast").attributeToAttribute({model:"ckboxImageId",view:"data-ckbox-resource-id"}),e.conversion.for("upcast").elementToAttribute({model:{key:"ckboxImageId",value:e=>e.getAttribute("data-ckbox-resource-id")},view:{attributes:{"data-ckbox-resource-id":/[\s\S]+/}}})}_initFixers(){const e=this.editor,t=e.model,i=t.document.selection;t.document.registerPostFixer(function(e){return t=>{let i=!1;const n=e.model,o=e.commands.get("ckbox");if(!o)return i;for(const e of n.document.differ.getChanges()){if("insert"!==e.type&&"attribute"!==e.type)continue;const n="insert"===e.type?new r.Range(e.position,e.position.getShiftedBy(e.length)):e.range,s="attribute"===e.type&&"linkHref"===e.attributeKey&&null===e.attributeNewValue;for(const e of n.getItems()){if(s&&e.hasAttribute("ckboxLinkId")){t.removeAttribute("ckboxLinkId",e),i=!0;continue}const n=x(e,o._chosenAssets);for(const o of n){const n="image"===o.type?"ckboxImageId":"ckboxLinkId";o.id!==e.getAttribute(n)&&(t.setAttribute(n,o.id,e),i=!0)}}}return i}}(e)),t.document.registerPostFixer(function(e){return t=>{!e.hasAttribute("linkHref")&&e.hasAttribute("ckboxLinkId")&&t.removeSelectionAttribute("ckboxLinkId")}}(i))}}function x(e,t){const i=e.is("element","imageInline")||e.is("element","imageBlock"),n=e.hasAttribute("linkHref");return[...t].filter((t=>"image"===t.type&&i?t.attributes.imageFallbackUrl===e.getAttribute("src"):"link"===t.type&&n?t.attributes.linkHref===e.getAttribute("linkHref"):void 0))}function w(e,t){const i=e.createAttributeElement("a",{"data-ckbox-resource-id":t},{priority:5});return e.setCustomProperty("link",!0,i),i}function v(e){return!!e.is("$text")||!(!e.is("element","imageInline")&&!e.is("element","imageBlock"))}class I extends e.Plugin{static get pluginName(){return"CKBox"}static get requires(){return[f,o]}}})(),(window.CKEditor5=window.CKEditor5||{}).ckbox=n})();
|
@@ -0,0 +1,38 @@
|
|
1
|
+
{
|
2
|
+
"plugins": [
|
3
|
+
{
|
4
|
+
"name": "CKBox",
|
5
|
+
"className": "CKBox",
|
6
|
+
"description": "Allows inserting images as well as links to files into the rich-text editor content.",
|
7
|
+
"docs": "features/images/image-upload/ckbox.html",
|
8
|
+
"path": "src/ckbox.js",
|
9
|
+
"requires": [
|
10
|
+
"CloudServices",
|
11
|
+
"Link",
|
12
|
+
"Image",
|
13
|
+
"ImageUpload",
|
14
|
+
"PictureEditing"
|
15
|
+
],
|
16
|
+
"uiComponents": [
|
17
|
+
{
|
18
|
+
"name": "ckbox",
|
19
|
+
"type": "Button",
|
20
|
+
"iconPath": "theme/icons/browse-files.svg"
|
21
|
+
}
|
22
|
+
],
|
23
|
+
"htmlOutput": [
|
24
|
+
{
|
25
|
+
"elements": [
|
26
|
+
"a",
|
27
|
+
"figure",
|
28
|
+
"img"
|
29
|
+
],
|
30
|
+
"attributes": [
|
31
|
+
"data-ckbox-resource-id"
|
32
|
+
],
|
33
|
+
"_comment": "If `config.ckbox.ignoreDataId` is set to false (off), the asset ID as the `data-ckbox-resource-id` attribute is added on the inserted elements (by default)."
|
34
|
+
}
|
35
|
+
]
|
36
|
+
}
|
37
|
+
]
|
38
|
+
}
|
@@ -0,0 +1,4 @@
|
|
1
|
+
{
|
2
|
+
"Open file manager": "Toolbar button tooltip for opening a file browser that allows inserting an image or a file to the editor.",
|
3
|
+
"Cannot determine a category for the uploaded file.": "A message is displayed when CKEditor 5 cannot associate an image with any of the categories defined in CKBox while uploading an asset."
|
4
|
+
}
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
|
2
|
+
#
|
3
|
+
# !!! IMPORTANT !!!
|
4
|
+
#
|
5
|
+
# Before you edit this file, please keep in mind that contributing to the project
|
6
|
+
# translations is possible ONLY via the Transifex online service.
|
7
|
+
#
|
8
|
+
# To submit your translations, visit https://www.transifex.com/ckeditor/ckeditor5.
|
9
|
+
#
|
10
|
+
# To learn more, check out the official contributor's guide:
|
11
|
+
# https://ckeditor.com/docs/ckeditor5/latest/framework/guides/contributing/contributing.html
|
12
|
+
#
|
13
|
+
msgid ""
|
14
|
+
msgstr ""
|
15
|
+
"Language: \n"
|
16
|
+
"Language-Team: \n"
|
17
|
+
"Plural-Forms: \n"
|
18
|
+
|
19
|
+
msgctxt "Toolbar button tooltip for opening a file browser that allows inserting an image or a file to the editor."
|
20
|
+
msgid "Open file manager"
|
21
|
+
msgstr "Open file manager"
|
22
|
+
|
23
|
+
msgctxt "A message is displayed when CKEditor 5 cannot associate an image with any of the categories defined in CKBox while uploading an asset."
|
24
|
+
msgid "Cannot determine a category for the uploaded file."
|
25
|
+
msgstr "Cannot determine a category for the uploaded file."
|
package/package.json
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
{
|
2
|
+
"name": "@ckeditor/ckeditor5-ckbox",
|
3
|
+
"version": "34.2.0",
|
4
|
+
"description": "CKBox integration for CKEditor 5.",
|
5
|
+
"keywords": [
|
6
|
+
"ckeditor",
|
7
|
+
"ckeditor5",
|
8
|
+
"ckeditor 5",
|
9
|
+
"ckeditor5-feature",
|
10
|
+
"ckeditor5-plugin",
|
11
|
+
"ckeditor5-dll"
|
12
|
+
],
|
13
|
+
"main": "src/index.js",
|
14
|
+
"dependencies": {
|
15
|
+
"ckeditor5": "^34.2.0"
|
16
|
+
},
|
17
|
+
"devDependencies": {
|
18
|
+
"@ckeditor/ckeditor5-basic-styles": "^34.2.0",
|
19
|
+
"@ckeditor/ckeditor5-core": "^34.2.0",
|
20
|
+
"@ckeditor/ckeditor5-clipboard": "^34.2.0",
|
21
|
+
"@ckeditor/ckeditor5-cloud-services": "^34.2.0",
|
22
|
+
"@ckeditor/ckeditor5-dev-utils": "^30.1.0",
|
23
|
+
"@ckeditor/ckeditor5-editor-classic": "^34.2.0",
|
24
|
+
"@ckeditor/ckeditor5-engine": "^34.2.0",
|
25
|
+
"@ckeditor/ckeditor5-image": "^34.2.0",
|
26
|
+
"@ckeditor/ckeditor5-link": "^34.2.0",
|
27
|
+
"@ckeditor/ckeditor5-paragraph": "^34.2.0",
|
28
|
+
"@ckeditor/ckeditor5-theme-lark": "^34.2.0",
|
29
|
+
"@ckeditor/ckeditor5-ui": "^34.2.0",
|
30
|
+
"@ckeditor/ckeditor5-upload": "^34.2.0",
|
31
|
+
"@ckeditor/ckeditor5-utils": "^34.2.0",
|
32
|
+
"webpack": "^5.58.1",
|
33
|
+
"webpack-cli": "^4.9.0"
|
34
|
+
},
|
35
|
+
"engines": {
|
36
|
+
"node": ">=14.0.0",
|
37
|
+
"npm": ">=5.7.1"
|
38
|
+
},
|
39
|
+
"author": "CKSource (http://cksource.com/)",
|
40
|
+
"license": "GPL-2.0-or-later",
|
41
|
+
"homepage": "https://ckeditor.com/ckeditor-5",
|
42
|
+
"bugs": "https://github.com/ckeditor/ckeditor5/issues",
|
43
|
+
"repository": {
|
44
|
+
"type": "git",
|
45
|
+
"url": "https://github.com/ckeditor/ckeditor5.git",
|
46
|
+
"directory": "packages/ckeditor5-ckbox"
|
47
|
+
},
|
48
|
+
"files": [
|
49
|
+
"lang",
|
50
|
+
"src",
|
51
|
+
"theme",
|
52
|
+
"build",
|
53
|
+
"ckeditor5-metadata.json"
|
54
|
+
],
|
55
|
+
"scripts": {
|
56
|
+
"dll:build": "webpack"
|
57
|
+
}
|
58
|
+
}
|
package/src/ckbox.js
ADDED
@@ -0,0 +1,243 @@
|
|
1
|
+
/**
|
2
|
+
* @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
|
3
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
4
|
+
*/
|
5
|
+
|
6
|
+
/**
|
7
|
+
* @module ckbox/ckbox
|
8
|
+
*/
|
9
|
+
|
10
|
+
import { Plugin } from 'ckeditor5/src/core';
|
11
|
+
|
12
|
+
import CKBoxUI from './ckboxui';
|
13
|
+
import CKBoxEditing from './ckboxediting';
|
14
|
+
|
15
|
+
/**
|
16
|
+
* The CKBox feature, a bridge between the CKEditor 5 WYSIWYG editor and the CKBox file manager and uploader.
|
17
|
+
*
|
18
|
+
* This is a "glue" plugin which enables:
|
19
|
+
*
|
20
|
+
* * {@link module:ckbox/ckboxediting~CKBoxEditing},
|
21
|
+
* * {@link module:ckbox/ckboxui~CKBoxUI},
|
22
|
+
*
|
23
|
+
* See the {@glink features/images/image-upload/ckbox CKBox integration} guide to learn how to configure and use this feature.
|
24
|
+
*
|
25
|
+
* Check out the {@glink features/images/image-upload/image-upload Image upload} guide to learn about other ways to upload
|
26
|
+
* images into CKEditor 5.
|
27
|
+
*
|
28
|
+
* @extends module:core/plugin~Plugin
|
29
|
+
*/
|
30
|
+
export default class CKBox extends Plugin {
|
31
|
+
/**
|
32
|
+
* @inheritDoc
|
33
|
+
*/
|
34
|
+
static get pluginName() {
|
35
|
+
return 'CKBox';
|
36
|
+
}
|
37
|
+
|
38
|
+
/**
|
39
|
+
* @inheritDoc
|
40
|
+
*/
|
41
|
+
static get requires() {
|
42
|
+
return [ CKBoxEditing, CKBoxUI ];
|
43
|
+
}
|
44
|
+
}
|
45
|
+
|
46
|
+
/**
|
47
|
+
* The configuration of the {@link module:ckbox/ckbox~CKBox CKBox feature}.
|
48
|
+
*
|
49
|
+
* Read more in {@link module:ckbox/ckbox~CKBoxConfig}.
|
50
|
+
*
|
51
|
+
* @member {module:ckbox/ckbox~CKBoxConfig} module:core/editor/editorconfig~EditorConfig#ckbox
|
52
|
+
*/
|
53
|
+
|
54
|
+
/**
|
55
|
+
* The configuration of the {@link module:ckbox/ckbox~CKBox CKBox feature}.
|
56
|
+
*
|
57
|
+
* The minimal configuration for the CKBox feature requires providing the
|
58
|
+
* {@link module:ckbox/ckbox~CKBoxConfig#tokenUrl `config.ckbox.tokenUrl`}:
|
59
|
+
*
|
60
|
+
* ClassicEditor
|
61
|
+
* .create( editorElement, {
|
62
|
+
* ckbox: {
|
63
|
+
* tokenUrl: 'https://example.com/cs-token-endpoint'
|
64
|
+
* }
|
65
|
+
* } )
|
66
|
+
* .then( ... )
|
67
|
+
* .catch( ... );
|
68
|
+
*
|
69
|
+
* Hovewer, you can also adjust the feature to fit your needs:
|
70
|
+
*
|
71
|
+
* ClassicEditor
|
72
|
+
* .create( editorElement, {
|
73
|
+
* ckbox: {
|
74
|
+
* defaultUploadCategories: {
|
75
|
+
* Bitmaps: [ 'bmp' ],
|
76
|
+
* Pictures: [ 'jpg', 'jpeg' ],
|
77
|
+
* Scans: [ 'png', 'tiff' ]
|
78
|
+
* },
|
79
|
+
* ignoreDataId: true,
|
80
|
+
* serviceOrigin: 'https://example.com/',
|
81
|
+
* assetsOrigin: 'https://example.cloud/',
|
82
|
+
* tokenUrl: 'https://example.com/cs-token-endpoint'
|
83
|
+
* }
|
84
|
+
* } )
|
85
|
+
* .then( ... )
|
86
|
+
* .catch( ... );
|
87
|
+
*
|
88
|
+
* See {@link module:core/editor/editorconfig~EditorConfig all editor options}.
|
89
|
+
*
|
90
|
+
* @interface CKBoxConfig
|
91
|
+
*/
|
92
|
+
|
93
|
+
/**
|
94
|
+
* The authentication token URL for CKBox feature.
|
95
|
+
*
|
96
|
+
* Defaults to {@link module:cloud-services/cloudservices~CloudServicesConfig#tokenUrl `config.cloudServices.tokenUrl`}
|
97
|
+
*
|
98
|
+
* @member {String} module:ckbox/ckbox~CKBoxConfig#tokenUrl
|
99
|
+
*/
|
100
|
+
|
101
|
+
/**
|
102
|
+
* Defines the categories to which the uploaded images will be assigned. If configured, it overrides the category mappings defined on the
|
103
|
+
* cloud service. The value of this option should be an object, where the keys define categories and their values are the types of images
|
104
|
+
* that will be uploaded to these categories. The categories might be referenced by their name or ID.
|
105
|
+
*
|
106
|
+
* Example:
|
107
|
+
*
|
108
|
+
* const ckboxConfig = {
|
109
|
+
* defaultUploadCategories: {
|
110
|
+
* Bitmaps: [ 'bmp' ],
|
111
|
+
* Pictures: [ 'jpg', 'jpeg' ],
|
112
|
+
* Scans: [ 'png', 'tiff' ],
|
113
|
+
* // The category below is referenced by its ID.
|
114
|
+
* 'fdf2a647-b67f-4a6c-b692-5ba1dc1ed87b': [ 'gif' ]
|
115
|
+
* }
|
116
|
+
* };
|
117
|
+
*
|
118
|
+
* @default null
|
119
|
+
* @member {Object} [module:ckbox/ckbox~CKBoxConfig#defaultUploadCategories]
|
120
|
+
*/
|
121
|
+
|
122
|
+
/**
|
123
|
+
* Inserts the unique asset ID as the `data-ckbox-resource-id` attribute. To disable this behavior, set it to `true`.
|
124
|
+
*
|
125
|
+
* @default false
|
126
|
+
* @member {Boolean} [module:ckbox/ckbox~CKBoxConfig#ignoreDataId]
|
127
|
+
*/
|
128
|
+
|
129
|
+
/**
|
130
|
+
* Configures the base URL of the API service. Required only in on-premises installations.
|
131
|
+
*
|
132
|
+
* @default 'https://api.ckbox.io'
|
133
|
+
* @member {String} [module:ckbox/ckbox~CKBoxConfig#serviceOrigin]
|
134
|
+
*/
|
135
|
+
|
136
|
+
/**
|
137
|
+
* Configures the base URL for assets inserted into the editor. Required only in on-premises installations.
|
138
|
+
*
|
139
|
+
* @default 'https://ckbox.cloud'
|
140
|
+
* @member {String} [module:ckbox/ckbox~CKBoxConfig#assetsOrigin]
|
141
|
+
*/
|
142
|
+
|
143
|
+
/**
|
144
|
+
* Configures the language for the CKBox dialog.
|
145
|
+
*
|
146
|
+
* Defaults to {@link module:utils/locale~Locale#uiLanguage `Locale#uiLanguage`}
|
147
|
+
*
|
148
|
+
* @member {String} [module:ckbox/ckbox~CKBoxConfig#language]
|
149
|
+
*/
|
150
|
+
|
151
|
+
/**
|
152
|
+
* Asset definition.
|
153
|
+
*
|
154
|
+
* The definition contains the unique `id`, asset `type` and an `attributes` definition.
|
155
|
+
*
|
156
|
+
* @typedef {Object} module:ckbox/ckbox~CKBoxAssetDefinition
|
157
|
+
*
|
158
|
+
* @property {String} id An unique asset id.
|
159
|
+
* @property {'image'|'link'} type Asset type.
|
160
|
+
* @property {module:ckbox/ckbox~CKBoxAssetImageAttributesDefinition|
|
161
|
+
* module:ckbox/ckbox~CKBoxAssetLinkAttributesDefinition} attributes Asset attributes.
|
162
|
+
*/
|
163
|
+
|
164
|
+
/**
|
165
|
+
* Asset attributes definition for an image.
|
166
|
+
*
|
167
|
+
* The definition contains the `imageFallbackUrl`, an `imageSources` array with one image source definition object and the
|
168
|
+
* `imageTextAlternative`.
|
169
|
+
*
|
170
|
+
* {
|
171
|
+
* imageFallbackUrl: 'https://example.com/assets/asset-id/images/1000.png',
|
172
|
+
* imageSources: [
|
173
|
+
* {
|
174
|
+
* sizes: '1000px',
|
175
|
+
* srcset:
|
176
|
+
* 'https://example.com/assets/asset-id/images/100.webp 100w,' +
|
177
|
+
* 'https://example.com/assets/asset-id/images/200.webp 200w,' +
|
178
|
+
* 'https://example.com/assets/asset-id/images/300.webp 300w,' +
|
179
|
+
* 'https://example.com/assets/asset-id/images/400.webp 400w,' +
|
180
|
+
* 'https://example.com/assets/asset-id/images/500.webp 500w,' +
|
181
|
+
* 'https://example.com/assets/asset-id/images/600.webp 600w,' +
|
182
|
+
* 'https://example.com/assets/asset-id/images/700.webp 700w,' +
|
183
|
+
* 'https://example.com/assets/asset-id/images/800.webp 800w,' +
|
184
|
+
* 'https://example.com/assets/asset-id/images/900.webp 900w,' +
|
185
|
+
* 'https://example.com/assets/asset-id/images/1000.webp 1000w',
|
186
|
+
* type: 'image/webp'
|
187
|
+
* }
|
188
|
+
* ],
|
189
|
+
* imageTextAlternative: 'An alternative text for the image'
|
190
|
+
* }
|
191
|
+
*
|
192
|
+
* @typedef {Object} module:ckbox/ckbox~CKBoxAssetImageAttributesDefinition
|
193
|
+
*
|
194
|
+
* @property {String} imageFallbackUrl A fallback URL for browsers that do not support the "webp" format.
|
195
|
+
* @property {Array.<Object>} imageSources An array containing one image source definition object.
|
196
|
+
* @property {String} imageTextAlternative An alternative text for an image.
|
197
|
+
*/
|
198
|
+
|
199
|
+
/**
|
200
|
+
* Asset attributes definition for a link.
|
201
|
+
*
|
202
|
+
* The definition contains the `linkName` and `linkHref` strings.
|
203
|
+
*
|
204
|
+
* {
|
205
|
+
* linkName: 'File name',
|
206
|
+
* linkHref: 'https://example.com/assets/asset-id/file.pdf'
|
207
|
+
* }
|
208
|
+
*
|
209
|
+
* @typedef {Object} module:ckbox/ckbox~CKBoxAssetLinkAttributesDefinition
|
210
|
+
*
|
211
|
+
* @property {String} linkName A link name.
|
212
|
+
* @property {String} linkHref An URL for the asset.
|
213
|
+
*/
|
214
|
+
|
215
|
+
/**
|
216
|
+
* Raw asset definition that is received from the CKBox feature.
|
217
|
+
*
|
218
|
+
* @typedef {Object} module:ckbox/ckbox~CKBoxRawAssetDefinition
|
219
|
+
*
|
220
|
+
* @property {module:ckbox/ckbox~CKBoxRawAssetDataDefinition} data A raw asset data definition.
|
221
|
+
* @property {String} origin An asset origin URL.
|
222
|
+
*/
|
223
|
+
|
224
|
+
/**
|
225
|
+
* Part of raw asset data that is received from the CKBox feature.
|
226
|
+
*
|
227
|
+
* @typedef {Object} module:ckbox/ckbox~CKBoxRawAssetDataDefinition
|
228
|
+
*
|
229
|
+
* @property {String} id An unique asset id.
|
230
|
+
* @property {String} extension An asset extension.
|
231
|
+
* @property {String} name An asset name.
|
232
|
+
* @property {module:ckbox/ckbox~CKBoxRawAssetMetadataDefinition} metadata A raw asset metadata definition.
|
233
|
+
*/
|
234
|
+
|
235
|
+
/**
|
236
|
+
* Part of raw asset data that is received from the CKBox feature. Properties are set only if the chosen asset is an image.
|
237
|
+
*
|
238
|
+
* @typedef {Object} module:ckbox/ckbox~CKBoxRawAssetMetadataDefinition
|
239
|
+
*
|
240
|
+
* @property {String} [description] Image description.
|
241
|
+
* @property {Number} [width] Image width.
|
242
|
+
* @property {Number} [height] Image height.
|
243
|
+
*/
|