@ckeditor/ckeditor5-ckbox 36.0.0 → 37.0.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/ckbox.js +1 -1
- package/ckeditor5-metadata.json +1 -1
- package/package.json +24 -19
- package/src/ckbox.d.ts +36 -0
- package/src/ckbox.js +12 -218
- package/src/ckboxcommand.d.ts +114 -0
- package/src/ckboxcommand.js +278 -371
- package/src/ckboxconfig.d.ts +282 -0
- package/src/ckboxconfig.js +5 -0
- package/src/ckboxediting.d.ts +56 -0
- package/src/ckboxediting.js +343 -446
- package/src/ckboxui.d.ts +21 -0
- package/src/ckboxui.js +32 -47
- package/src/ckboxuploadadapter.d.ts +37 -0
- package/src/ckboxuploadadapter.js +248 -365
- package/src/index.d.ts +10 -0
- package/src/index.js +0 -2
- package/src/utils.d.ts +31 -0
- package/src/utils.js +70 -114
package/build/ckbox.js
CHANGED
@@ -2,4 +2,4 @@
|
|
2
2
|
/*!
|
3
3
|
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
4
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["CloudServices","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})();
|
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:()=>C,CKBoxEditing:()=>v,CKBoxUI:()=>o});var e=i(704),t=i(273);class o extends e.Plugin{static get pluginName(){return"CKBoxUI"}afterInit(){const e=this.editor,i=e.commands.get("ckbox");if(!i)return;const n=e.t;e.ui.componentFactory.add("ckbox",(o=>{const r=new t.ButtonView(o);return r.set({label:n("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(i,"value","isEnabled"),r.on("execute",(()=>{e.execute("ckbox")})),r}))}}var r=i(492),s=i(209);const a=4e3,c=80,d=10;function l({token:e,id:t,origin:i,width:n,extension:o}){const r=u(e),s=function(e){const t=[e*d/100,c],i=Math.floor(Math.max(...t)),n=[Math.min(e,a)];let o=n[0];for(;o-i>=i;)o-=i,n.unshift(o);return n}(n),l=function(e){if("bmp"===e||"tiff"===e||"jpg"===e)return"jpeg";return e}(o);return{imageFallbackUrl:g({environmentId:r,id:t,origin:i,width:n,extension:l}),imageSources:[{srcset:s.map((e=>`${g({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 u(e){const[,t]=e.value.split(".");return JSON.parse(atob(t)).aud}function g({environmentId:e,id:t,origin:i,width:n,extension:o}){return new URL(`${e}/assets/${t}/images/${n}.${o}`,i).toString()}class m 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=>function(e){const t=e.data.metadata;if(!t)return!1;return t.width&&t.height}(e)?{id:e.data.id,type:"image",attributes:h(e,i,t)}:{id:e.data.id,type:"link",attributes:b(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 h(e,t,i){const{imageFallbackUrl:n,imageSources:o}=l({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||""}}function b(e,t,i){return{linkName:e.data.name,linkHref:p(e,t,i)}}function p(e,t,i){const n=u(t),o=new URL(`${n}/assets/${e.data.id}/file`,i);return o.searchParams.set("download","true"),o.toString()}var k=i(448);class f extends e.Plugin{static get requires(){return["ImageUploadEditing","ImageUploadProgress",k.FileRepository,v]}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(k.FileRepository),o=e.plugins.get(v);n.createUploadAdapter=t=>new x(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 x{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=w(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=w(i.name),o=l({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({url:e,method:t="GET",data:i,onUploadProgress:n}){const o=this.controller.signal,r=new XMLHttpRequest;r.open(t,e.toString(),!0),r.setRequestHeader("Authorization",this.token.value),r.setRequestHeader("CKBox-Version","CKEditor 5"),r.responseType="json";const s=()=>{r.abort()};return new Promise(((e,t)=>{o.addEventListener("abort",s),r.addEventListener("loadstart",(()=>{o.addEventListener("abort",s)})),r.addEventListener("loadend",(()=>{o.removeEventListener("abort",s)})),r.addEventListener("error",(()=>{t()})),r.addEventListener("abort",(()=>{t()})),r.addEventListener("load",(async()=>{const i=r.response;return!i||i.statusCode>=400?t(i&&i.message):e(i)})),n&&r.upload.addEventListener("progress",(e=>{n(e)})),r.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 w(e){return e.match(/\.(?<ext>[^.]+)$/).groups.ext}class v extends e.Plugin{static get pluginName(){return"CKBoxEditing"}static get requires(){return["CloudServices","LinkEditing","PictureEditing",f]}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");if(o===e.config.get("cloudServices.tokenUrl")){const t=e.plugins.get("CloudServices");this._token=t.token}else this._token=await n.createToken(o).init();e.config.get("ckbox.ignoreDataId")||(this._initSchema(),this._initConversion(),this._initFixers()),i&&e.commands.add("ckbox",new m(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=A(n,t.attributeOldValue);n.unwrap(o.toViewRange(t.range),e)}if(t.attributeNewValue){const e=A(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),y(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=I(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"),!0)}(i))}}function I(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 A(e,t){const i=e.createAttributeElement("a",{"data-ckbox-resource-id":t},{priority:5});return e.setCustomProperty("link",!0,i),i}function y(e){return!!e.is("$text")||!(!e.is("element","imageInline")&&!e.is("element","imageBlock"))}class C extends e.Plugin{static get pluginName(){return"CKBox"}static get requires(){return[v,o]}}})(),(window.CKEditor5=window.CKEditor5||{}).ckbox=n})();
|
package/ckeditor5-metadata.json
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
"name": "CKBox",
|
5
5
|
"className": "CKBox",
|
6
6
|
"description": "Allows inserting images as well as links to files into the rich-text editor content.",
|
7
|
-
"docs": "features/
|
7
|
+
"docs": "features/file-management/ckbox.html",
|
8
8
|
"path": "src/ckbox.js",
|
9
9
|
"requires": [
|
10
10
|
"CloudServices",
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@ckeditor/ckeditor5-ckbox",
|
3
|
-
"version": "
|
3
|
+
"version": "37.0.0-alpha.0",
|
4
4
|
"description": "CKBox integration for CKEditor 5.",
|
5
5
|
"keywords": [
|
6
6
|
"ckeditor",
|
@@ -12,23 +12,24 @@
|
|
12
12
|
],
|
13
13
|
"main": "src/index.js",
|
14
14
|
"dependencies": {
|
15
|
-
"ckeditor5": "^
|
15
|
+
"ckeditor5": "^37.0.0-alpha.0"
|
16
16
|
},
|
17
17
|
"devDependencies": {
|
18
|
-
"@ckeditor/ckeditor5-basic-styles": "^
|
19
|
-
"@ckeditor/ckeditor5-core": "^
|
20
|
-
"@ckeditor/ckeditor5-clipboard": "^
|
21
|
-
"@ckeditor/ckeditor5-cloud-services": "^
|
22
|
-
"@ckeditor/ckeditor5-dev-utils": "^
|
23
|
-
"@ckeditor/ckeditor5-editor-classic": "^
|
24
|
-
"@ckeditor/ckeditor5-engine": "^
|
25
|
-
"@ckeditor/ckeditor5-image": "^
|
26
|
-
"@ckeditor/ckeditor5-link": "^
|
27
|
-
"@ckeditor/ckeditor5-paragraph": "^
|
28
|
-
"@ckeditor/ckeditor5-theme-lark": "^
|
29
|
-
"@ckeditor/ckeditor5-ui": "^
|
30
|
-
"@ckeditor/ckeditor5-upload": "^
|
31
|
-
"@ckeditor/ckeditor5-utils": "^
|
18
|
+
"@ckeditor/ckeditor5-basic-styles": "^37.0.0-alpha.0",
|
19
|
+
"@ckeditor/ckeditor5-core": "^37.0.0-alpha.0",
|
20
|
+
"@ckeditor/ckeditor5-clipboard": "^37.0.0-alpha.0",
|
21
|
+
"@ckeditor/ckeditor5-cloud-services": "^37.0.0-alpha.0",
|
22
|
+
"@ckeditor/ckeditor5-dev-utils": "^34.0.0",
|
23
|
+
"@ckeditor/ckeditor5-editor-classic": "^37.0.0-alpha.0",
|
24
|
+
"@ckeditor/ckeditor5-engine": "^37.0.0-alpha.0",
|
25
|
+
"@ckeditor/ckeditor5-image": "^37.0.0-alpha.0",
|
26
|
+
"@ckeditor/ckeditor5-link": "^37.0.0-alpha.0",
|
27
|
+
"@ckeditor/ckeditor5-paragraph": "^37.0.0-alpha.0",
|
28
|
+
"@ckeditor/ckeditor5-theme-lark": "^37.0.0-alpha.0",
|
29
|
+
"@ckeditor/ckeditor5-ui": "^37.0.0-alpha.0",
|
30
|
+
"@ckeditor/ckeditor5-upload": "^37.0.0-alpha.0",
|
31
|
+
"@ckeditor/ckeditor5-utils": "^37.0.0-alpha.0",
|
32
|
+
"typescript": "^4.8.4",
|
32
33
|
"webpack": "^5.58.1",
|
33
34
|
"webpack-cli": "^4.9.0"
|
34
35
|
},
|
@@ -47,13 +48,17 @@
|
|
47
48
|
},
|
48
49
|
"files": [
|
49
50
|
"lang",
|
50
|
-
"src",
|
51
|
+
"src/**/*.js",
|
52
|
+
"src/**/*.d.ts",
|
51
53
|
"theme",
|
52
54
|
"build",
|
53
55
|
"ckeditor5-metadata.json",
|
54
56
|
"CHANGELOG.md"
|
55
57
|
],
|
56
58
|
"scripts": {
|
57
|
-
"dll:build": "webpack"
|
58
|
-
|
59
|
+
"dll:build": "webpack",
|
60
|
+
"build": "tsc -p ./tsconfig.release.json",
|
61
|
+
"postversion": "npm run build"
|
62
|
+
},
|
63
|
+
"types": "src/index.d.ts"
|
59
64
|
}
|
package/src/ckbox.d.ts
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
/**
|
2
|
+
* @license Copyright (c) 2003-2023, 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
|
+
* @module ckbox/ckbox
|
7
|
+
*/
|
8
|
+
import { Plugin, type PluginDependencies } from 'ckeditor5/src/core';
|
9
|
+
/**
|
10
|
+
* The CKBox feature, a bridge between the CKEditor 5 WYSIWYG editor and the CKBox file manager and uploader.
|
11
|
+
*
|
12
|
+
* This is a "glue" plugin which enables:
|
13
|
+
*
|
14
|
+
* * {@link module:ckbox/ckboxediting~CKBoxEditing},
|
15
|
+
* * {@link module:ckbox/ckboxui~CKBoxUI},
|
16
|
+
*
|
17
|
+
* See the {@glink features/images/image-upload/ckbox CKBox integration} guide to learn how to configure and use this feature.
|
18
|
+
*
|
19
|
+
* Check out the {@glink features/images/image-upload/image-upload Image upload} guide to learn about other ways to upload
|
20
|
+
* images into CKEditor 5.
|
21
|
+
*/
|
22
|
+
export default class CKBox extends Plugin {
|
23
|
+
/**
|
24
|
+
* @inheritDoc
|
25
|
+
*/
|
26
|
+
static get pluginName(): 'CKBox';
|
27
|
+
/**
|
28
|
+
* @inheritDoc
|
29
|
+
*/
|
30
|
+
static get requires(): PluginDependencies;
|
31
|
+
}
|
32
|
+
declare module '@ckeditor/ckeditor5-core' {
|
33
|
+
interface PluginsMap {
|
34
|
+
[CKBox.pluginName]: CKBox;
|
35
|
+
}
|
36
|
+
}
|
package/src/ckbox.js
CHANGED
@@ -2,16 +2,12 @@
|
|
2
2
|
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
3
3
|
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
4
4
|
*/
|
5
|
-
|
6
5
|
/**
|
7
6
|
* @module ckbox/ckbox
|
8
7
|
*/
|
9
|
-
|
10
8
|
import { Plugin } from 'ckeditor5/src/core';
|
11
|
-
|
12
9
|
import CKBoxUI from './ckboxui';
|
13
10
|
import CKBoxEditing from './ckboxediting';
|
14
|
-
|
15
11
|
/**
|
16
12
|
* The CKBox feature, a bridge between the CKEditor 5 WYSIWYG editor and the CKBox file manager and uploader.
|
17
13
|
*
|
@@ -24,220 +20,18 @@ import CKBoxEditing from './ckboxediting';
|
|
24
20
|
*
|
25
21
|
* Check out the {@glink features/images/image-upload/image-upload Image upload} guide to learn about other ways to upload
|
26
22
|
* images into CKEditor 5.
|
27
|
-
*
|
28
|
-
* @extends module:core/plugin~Plugin
|
29
23
|
*/
|
30
24
|
export default class CKBox extends Plugin {
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
}
|
25
|
+
/**
|
26
|
+
* @inheritDoc
|
27
|
+
*/
|
28
|
+
static get pluginName() {
|
29
|
+
return 'CKBox';
|
30
|
+
}
|
31
|
+
/**
|
32
|
+
* @inheritDoc
|
33
|
+
*/
|
34
|
+
static get requires() {
|
35
|
+
return [CKBoxEditing, CKBoxUI];
|
36
|
+
}
|
44
37
|
}
|
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
|
-
*/
|
@@ -0,0 +1,114 @@
|
|
1
|
+
/**
|
2
|
+
* @license Copyright (c) 2003-2023, 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
|
+
import { Command, type Editor } from 'ckeditor5/src/core';
|
6
|
+
import type { CKBoxAssetDefinition } from './ckboxconfig';
|
7
|
+
declare global {
|
8
|
+
var CKBox: {
|
9
|
+
mount(wrapper: Element, options: Record<string, unknown>): void;
|
10
|
+
};
|
11
|
+
}
|
12
|
+
/**
|
13
|
+
* The CKBox command. It is used by the {@link module:ckbox/ckboxediting~CKBoxEditing CKBox editing feature} to open the CKBox file manager.
|
14
|
+
* The file manager allows inserting an image or a link to a file into the editor content.
|
15
|
+
*
|
16
|
+
* editor.execute( 'ckbox' );
|
17
|
+
*
|
18
|
+
* **Note:** This command uses other features to perform the following tasks:
|
19
|
+
* - To insert images it uses the {@link module:image/image/insertimagecommand~InsertImageCommand 'insertImage'} command from the
|
20
|
+
* {@link module:image/image~Image Image feature}.
|
21
|
+
* - To insert links to other files it uses the {@link module:link/linkcommand~LinkCommand 'link'} command from the
|
22
|
+
* {@link module:link/link~Link Link feature}.
|
23
|
+
*/
|
24
|
+
export default class CKBoxCommand extends Command {
|
25
|
+
value: boolean;
|
26
|
+
/**
|
27
|
+
* A set of all chosen assets. They are stored temporarily and they are automatically removed 1 second after being chosen.
|
28
|
+
* Chosen assets have to be "remembered" for a while to be able to map the given asset with the element inserted into the model.
|
29
|
+
* This association map is then used to set the ID on the model element.
|
30
|
+
*
|
31
|
+
* All chosen assets are automatically removed after the timeout, because (theoretically) it may happen that they will never be
|
32
|
+
* inserted into the model, even if the {@link module:link/linkcommand~LinkCommand `'link'`} command or the
|
33
|
+
* {@link module:image/image/insertimagecommand~InsertImageCommand `'insertImage'`} command is enabled. Such a case may arise when
|
34
|
+
* another plugin blocks the command execution. Then, in order not to keep the chosen (but not inserted) assets forever, we delete
|
35
|
+
* them automatically to prevent memory leakage. The 1 second timeout is enough to insert the asset into the model and extract the
|
36
|
+
* ID from the chosen asset.
|
37
|
+
*
|
38
|
+
* The assets are stored only if
|
39
|
+
* the {@link module:ckbox/ckboxconfig~CKBoxConfig#ignoreDataId `config.ckbox.ignoreDataId`} option is set to `false` (by default).
|
40
|
+
*
|
41
|
+
* @internal
|
42
|
+
*/
|
43
|
+
readonly _chosenAssets: Set<CKBoxAssetDefinition>;
|
44
|
+
/**
|
45
|
+
* The DOM element that acts as a mounting point for the CKBox dialog.
|
46
|
+
*/
|
47
|
+
private _wrapper;
|
48
|
+
/**
|
49
|
+
* @inheritDoc
|
50
|
+
*/
|
51
|
+
constructor(editor: Editor);
|
52
|
+
/**
|
53
|
+
* @inheritDoc
|
54
|
+
*/
|
55
|
+
refresh(): void;
|
56
|
+
/**
|
57
|
+
* @inheritDoc
|
58
|
+
*/
|
59
|
+
execute(): void;
|
60
|
+
/**
|
61
|
+
* Indicates if the CKBox dialog is already opened.
|
62
|
+
*
|
63
|
+
* @protected
|
64
|
+
* @returns {Boolean}
|
65
|
+
*/
|
66
|
+
private _getValue;
|
67
|
+
/**
|
68
|
+
* Checks whether the command can be enabled in the current context.
|
69
|
+
*/
|
70
|
+
private _checkEnabled;
|
71
|
+
/**
|
72
|
+
* Creates the options object for the CKBox dialog.
|
73
|
+
*
|
74
|
+
* @returns The object with properties:
|
75
|
+
* - theme The theme for CKBox dialog.
|
76
|
+
* - language The language for CKBox dialog.
|
77
|
+
* - tokenUrl The token endpoint URL.
|
78
|
+
* - serviceOrigin The base URL of the API service.
|
79
|
+
* - assetsOrigin The base URL for assets inserted into the editor.
|
80
|
+
* - dialog.onClose The callback function invoked after closing the CKBox dialog.
|
81
|
+
* - assets.onChoose The callback function invoked after choosing the assets.
|
82
|
+
*/
|
83
|
+
private _prepareOptions;
|
84
|
+
/**
|
85
|
+
* Initializes various event listeners for the `ckbox:*` events, because all functionality of the `ckbox` command is event-based.
|
86
|
+
*/
|
87
|
+
private _initListeners;
|
88
|
+
/**
|
89
|
+
* Inserts the asset into the model.
|
90
|
+
*
|
91
|
+
* @param asset The asset to be inserted.
|
92
|
+
* @param isLastAsset Indicates if the current asset is the last one from the chosen set.
|
93
|
+
* @param writer An instance of the model writer.
|
94
|
+
*/
|
95
|
+
private _insertAsset;
|
96
|
+
/**
|
97
|
+
* Inserts the image by calling the `insertImage` command.
|
98
|
+
*
|
99
|
+
* @param asset The asset to be inserted.
|
100
|
+
*/
|
101
|
+
private _insertImage;
|
102
|
+
/**
|
103
|
+
* Inserts the link to the asset by calling the `link` command.
|
104
|
+
*
|
105
|
+
* @param asset The asset to be inserted.
|
106
|
+
* @param writer An instance of the model writer.
|
107
|
+
*/
|
108
|
+
private _insertLink;
|
109
|
+
}
|
110
|
+
declare module '@ckeditor/ckeditor5-core' {
|
111
|
+
interface CommandsMap {
|
112
|
+
ckbox: CKBoxCommand;
|
113
|
+
}
|
114
|
+
}
|