@ckeditor/ckeditor5-ckbox 42.0.2 → 43.0.0-alpha.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (219) hide show
  1. package/CHANGELOG.md +1 -1
  2. package/build/ckbox.js +2 -2
  3. package/build/translations/ar.js +1 -1
  4. package/build/translations/az.js +1 -1
  5. package/build/translations/bg.js +1 -1
  6. package/build/translations/bn.js +1 -1
  7. package/build/translations/ca.js +1 -1
  8. package/build/translations/cs.js +1 -1
  9. package/build/translations/da.js +1 -1
  10. package/build/translations/de.js +1 -1
  11. package/build/translations/el.js +1 -1
  12. package/build/translations/en-au.js +1 -1
  13. package/build/translations/es-co.js +1 -1
  14. package/build/translations/es.js +1 -1
  15. package/build/translations/et.js +1 -1
  16. package/build/translations/fa.js +1 -1
  17. package/build/translations/fi.js +1 -1
  18. package/build/translations/fr.js +1 -1
  19. package/build/translations/gl.js +1 -1
  20. package/build/translations/he.js +1 -1
  21. package/build/translations/hi.js +1 -1
  22. package/build/translations/hr.js +1 -1
  23. package/build/translations/hu.js +1 -1
  24. package/build/translations/id.js +1 -1
  25. package/build/translations/it.js +1 -1
  26. package/build/translations/ja.js +1 -1
  27. package/build/translations/ko.js +1 -1
  28. package/build/translations/lt.js +1 -1
  29. package/build/translations/lv.js +1 -1
  30. package/build/translations/ms.js +1 -1
  31. package/build/translations/nl.js +1 -1
  32. package/build/translations/no.js +1 -1
  33. package/build/translations/pl.js +1 -1
  34. package/build/translations/pt-br.js +1 -1
  35. package/build/translations/pt.js +1 -1
  36. package/build/translations/ro.js +1 -1
  37. package/build/translations/ru.js +1 -1
  38. package/build/translations/sk.js +1 -1
  39. package/build/translations/sq.js +1 -1
  40. package/build/translations/sr-latn.js +1 -1
  41. package/build/translations/sr.js +1 -1
  42. package/build/translations/sv.js +1 -1
  43. package/build/translations/th.js +1 -1
  44. package/build/translations/tr.js +1 -1
  45. package/build/translations/ug.js +1 -1
  46. package/build/translations/uk.js +1 -1
  47. package/build/translations/ur.js +1 -1
  48. package/build/translations/uz.js +1 -1
  49. package/build/translations/vi.js +1 -1
  50. package/build/translations/zh-cn.js +1 -1
  51. package/build/translations/zh.js +1 -1
  52. package/dist/ckboxcommand.d.ts +13 -1
  53. package/dist/ckboxconfig.d.ts +105 -0
  54. package/dist/ckboxediting.d.ts +7 -4
  55. package/dist/ckboxutils.d.ts +3 -3
  56. package/dist/index.js +90 -25
  57. package/dist/index.js.map +1 -1
  58. package/dist/translations/ar.js +1 -1
  59. package/dist/translations/ar.umd.js +1 -1
  60. package/dist/translations/az.js +1 -1
  61. package/dist/translations/az.umd.js +1 -1
  62. package/dist/translations/bg.js +1 -1
  63. package/dist/translations/bg.umd.js +1 -1
  64. package/dist/translations/bn.js +1 -1
  65. package/dist/translations/bn.umd.js +1 -1
  66. package/dist/translations/ca.js +1 -1
  67. package/dist/translations/ca.umd.js +1 -1
  68. package/dist/translations/cs.js +1 -1
  69. package/dist/translations/cs.umd.js +1 -1
  70. package/dist/translations/da.js +1 -1
  71. package/dist/translations/da.umd.js +1 -1
  72. package/dist/translations/de.js +1 -1
  73. package/dist/translations/de.umd.js +1 -1
  74. package/dist/translations/el.js +1 -1
  75. package/dist/translations/el.umd.js +1 -1
  76. package/dist/translations/en-au.js +1 -1
  77. package/dist/translations/en-au.umd.js +1 -1
  78. package/dist/translations/en.js +1 -1
  79. package/dist/translations/en.umd.js +1 -1
  80. package/dist/translations/es-co.js +1 -1
  81. package/dist/translations/es-co.umd.js +1 -1
  82. package/dist/translations/es.js +1 -1
  83. package/dist/translations/es.umd.js +1 -1
  84. package/dist/translations/et.js +1 -1
  85. package/dist/translations/et.umd.js +1 -1
  86. package/dist/translations/fa.js +1 -1
  87. package/dist/translations/fa.umd.js +1 -1
  88. package/dist/translations/fi.js +1 -1
  89. package/dist/translations/fi.umd.js +1 -1
  90. package/dist/translations/fr.js +1 -1
  91. package/dist/translations/fr.umd.js +1 -1
  92. package/dist/translations/gl.js +1 -1
  93. package/dist/translations/gl.umd.js +1 -1
  94. package/dist/translations/he.js +1 -1
  95. package/dist/translations/he.umd.js +1 -1
  96. package/dist/translations/hi.js +1 -1
  97. package/dist/translations/hi.umd.js +1 -1
  98. package/dist/translations/hr.js +1 -1
  99. package/dist/translations/hr.umd.js +1 -1
  100. package/dist/translations/hu.js +1 -1
  101. package/dist/translations/hu.umd.js +1 -1
  102. package/dist/translations/id.js +1 -1
  103. package/dist/translations/id.umd.js +1 -1
  104. package/dist/translations/it.js +1 -1
  105. package/dist/translations/it.umd.js +1 -1
  106. package/dist/translations/ja.js +1 -1
  107. package/dist/translations/ja.umd.js +1 -1
  108. package/dist/translations/ko.js +1 -1
  109. package/dist/translations/ko.umd.js +1 -1
  110. package/dist/translations/lt.js +1 -1
  111. package/dist/translations/lt.umd.js +1 -1
  112. package/dist/translations/lv.js +1 -1
  113. package/dist/translations/lv.umd.js +1 -1
  114. package/dist/translations/ms.js +1 -1
  115. package/dist/translations/ms.umd.js +1 -1
  116. package/dist/translations/nl.js +1 -1
  117. package/dist/translations/nl.umd.js +1 -1
  118. package/dist/translations/no.js +1 -1
  119. package/dist/translations/no.umd.js +1 -1
  120. package/dist/translations/pl.js +1 -1
  121. package/dist/translations/pl.umd.js +1 -1
  122. package/dist/translations/pt-br.js +1 -1
  123. package/dist/translations/pt-br.umd.js +1 -1
  124. package/dist/translations/pt.js +1 -1
  125. package/dist/translations/pt.umd.js +1 -1
  126. package/dist/translations/ro.js +1 -1
  127. package/dist/translations/ro.umd.js +1 -1
  128. package/dist/translations/ru.js +1 -1
  129. package/dist/translations/ru.umd.js +1 -1
  130. package/dist/translations/sk.js +1 -1
  131. package/dist/translations/sk.umd.js +1 -1
  132. package/dist/translations/sq.js +1 -1
  133. package/dist/translations/sq.umd.js +1 -1
  134. package/dist/translations/sr-latn.js +1 -1
  135. package/dist/translations/sr-latn.umd.js +1 -1
  136. package/dist/translations/sr.js +1 -1
  137. package/dist/translations/sr.umd.js +1 -1
  138. package/dist/translations/sv.js +1 -1
  139. package/dist/translations/sv.umd.js +1 -1
  140. package/dist/translations/th.js +1 -1
  141. package/dist/translations/th.umd.js +1 -1
  142. package/dist/translations/tr.js +1 -1
  143. package/dist/translations/tr.umd.js +1 -1
  144. package/dist/translations/ug.js +1 -1
  145. package/dist/translations/ug.umd.js +1 -1
  146. package/dist/translations/uk.js +1 -1
  147. package/dist/translations/uk.umd.js +1 -1
  148. package/dist/translations/ur.js +1 -1
  149. package/dist/translations/ur.umd.js +1 -1
  150. package/dist/translations/uz.js +1 -1
  151. package/dist/translations/uz.umd.js +1 -1
  152. package/dist/translations/vi.js +1 -1
  153. package/dist/translations/vi.umd.js +1 -1
  154. package/dist/translations/zh-cn.js +1 -1
  155. package/dist/translations/zh-cn.umd.js +1 -1
  156. package/dist/translations/zh.js +1 -1
  157. package/dist/translations/zh.umd.js +1 -1
  158. package/lang/contexts.json +1 -0
  159. package/lang/translations/ar.po +4 -0
  160. package/lang/translations/az.po +4 -0
  161. package/lang/translations/bg.po +4 -0
  162. package/lang/translations/bn.po +4 -0
  163. package/lang/translations/ca.po +4 -0
  164. package/lang/translations/cs.po +4 -0
  165. package/lang/translations/da.po +4 -0
  166. package/lang/translations/de.po +4 -0
  167. package/lang/translations/el.po +4 -0
  168. package/lang/translations/en-au.po +4 -0
  169. package/lang/translations/en.po +4 -0
  170. package/lang/translations/es-co.po +4 -0
  171. package/lang/translations/es.po +4 -0
  172. package/lang/translations/et.po +4 -0
  173. package/lang/translations/fa.po +4 -0
  174. package/lang/translations/fi.po +4 -0
  175. package/lang/translations/fr.po +4 -0
  176. package/lang/translations/gl.po +4 -0
  177. package/lang/translations/he.po +4 -0
  178. package/lang/translations/hi.po +4 -0
  179. package/lang/translations/hr.po +4 -0
  180. package/lang/translations/hu.po +4 -0
  181. package/lang/translations/id.po +4 -0
  182. package/lang/translations/it.po +4 -0
  183. package/lang/translations/ja.po +4 -0
  184. package/lang/translations/ko.po +4 -0
  185. package/lang/translations/lt.po +4 -0
  186. package/lang/translations/lv.po +4 -0
  187. package/lang/translations/ms.po +4 -0
  188. package/lang/translations/nl.po +4 -0
  189. package/lang/translations/no.po +4 -0
  190. package/lang/translations/pl.po +4 -0
  191. package/lang/translations/pt-br.po +4 -0
  192. package/lang/translations/pt.po +4 -0
  193. package/lang/translations/ro.po +4 -0
  194. package/lang/translations/ru.po +4 -0
  195. package/lang/translations/sk.po +4 -0
  196. package/lang/translations/sq.po +4 -0
  197. package/lang/translations/sr-latn.po +8 -4
  198. package/lang/translations/sr.po +4 -0
  199. package/lang/translations/sv.po +4 -0
  200. package/lang/translations/th.po +4 -0
  201. package/lang/translations/tr.po +4 -0
  202. package/lang/translations/ug.po +4 -0
  203. package/lang/translations/uk.po +4 -0
  204. package/lang/translations/ur.po +4 -0
  205. package/lang/translations/uz.po +4 -0
  206. package/lang/translations/vi.po +4 -0
  207. package/lang/translations/zh-cn.po +4 -0
  208. package/lang/translations/zh.po +4 -0
  209. package/package.json +7 -7
  210. package/src/ckboxcommand.d.ts +13 -1
  211. package/src/ckboxcommand.js +36 -4
  212. package/src/ckboxconfig.d.ts +105 -0
  213. package/src/ckboxediting.d.ts +7 -4
  214. package/src/ckboxediting.js +46 -4
  215. package/src/ckboximageedit/ckboximageeditcommand.js +1 -1
  216. package/src/ckboximageedit/ckboximageeditui.js +4 -1
  217. package/src/ckboxuploadadapter.js +2 -2
  218. package/src/ckboxutils.d.ts +3 -3
  219. package/src/ckboxutils.js +10 -10
@@ -29,6 +29,10 @@ msgctxt "A message is displayed when the user is not authorised to access the CK
29
29
  msgid "Cannot access default workspace."
30
30
  msgstr ""
31
31
 
32
+ msgctxt "The title of the notification displayed when there is no permission to edit assets."
33
+ msgid "No permission for image editing. Try using the file manager or contact your administrator."
34
+ msgstr ""
35
+
32
36
  msgctxt "Image toolbar button tooltip for opening a dialog to manipulate the image."
33
37
  msgid "Edit image"
34
38
  msgstr ""
@@ -29,6 +29,10 @@ msgctxt "A message is displayed when the user is not authorised to access the CK
29
29
  msgid "Cannot access default workspace."
30
30
  msgstr ""
31
31
 
32
+ msgctxt "The title of the notification displayed when there is no permission to edit assets."
33
+ msgid "No permission for image editing. Try using the file manager or contact your administrator."
34
+ msgstr ""
35
+
32
36
  msgctxt "Image toolbar button tooltip for opening a dialog to manipulate the image."
33
37
  msgid "Edit image"
34
38
  msgstr ""
@@ -29,6 +29,10 @@ msgctxt "A message is displayed when the user is not authorised to access the CK
29
29
  msgid "Cannot access default workspace."
30
30
  msgstr "Không thể truy cập vào không gian làm việc mặc định."
31
31
 
32
+ msgctxt "The title of the notification displayed when there is no permission to edit assets."
33
+ msgid "No permission for image editing. Try using the file manager or contact your administrator."
34
+ msgstr ""
35
+
32
36
  msgctxt "Image toolbar button tooltip for opening a dialog to manipulate the image."
33
37
  msgid "Edit image"
34
38
  msgstr "Chỉnh sửa hình ảnh"
@@ -29,6 +29,10 @@ msgctxt "A message is displayed when the user is not authorised to access the CK
29
29
  msgid "Cannot access default workspace."
30
30
  msgstr "无法访问默认工作区"
31
31
 
32
+ msgctxt "The title of the notification displayed when there is no permission to edit assets."
33
+ msgid "No permission for image editing. Try using the file manager or contact your administrator."
34
+ msgstr ""
35
+
32
36
  msgctxt "Image toolbar button tooltip for opening a dialog to manipulate the image."
33
37
  msgid "Edit image"
34
38
  msgstr "编辑图片"
@@ -29,6 +29,10 @@ msgctxt "A message is displayed when the user is not authorised to access the CK
29
29
  msgid "Cannot access default workspace."
30
30
  msgstr "無法存取預設工作區。"
31
31
 
32
+ msgctxt "The title of the notification displayed when there is no permission to edit assets."
33
+ msgid "No permission for image editing. Try using the file manager or contact your administrator."
34
+ msgstr ""
35
+
32
36
  msgctxt "Image toolbar button tooltip for opening a dialog to manipulate the image."
33
37
  msgid "Edit image"
34
38
  msgstr "編輯圖片"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ckeditor/ckeditor5-ckbox",
3
- "version": "42.0.2",
3
+ "version": "43.0.0-alpha.0",
4
4
  "description": "CKBox integration for CKEditor 5.",
5
5
  "keywords": [
6
6
  "ckeditor",
@@ -13,12 +13,12 @@
13
13
  "type": "module",
14
14
  "main": "src/index.js",
15
15
  "dependencies": {
16
- "@ckeditor/ckeditor5-core": "42.0.2",
17
- "@ckeditor/ckeditor5-engine": "42.0.2",
18
- "@ckeditor/ckeditor5-ui": "42.0.2",
19
- "@ckeditor/ckeditor5-upload": "42.0.2",
20
- "@ckeditor/ckeditor5-utils": "42.0.2",
21
- "ckeditor5": "42.0.2",
16
+ "@ckeditor/ckeditor5-core": "43.0.0-alpha.0",
17
+ "@ckeditor/ckeditor5-engine": "43.0.0-alpha.0",
18
+ "@ckeditor/ckeditor5-ui": "43.0.0-alpha.0",
19
+ "@ckeditor/ckeditor5-upload": "43.0.0-alpha.0",
20
+ "@ckeditor/ckeditor5-utils": "43.0.0-alpha.0",
21
+ "ckeditor5": "43.0.0-alpha.0",
22
22
  "blurhash": "2.0.5",
23
23
  "lodash-es": "4.17.21"
24
24
  },
@@ -74,8 +74,20 @@ export default class CKBoxCommand extends Command {
74
74
  * - tokenUrl The token endpoint URL.
75
75
  * - serviceOrigin The base URL of the API service.
76
76
  * - forceDemoLabel Whether to force "Powered by CKBox" link.
77
- * - dialog.onClose The callback function invoked after closing the CKBox dialog.
78
77
  * - assets.onChoose The callback function invoked after choosing the assets.
78
+ * - dialog.onClose The callback function invoked after closing the CKBox dialog.
79
+ * - dialog.width The dialog width in pixels.
80
+ * - dialog.height The dialog height in pixels.
81
+ * - categories.icons Allows setting custom icons for categories.
82
+ * - view.openLastView Sets if the last view visited by the user will be reopened
83
+ * on the next startup.
84
+ * - view.startupFolderId Sets the ID of the folder that will be opened on startup.
85
+ * - view.startupCategoryId Sets the ID of the category that will be opened on startup.
86
+ * - view.hideMaximizeButton Sets whether to hide the ‘Maximize’ button.
87
+ * - view.componentsHideTimeout Sets timeout after which upload components are hidden
88
+ * after completed upload.
89
+ * - view.dialogMinimizeTimeout Sets timeout after which upload dialog is minimized
90
+ * after completed upload.
79
91
  */
80
92
  private _prepareOptions;
81
93
  /**
@@ -95,23 +95,55 @@ export default class CKBoxCommand extends Command {
95
95
  * - tokenUrl The token endpoint URL.
96
96
  * - serviceOrigin The base URL of the API service.
97
97
  * - forceDemoLabel Whether to force "Powered by CKBox" link.
98
- * - dialog.onClose The callback function invoked after closing the CKBox dialog.
99
98
  * - assets.onChoose The callback function invoked after choosing the assets.
99
+ * - dialog.onClose The callback function invoked after closing the CKBox dialog.
100
+ * - dialog.width The dialog width in pixels.
101
+ * - dialog.height The dialog height in pixels.
102
+ * - categories.icons Allows setting custom icons for categories.
103
+ * - view.openLastView Sets if the last view visited by the user will be reopened
104
+ * on the next startup.
105
+ * - view.startupFolderId Sets the ID of the folder that will be opened on startup.
106
+ * - view.startupCategoryId Sets the ID of the category that will be opened on startup.
107
+ * - view.hideMaximizeButton Sets whether to hide the ‘Maximize’ button.
108
+ * - view.componentsHideTimeout Sets timeout after which upload components are hidden
109
+ * after completed upload.
110
+ * - view.dialogMinimizeTimeout Sets timeout after which upload dialog is minimized
111
+ * after completed upload.
100
112
  */
101
113
  _prepareOptions() {
102
114
  const editor = this.editor;
103
115
  const ckboxConfig = editor.config.get('ckbox');
116
+ const dialog = ckboxConfig.dialog;
117
+ const categories = ckboxConfig.categories;
118
+ const view = ckboxConfig.view;
119
+ const upload = ckboxConfig.upload;
104
120
  return {
105
121
  theme: ckboxConfig.theme,
106
122
  language: ckboxConfig.language,
107
123
  tokenUrl: ckboxConfig.tokenUrl,
108
124
  serviceOrigin: ckboxConfig.serviceOrigin,
109
125
  forceDemoLabel: ckboxConfig.forceDemoLabel,
110
- dialog: {
111
- onClose: () => this.fire('ckbox:close')
112
- },
126
+ choosableFileExtensions: ckboxConfig.choosableFileExtensions,
113
127
  assets: {
114
128
  onChoose: (assets) => this.fire('ckbox:choose', assets)
129
+ },
130
+ dialog: {
131
+ onClose: () => this.fire('ckbox:close'),
132
+ width: dialog && dialog.width,
133
+ height: dialog && dialog.height
134
+ },
135
+ categories: categories && {
136
+ icons: categories.icons
137
+ },
138
+ view: view && {
139
+ openLastView: view.openLastView,
140
+ startupFolderId: view.startupFolderId,
141
+ startupCategoryId: view.startupCategoryId,
142
+ hideMaximizeButton: view.hideMaximizeButton
143
+ },
144
+ upload: upload && {
145
+ componentsHideTimeout: upload.componentsHideTimeout,
146
+ dialogMinimizeTimeout: upload.dialogMinimizeTimeout
115
147
  }
116
148
  };
117
149
  }
@@ -125,6 +125,111 @@ export interface CKBoxConfig {
125
125
  * Defaults to {@link module:utils/locale~Locale#uiLanguage `Locale#uiLanguage`}
126
126
  */
127
127
  language?: string;
128
+ /**
129
+ * This option allows opening CKBox in dialog mode. It takes a configuration object with
130
+ * the width and height attributes.
131
+ */
132
+ dialog?: CKBoxDialogConfig;
133
+ /**
134
+ * Allows setting custom icons for categories.
135
+ */
136
+ categories?: CKBoxCategoriesConfig;
137
+ /**
138
+ * Configures the view of CKBox.
139
+ */
140
+ view?: CKBoxViewConfig;
141
+ /**
142
+ * Configures when dialog should be minimized and hidden.
143
+ */
144
+ upload?: CKBoxUploadConfig;
145
+ /**
146
+ * Specifies the file extensions considered valid for user interaction. Whith this
147
+ * option developers can restrict user interaction to only those assets whose file
148
+ * extensions match those listed in the array. Assets whose file
149
+ * extensions are not listed in the `choosableFileExtensions` array are
150
+ * automatically disabled within the CKBox interface.
151
+ *
152
+ * ```ts
153
+ * const ckboxConfig = {
154
+ * choosableFileExtensions: ['jpg', 'png']
155
+ * };
156
+ * ```
157
+ */
158
+ choosableFileExtensions?: Array<string>;
159
+ }
160
+ export interface CKBoxDialogConfig {
161
+ /**
162
+ * The dialog width in pixels.
163
+ */
164
+ width: number;
165
+ /**
166
+ * The dialog height in pixels.
167
+ */
168
+ height: number;
169
+ }
170
+ export interface CKBoxCategoriesConfig {
171
+ /**
172
+ * This option takes an object with categories and icons that should be used instead
173
+ * of the default ones. Categories can be defined using either their name or id.
174
+ * Icons should be defined as strings containing the SVG images, or as React components.
175
+ *
176
+ * ```ts
177
+ * const ckboxConfig = {
178
+ * categories: {
179
+ * icons: {
180
+ * Images: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path ... /></svg>',
181
+ * // Category can be referenced by ID
182
+ * // 'fdf2a647-b67f-4a6c-b692-5ba1dc1ed87b': '<svg...'
183
+ * }
184
+ * }
185
+ * }
186
+ * ```
187
+ */
188
+ icons?: {
189
+ [key: string]: string;
190
+ };
191
+ }
192
+ export interface CKBoxViewConfig {
193
+ /**
194
+ * If it is set to `false` the last view visited by the user will not be reopened on
195
+ * the next startup.
196
+ */
197
+ openLastView?: boolean;
198
+ /**
199
+ * Sets the ID of the folder that will be opened on startup. This option can be paired
200
+ * with setting `view.openLastView` to `false` to enforce CKBox to always open in a given
201
+ * folder at startup.
202
+ */
203
+ startupFolderId?: string;
204
+ /**
205
+ * Sets the ID of the category that will be opened on startup. This option can be paired
206
+ * with setting `view.openLastView` to `false` to enforce CKBox to always open in a given
207
+ * category at startup. If `view.startupCategoryId` is passed along with the
208
+ * `view.startupFolderId` option, CKBox will prioritize opening category view on the startup.
209
+ */
210
+ startupCategoryId?: string;
211
+ /**
212
+ * Sets whether to hide the ‘Maximize’ button. By default, the button is shown and enabling
213
+ * this option will hide it.
214
+ */
215
+ hideMaximizeButton?: boolean;
216
+ }
217
+ export interface CKBoxUploadConfig {
218
+ /**
219
+ * Sets timeout (in milliseconds) after which upload components (dialog and indicator) are
220
+ * hidden. By default, these components hide automatically after 10 seconds.
221
+ *
222
+ * Read more: https://ckeditor.com/docs/ckbox/latest/guides/configuration/configuration-options.html#uploadcomponentshidetimeout
223
+ */
224
+ componentsHideTimeout?: number;
225
+ /**
226
+ * Sets timeout (in milliseconds) after which upload dialog is minimized once upload is
227
+ * finished and all uploads were successful. By default, upload dialog is never minimized
228
+ * automatically.
229
+ *
230
+ * Read more: https://ckeditor.com/docs/ckbox/latest/guides/configuration/configuration-options.html#uploaddialogminimizetimeout
231
+ */
232
+ dialogMinimizeTimeout?: number;
128
233
  }
129
234
  /**
130
235
  * Asset definition.
@@ -2,6 +2,9 @@
2
2
  * @license Copyright (c) 2003-2024, 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
+ * @module ckbox/ckboxediting
7
+ */
5
8
  import { Plugin } from 'ckeditor5/src/core.js';
6
9
  import CKBoxUploadAdapter from './ckboxuploadadapter.js';
7
10
  import CKBoxUtils from './ckboxutils.js';
@@ -10,10 +13,6 @@ import CKBoxUtils from './ckboxutils.js';
10
13
  * {@link module:ckbox/ckboxuploadadapter~CKBoxUploadAdapter CKBox upload adapter}.
11
14
  */
12
15
  export default class CKBoxEditing extends Plugin {
13
- /**
14
- * CKEditor Cloud Services access token.
15
- */
16
- private _token;
17
16
  /**
18
17
  * @inheritDoc
19
18
  */
@@ -35,6 +34,10 @@ export default class CKBoxEditing extends Plugin {
35
34
  * the CKBox JavaScript library is loaded.
36
35
  */
37
36
  private _shouldBeInitialised;
37
+ /**
38
+ * Blocks `uploadImage` and `ckboxImageEdit` commands.
39
+ */
40
+ private _blockImageCommands;
38
41
  /**
39
42
  * Checks if at least one image plugin is loaded.
40
43
  */
@@ -2,12 +2,18 @@
2
2
  * @license Copyright (c) 2003-2024, 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
+ /* globals window */
6
+ /**
7
+ * @module ckbox/ckboxediting
8
+ */
5
9
  import { Plugin } from 'ckeditor5/src/core.js';
6
10
  import { Range } from 'ckeditor5/src/engine.js';
7
11
  import { logError } from 'ckeditor5/src/utils.js';
8
12
  import CKBoxCommand from './ckboxcommand.js';
9
13
  import CKBoxUploadAdapter from './ckboxuploadadapter.js';
10
14
  import CKBoxUtils from './ckboxutils.js';
15
+ import { sendHttpRequest } from './utils.js';
16
+ const COMMAND_FORCE_DISABLE_ID = 'NoPermission';
11
17
  /**
12
18
  * The CKBox editing feature. It introduces the {@link module:ckbox/ckboxcommand~CKBoxCommand CKBox command} and
13
19
  * {@link module:ckbox/ckboxuploadadapter~CKBoxUploadAdapter CKBox upload adapter}.
@@ -38,6 +44,12 @@ export default class CKBoxEditing extends Plugin {
38
44
  if (isLibraryLoaded()) {
39
45
  editor.commands.add('ckbox', new CKBoxCommand(editor));
40
46
  }
47
+ // Promise is not handled intentionally. Errors should be displayed in console if there are so.
48
+ isUploadPermissionGranted(editor).then(isCreateAssetAllowed => {
49
+ if (!isCreateAssetAllowed) {
50
+ this._blockImageCommands();
51
+ }
52
+ });
41
53
  }
42
54
  /**
43
55
  * @inheritDoc
@@ -64,6 +76,21 @@ export default class CKBoxEditing extends Plugin {
64
76
  const hasConfiguration = !!editor.config.get('ckbox');
65
77
  return hasConfiguration || isLibraryLoaded();
66
78
  }
79
+ /**
80
+ * Blocks `uploadImage` and `ckboxImageEdit` commands.
81
+ */
82
+ _blockImageCommands() {
83
+ const editor = this.editor;
84
+ const uploadImageCommand = editor.commands.get('uploadImage');
85
+ const imageEditingCommand = editor.commands.get('ckboxImageEdit');
86
+ if (uploadImageCommand) {
87
+ uploadImageCommand.isAccessAllowed = false;
88
+ uploadImageCommand.forceDisabled(COMMAND_FORCE_DISABLE_ID);
89
+ }
90
+ if (imageEditingCommand) {
91
+ imageEditingCommand.forceDisabled(COMMAND_FORCE_DISABLE_ID);
92
+ }
93
+ }
67
94
  /**
68
95
  * Checks if at least one image plugin is loaded.
69
96
  */
@@ -98,12 +125,12 @@ export default class CKBoxEditing extends Plugin {
98
125
  if (schema.isRegistered('imageInline')) {
99
126
  schema.extend('imageInline', { allowAttributes: ['ckboxImageId', 'ckboxLinkId'] });
100
127
  }
101
- schema.addAttributeCheck((context, attributeName) => {
102
- const isLink = !!context.last.getAttribute('linkHref');
103
- if (!isLink && attributeName === 'ckboxLinkId') {
128
+ schema.addAttributeCheck(context => {
129
+ // Don't allow `ckboxLinkId` on elements which do not have `linkHref` attribute.
130
+ if (!context.last.getAttribute('linkHref')) {
104
131
  return false;
105
132
  }
106
- });
133
+ }, 'ckboxLinkId');
107
134
  }
108
135
  /**
109
136
  * Configures the upcast and downcast conversions for the `ckboxImageId` and `ckboxLinkId` attributes.
@@ -339,3 +366,18 @@ function shouldUpcastAttributeForNode(node) {
339
366
  function isLibraryLoaded() {
340
367
  return !!window.CKBox;
341
368
  }
369
+ /**
370
+ * Checks is access allowed to upload assets.
371
+ */
372
+ async function isUploadPermissionGranted(editor) {
373
+ const ckboxUtils = editor.plugins.get(CKBoxUtils);
374
+ const origin = editor.config.get('ckbox.serviceOrigin');
375
+ const url = new URL('permissions', origin);
376
+ const { value } = await ckboxUtils.getToken();
377
+ const response = (await sendHttpRequest({
378
+ url,
379
+ authorization: value,
380
+ signal: (new AbortController()).signal // Aborting is unnecessary.
381
+ }));
382
+ return Object.values(response).some(category => category['asset:create']);
383
+ }
@@ -227,7 +227,7 @@ export default class CKBoxImageEditCommand extends Command {
227
227
  const response = await sendHttpRequest({
228
228
  url,
229
229
  signal,
230
- authorization: ckboxUtils.getToken().value
230
+ authorization: (await ckboxUtils.getToken()).value
231
231
  });
232
232
  const status = response.metadata.metadataProcessingStatus;
233
233
  if (!status || status == 'queued') {
@@ -28,13 +28,16 @@ export default class CKBoxImageEditUI extends Plugin {
28
28
  const editor = this.editor;
29
29
  editor.ui.componentFactory.add('ckboxImageEdit', locale => {
30
30
  const command = editor.commands.get('ckboxImageEdit');
31
+ const uploadImageCommand = editor.commands.get('uploadImage');
31
32
  const view = new ButtonView(locale);
32
33
  const t = locale.t;
33
34
  view.set({
34
- label: t('Edit image'),
35
35
  icon: ckboxImageEditIcon,
36
36
  tooltip: true
37
37
  });
38
+ view.bind('label').to(uploadImageCommand, 'isAccessAllowed', isAccessAllowed => isAccessAllowed ?
39
+ t('Edit image') :
40
+ t('No permission for image editing. Try using the file manager or contact your administrator.'));
38
41
  view.bind('isOn').to(command, 'value', command, 'isEnabled', (value, isEnabled) => value && isEnabled);
39
42
  view.bind('isEnabled').to(command);
40
43
  // Execute the command.
@@ -88,7 +88,7 @@ class Adapter {
88
88
  const category = await ckboxUtils.getCategoryIdForFile(file, { signal: this.controller.signal });
89
89
  const uploadUrl = new URL('assets', this.serviceOrigin);
90
90
  const formData = new FormData();
91
- uploadUrl.searchParams.set('workspaceId', ckboxUtils.getWorkspaceId());
91
+ uploadUrl.searchParams.set('workspaceId', await ckboxUtils.getWorkspaceId());
92
92
  formData.append('categoryId', category);
93
93
  formData.append('file', file);
94
94
  const requestConfig = {
@@ -103,7 +103,7 @@ class Adapter {
103
103
  }
104
104
  },
105
105
  signal: this.controller.signal,
106
- authorization: this.token.value
106
+ authorization: (await this.token).value
107
107
  };
108
108
  return sendHttpRequest(requestConfig)
109
109
  .then(async (data) => {
@@ -26,15 +26,15 @@ export default class CKBoxUtils extends Plugin {
26
26
  /**
27
27
  * @inheritDoc
28
28
  */
29
- init(): Promise<void>;
29
+ init(): void;
30
30
  /**
31
31
  * Returns a token used by the CKBox plugin for communication with the CKBox service.
32
32
  */
33
- getToken(): InitializedToken;
33
+ getToken(): Promise<InitializedToken>;
34
34
  /**
35
35
  * The ID of workspace to use when uploading an image.
36
36
  */
37
- getWorkspaceId(): string;
37
+ getWorkspaceId(): Promise<string>;
38
38
  /**
39
39
  * Resolves a promise with an object containing a category with which the uploaded file is associated or an error code.
40
40
  */
package/src/ckboxutils.js CHANGED
@@ -25,7 +25,7 @@ export default class CKBoxUtils extends Plugin {
25
25
  /**
26
26
  * @inheritDoc
27
27
  */
28
- async init() {
28
+ init() {
29
29
  const editor = this.editor;
30
30
  const hasConfiguration = !!editor.config.get('ckbox');
31
31
  const isLibraryLoaded = !!window.CKBox;
@@ -66,10 +66,10 @@ export default class CKBoxUtils extends Plugin {
66
66
  throw new CKEditorError('ckbox-plugin-missing-token-url', this);
67
67
  }
68
68
  if (ckboxTokenUrl == cloudServicesTokenUrl) {
69
- this._token = cloudServices.token;
69
+ this._token = Promise.resolve(cloudServices.token);
70
70
  }
71
71
  else {
72
- this._token = await cloudServices.registerTokenUrl(ckboxTokenUrl);
72
+ this._token = cloudServices.registerTokenUrl(ckboxTokenUrl);
73
73
  }
74
74
  }
75
75
  /**
@@ -81,11 +81,11 @@ export default class CKBoxUtils extends Plugin {
81
81
  /**
82
82
  * The ID of workspace to use when uploading an image.
83
83
  */
84
- getWorkspaceId() {
84
+ async getWorkspaceId() {
85
85
  const t = this.editor.t;
86
86
  const cannotAccessDefaultWorkspaceError = t('Cannot access default workspace.');
87
87
  const defaultWorkspaceId = this.editor.config.get('ckbox.defaultUploadWorkspaceId');
88
- const workspaceId = getWorkspaceId(this._token, defaultWorkspaceId);
88
+ const workspaceId = getWorkspaceId(await this._token, defaultWorkspaceId);
89
89
  if (workspaceId == null) {
90
90
  /**
91
91
  * The user is not authorized to access the workspace defined in the`ckbox.defaultUploadWorkspaceId` configuration.
@@ -145,7 +145,7 @@ export default class CKBoxUtils extends Plugin {
145
145
  const token = this._token;
146
146
  const { signal } = options;
147
147
  const serviceOrigin = editor.config.get('ckbox.serviceOrigin');
148
- const workspaceId = this.getWorkspaceId();
148
+ const workspaceId = await this.getWorkspaceId();
149
149
  try {
150
150
  const result = [];
151
151
  let offset = 0;
@@ -168,15 +168,15 @@ export default class CKBoxUtils extends Plugin {
168
168
  logError('ckbox-fetch-category-http-error');
169
169
  return undefined;
170
170
  }
171
- function fetchCategories(offset) {
171
+ async function fetchCategories(offset) {
172
172
  const categoryUrl = new URL('categories', serviceOrigin);
173
- categoryUrl.searchParams.set('limit', ITEMS_PER_REQUEST.toString());
174
- categoryUrl.searchParams.set('offset', offset.toString());
173
+ categoryUrl.searchParams.set('limit', String(ITEMS_PER_REQUEST));
174
+ categoryUrl.searchParams.set('offset', String(offset));
175
175
  categoryUrl.searchParams.set('workspaceId', workspaceId);
176
176
  return sendHttpRequest({
177
177
  url: categoryUrl,
178
178
  signal,
179
- authorization: token.value
179
+ authorization: (await token).value
180
180
  });
181
181
  }
182
182
  }