@ckeditor/ckeditor5-ckbox 0.0.0-internal-20241017.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.
Files changed (309) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/LICENSE.md +21 -0
  3. package/README.md +24 -0
  4. package/build/ckbox.js +5 -0
  5. package/build/translations/ar.js +1 -0
  6. package/build/translations/az.js +1 -0
  7. package/build/translations/bg.js +1 -0
  8. package/build/translations/bn.js +1 -0
  9. package/build/translations/ca.js +1 -0
  10. package/build/translations/cs.js +1 -0
  11. package/build/translations/da.js +1 -0
  12. package/build/translations/de.js +1 -0
  13. package/build/translations/el.js +1 -0
  14. package/build/translations/en-au.js +1 -0
  15. package/build/translations/es-co.js +1 -0
  16. package/build/translations/es.js +1 -0
  17. package/build/translations/et.js +1 -0
  18. package/build/translations/fa.js +1 -0
  19. package/build/translations/fi.js +1 -0
  20. package/build/translations/fr.js +1 -0
  21. package/build/translations/gl.js +1 -0
  22. package/build/translations/he.js +1 -0
  23. package/build/translations/hi.js +1 -0
  24. package/build/translations/hr.js +1 -0
  25. package/build/translations/hu.js +1 -0
  26. package/build/translations/id.js +1 -0
  27. package/build/translations/it.js +1 -0
  28. package/build/translations/ja.js +1 -0
  29. package/build/translations/ko.js +1 -0
  30. package/build/translations/lt.js +1 -0
  31. package/build/translations/lv.js +1 -0
  32. package/build/translations/ms.js +1 -0
  33. package/build/translations/nl.js +1 -0
  34. package/build/translations/no.js +1 -0
  35. package/build/translations/pl.js +1 -0
  36. package/build/translations/pt-br.js +1 -0
  37. package/build/translations/pt.js +1 -0
  38. package/build/translations/ro.js +1 -0
  39. package/build/translations/ru.js +1 -0
  40. package/build/translations/sk.js +1 -0
  41. package/build/translations/sq.js +1 -0
  42. package/build/translations/sr-latn.js +1 -0
  43. package/build/translations/sr.js +1 -0
  44. package/build/translations/sv.js +1 -0
  45. package/build/translations/th.js +1 -0
  46. package/build/translations/tr.js +1 -0
  47. package/build/translations/ug.js +1 -0
  48. package/build/translations/uk.js +1 -0
  49. package/build/translations/ur.js +1 -0
  50. package/build/translations/uz.js +1 -0
  51. package/build/translations/vi.js +1 -0
  52. package/build/translations/zh-cn.js +1 -0
  53. package/build/translations/zh.js +1 -0
  54. package/ckeditor5-metadata.json +58 -0
  55. package/dist/augmentation.d.ts +36 -0
  56. package/dist/ckbox.d.ts +41 -0
  57. package/dist/ckboxcommand.d.ts +130 -0
  58. package/dist/ckboxconfig.d.ts +434 -0
  59. package/dist/ckboxediting.d.ts +65 -0
  60. package/dist/ckboximageedit/ckboximageeditcommand.d.ts +109 -0
  61. package/dist/ckboximageedit/ckboximageeditediting.d.ts +36 -0
  62. package/dist/ckboximageedit/ckboximageeditui.d.ts +32 -0
  63. package/dist/ckboximageedit/utils.d.ts +14 -0
  64. package/dist/ckboximageedit.d.ts +32 -0
  65. package/dist/ckboxui.d.ts +60 -0
  66. package/dist/ckboxuploadadapter.d.ts +41 -0
  67. package/dist/ckboxutils.d.ts +58 -0
  68. package/dist/index-content.css +4 -0
  69. package/dist/index-editor.css +46 -0
  70. package/dist/index.css +55 -0
  71. package/dist/index.css.map +1 -0
  72. package/dist/index.d.ts +21 -0
  73. package/dist/index.js +1787 -0
  74. package/dist/index.js.map +1 -0
  75. package/dist/translations/ar.d.ts +8 -0
  76. package/dist/translations/ar.js +5 -0
  77. package/dist/translations/ar.umd.js +11 -0
  78. package/dist/translations/az.d.ts +8 -0
  79. package/dist/translations/az.js +5 -0
  80. package/dist/translations/az.umd.js +11 -0
  81. package/dist/translations/bg.d.ts +8 -0
  82. package/dist/translations/bg.js +5 -0
  83. package/dist/translations/bg.umd.js +11 -0
  84. package/dist/translations/bn.d.ts +8 -0
  85. package/dist/translations/bn.js +5 -0
  86. package/dist/translations/bn.umd.js +11 -0
  87. package/dist/translations/ca.d.ts +8 -0
  88. package/dist/translations/ca.js +5 -0
  89. package/dist/translations/ca.umd.js +11 -0
  90. package/dist/translations/cs.d.ts +8 -0
  91. package/dist/translations/cs.js +5 -0
  92. package/dist/translations/cs.umd.js +11 -0
  93. package/dist/translations/da.d.ts +8 -0
  94. package/dist/translations/da.js +5 -0
  95. package/dist/translations/da.umd.js +11 -0
  96. package/dist/translations/de.d.ts +8 -0
  97. package/dist/translations/de.js +5 -0
  98. package/dist/translations/de.umd.js +11 -0
  99. package/dist/translations/el.d.ts +8 -0
  100. package/dist/translations/el.js +5 -0
  101. package/dist/translations/el.umd.js +11 -0
  102. package/dist/translations/en-au.d.ts +8 -0
  103. package/dist/translations/en-au.js +5 -0
  104. package/dist/translations/en-au.umd.js +11 -0
  105. package/dist/translations/en.d.ts +8 -0
  106. package/dist/translations/en.js +5 -0
  107. package/dist/translations/en.umd.js +11 -0
  108. package/dist/translations/es-co.d.ts +8 -0
  109. package/dist/translations/es-co.js +5 -0
  110. package/dist/translations/es-co.umd.js +11 -0
  111. package/dist/translations/es.d.ts +8 -0
  112. package/dist/translations/es.js +5 -0
  113. package/dist/translations/es.umd.js +11 -0
  114. package/dist/translations/et.d.ts +8 -0
  115. package/dist/translations/et.js +5 -0
  116. package/dist/translations/et.umd.js +11 -0
  117. package/dist/translations/fa.d.ts +8 -0
  118. package/dist/translations/fa.js +5 -0
  119. package/dist/translations/fa.umd.js +11 -0
  120. package/dist/translations/fi.d.ts +8 -0
  121. package/dist/translations/fi.js +5 -0
  122. package/dist/translations/fi.umd.js +11 -0
  123. package/dist/translations/fr.d.ts +8 -0
  124. package/dist/translations/fr.js +5 -0
  125. package/dist/translations/fr.umd.js +11 -0
  126. package/dist/translations/gl.d.ts +8 -0
  127. package/dist/translations/gl.js +5 -0
  128. package/dist/translations/gl.umd.js +11 -0
  129. package/dist/translations/he.d.ts +8 -0
  130. package/dist/translations/he.js +5 -0
  131. package/dist/translations/he.umd.js +11 -0
  132. package/dist/translations/hi.d.ts +8 -0
  133. package/dist/translations/hi.js +5 -0
  134. package/dist/translations/hi.umd.js +11 -0
  135. package/dist/translations/hr.d.ts +8 -0
  136. package/dist/translations/hr.js +5 -0
  137. package/dist/translations/hr.umd.js +11 -0
  138. package/dist/translations/hu.d.ts +8 -0
  139. package/dist/translations/hu.js +5 -0
  140. package/dist/translations/hu.umd.js +11 -0
  141. package/dist/translations/id.d.ts +8 -0
  142. package/dist/translations/id.js +5 -0
  143. package/dist/translations/id.umd.js +11 -0
  144. package/dist/translations/it.d.ts +8 -0
  145. package/dist/translations/it.js +5 -0
  146. package/dist/translations/it.umd.js +11 -0
  147. package/dist/translations/ja.d.ts +8 -0
  148. package/dist/translations/ja.js +5 -0
  149. package/dist/translations/ja.umd.js +11 -0
  150. package/dist/translations/ko.d.ts +8 -0
  151. package/dist/translations/ko.js +5 -0
  152. package/dist/translations/ko.umd.js +11 -0
  153. package/dist/translations/lt.d.ts +8 -0
  154. package/dist/translations/lt.js +5 -0
  155. package/dist/translations/lt.umd.js +11 -0
  156. package/dist/translations/lv.d.ts +8 -0
  157. package/dist/translations/lv.js +5 -0
  158. package/dist/translations/lv.umd.js +11 -0
  159. package/dist/translations/ms.d.ts +8 -0
  160. package/dist/translations/ms.js +5 -0
  161. package/dist/translations/ms.umd.js +11 -0
  162. package/dist/translations/nl.d.ts +8 -0
  163. package/dist/translations/nl.js +5 -0
  164. package/dist/translations/nl.umd.js +11 -0
  165. package/dist/translations/no.d.ts +8 -0
  166. package/dist/translations/no.js +5 -0
  167. package/dist/translations/no.umd.js +11 -0
  168. package/dist/translations/pl.d.ts +8 -0
  169. package/dist/translations/pl.js +5 -0
  170. package/dist/translations/pl.umd.js +11 -0
  171. package/dist/translations/pt-br.d.ts +8 -0
  172. package/dist/translations/pt-br.js +5 -0
  173. package/dist/translations/pt-br.umd.js +11 -0
  174. package/dist/translations/pt.d.ts +8 -0
  175. package/dist/translations/pt.js +5 -0
  176. package/dist/translations/pt.umd.js +11 -0
  177. package/dist/translations/ro.d.ts +8 -0
  178. package/dist/translations/ro.js +5 -0
  179. package/dist/translations/ro.umd.js +11 -0
  180. package/dist/translations/ru.d.ts +8 -0
  181. package/dist/translations/ru.js +5 -0
  182. package/dist/translations/ru.umd.js +11 -0
  183. package/dist/translations/sk.d.ts +8 -0
  184. package/dist/translations/sk.js +5 -0
  185. package/dist/translations/sk.umd.js +11 -0
  186. package/dist/translations/sq.d.ts +8 -0
  187. package/dist/translations/sq.js +5 -0
  188. package/dist/translations/sq.umd.js +11 -0
  189. package/dist/translations/sr-latn.d.ts +8 -0
  190. package/dist/translations/sr-latn.js +5 -0
  191. package/dist/translations/sr-latn.umd.js +11 -0
  192. package/dist/translations/sr.d.ts +8 -0
  193. package/dist/translations/sr.js +5 -0
  194. package/dist/translations/sr.umd.js +11 -0
  195. package/dist/translations/sv.d.ts +8 -0
  196. package/dist/translations/sv.js +5 -0
  197. package/dist/translations/sv.umd.js +11 -0
  198. package/dist/translations/th.d.ts +8 -0
  199. package/dist/translations/th.js +5 -0
  200. package/dist/translations/th.umd.js +11 -0
  201. package/dist/translations/tr.d.ts +8 -0
  202. package/dist/translations/tr.js +5 -0
  203. package/dist/translations/tr.umd.js +11 -0
  204. package/dist/translations/ug.d.ts +8 -0
  205. package/dist/translations/ug.js +5 -0
  206. package/dist/translations/ug.umd.js +11 -0
  207. package/dist/translations/uk.d.ts +8 -0
  208. package/dist/translations/uk.js +5 -0
  209. package/dist/translations/uk.umd.js +11 -0
  210. package/dist/translations/ur.d.ts +8 -0
  211. package/dist/translations/ur.js +5 -0
  212. package/dist/translations/ur.umd.js +11 -0
  213. package/dist/translations/uz.d.ts +8 -0
  214. package/dist/translations/uz.js +5 -0
  215. package/dist/translations/uz.umd.js +11 -0
  216. package/dist/translations/vi.d.ts +8 -0
  217. package/dist/translations/vi.js +5 -0
  218. package/dist/translations/vi.umd.js +11 -0
  219. package/dist/translations/zh-cn.d.ts +8 -0
  220. package/dist/translations/zh-cn.js +5 -0
  221. package/dist/translations/zh-cn.umd.js +11 -0
  222. package/dist/translations/zh.d.ts +8 -0
  223. package/dist/translations/zh.js +5 -0
  224. package/dist/translations/zh.umd.js +11 -0
  225. package/dist/utils.d.ts +67 -0
  226. package/lang/contexts.json +10 -0
  227. package/lang/translations/ar.po +50 -0
  228. package/lang/translations/az.po +50 -0
  229. package/lang/translations/bg.po +50 -0
  230. package/lang/translations/bn.po +50 -0
  231. package/lang/translations/ca.po +50 -0
  232. package/lang/translations/cs.po +50 -0
  233. package/lang/translations/da.po +50 -0
  234. package/lang/translations/de.po +50 -0
  235. package/lang/translations/el.po +50 -0
  236. package/lang/translations/en-au.po +50 -0
  237. package/lang/translations/en.po +50 -0
  238. package/lang/translations/es-co.po +50 -0
  239. package/lang/translations/es.po +50 -0
  240. package/lang/translations/et.po +50 -0
  241. package/lang/translations/fa.po +50 -0
  242. package/lang/translations/fi.po +50 -0
  243. package/lang/translations/fr.po +50 -0
  244. package/lang/translations/gl.po +50 -0
  245. package/lang/translations/he.po +50 -0
  246. package/lang/translations/hi.po +50 -0
  247. package/lang/translations/hr.po +50 -0
  248. package/lang/translations/hu.po +50 -0
  249. package/lang/translations/id.po +50 -0
  250. package/lang/translations/it.po +50 -0
  251. package/lang/translations/ja.po +50 -0
  252. package/lang/translations/ko.po +50 -0
  253. package/lang/translations/lt.po +50 -0
  254. package/lang/translations/lv.po +50 -0
  255. package/lang/translations/ms.po +50 -0
  256. package/lang/translations/nl.po +50 -0
  257. package/lang/translations/no.po +50 -0
  258. package/lang/translations/pl.po +50 -0
  259. package/lang/translations/pt-br.po +50 -0
  260. package/lang/translations/pt.po +50 -0
  261. package/lang/translations/ro.po +50 -0
  262. package/lang/translations/ru.po +50 -0
  263. package/lang/translations/sk.po +50 -0
  264. package/lang/translations/sq.po +50 -0
  265. package/lang/translations/sr-latn.po +50 -0
  266. package/lang/translations/sr.po +50 -0
  267. package/lang/translations/sv.po +50 -0
  268. package/lang/translations/th.po +50 -0
  269. package/lang/translations/tr.po +50 -0
  270. package/lang/translations/ug.po +50 -0
  271. package/lang/translations/uk.po +50 -0
  272. package/lang/translations/ur.po +50 -0
  273. package/lang/translations/uz.po +50 -0
  274. package/lang/translations/vi.po +50 -0
  275. package/lang/translations/zh-cn.po +50 -0
  276. package/lang/translations/zh.po +50 -0
  277. package/package.json +45 -0
  278. package/src/augmentation.d.ts +32 -0
  279. package/src/augmentation.js +5 -0
  280. package/src/ckbox.d.ts +37 -0
  281. package/src/ckbox.js +43 -0
  282. package/src/ckboxcommand.d.ts +126 -0
  283. package/src/ckboxcommand.js +364 -0
  284. package/src/ckboxconfig.d.ts +430 -0
  285. package/src/ckboxconfig.js +5 -0
  286. package/src/ckboxediting.d.ts +61 -0
  287. package/src/ckboxediting.js +389 -0
  288. package/src/ckboximageedit/ckboximageeditcommand.d.ts +105 -0
  289. package/src/ckboximageedit/ckboximageeditcommand.js +310 -0
  290. package/src/ckboximageedit/ckboximageeditediting.d.ts +32 -0
  291. package/src/ckboximageedit/ckboximageeditediting.js +42 -0
  292. package/src/ckboximageedit/ckboximageeditui.d.ts +28 -0
  293. package/src/ckboximageedit/ckboximageeditui.js +57 -0
  294. package/src/ckboximageedit/utils.d.ts +10 -0
  295. package/src/ckboximageedit/utils.js +48 -0
  296. package/src/ckboximageedit.d.ts +28 -0
  297. package/src/ckboximageedit.js +34 -0
  298. package/src/ckboxui.d.ts +56 -0
  299. package/src/ckboxui.js +136 -0
  300. package/src/ckboxuploadadapter.d.ts +37 -0
  301. package/src/ckboxuploadadapter.js +136 -0
  302. package/src/ckboxutils.d.ts +54 -0
  303. package/src/ckboxutils.js +189 -0
  304. package/src/index.d.ts +17 -0
  305. package/src/index.js +14 -0
  306. package/src/utils.d.ts +63 -0
  307. package/src/utils.js +175 -0
  308. package/theme/ckboximageedit.css +53 -0
  309. package/theme/icons/ckbox-image-edit.svg +1 -0
@@ -0,0 +1,310 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2024, 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
+ /* globals document, console, AbortController, URL, window */
6
+ /**
7
+ * @module ckbox/ckboximageedit/ckboximageeditcommand
8
+ */
9
+ import { Command, PendingActions } from 'ckeditor5/src/core.js';
10
+ import { CKEditorError, abortableDebounce, createElement, retry, delay } from 'ckeditor5/src/utils.js';
11
+ import { Notification } from 'ckeditor5/src/ui.js';
12
+ import { isEqual } from 'lodash-es';
13
+ import { sendHttpRequest } from '../utils.js';
14
+ import { prepareImageAssetAttributes } from '../ckboxcommand.js';
15
+ import { createEditabilityChecker } from './utils.js';
16
+ import CKBoxUtils from '../ckboxutils.js';
17
+ /**
18
+ * The CKBox edit image command.
19
+ *
20
+ * Opens the CKBox dialog for editing the image.
21
+ */
22
+ export default class CKBoxImageEditCommand extends Command {
23
+ /**
24
+ * @inheritDoc
25
+ */
26
+ constructor(editor) {
27
+ super(editor);
28
+ /**
29
+ * The DOM element that acts as a mounting point for the CKBox Edit Image dialog.
30
+ */
31
+ this._wrapper = null;
32
+ /**
33
+ * The states of image processing in progress.
34
+ */
35
+ this._processInProgress = new Set();
36
+ /**
37
+ * CKBox's onClose function runs before the final cleanup, potentially causing
38
+ * page layout changes after it finishes. To address this, we use a setTimeout hack
39
+ * to ensure that floating elements on the page maintain their correct position.
40
+ *
41
+ * See: https://github.com/ckeditor/ckeditor5/issues/16153.
42
+ */
43
+ this._updateUiDelayed = delay(() => this.editor.ui.update(), 0);
44
+ this.value = false;
45
+ this._canEdit = createEditabilityChecker(editor.config.get('ckbox.allowExternalImagesEditing'));
46
+ this._prepareOptions = abortableDebounce((signal, state) => this._prepareOptionsAbortable(signal, state));
47
+ this._prepareListeners();
48
+ }
49
+ /**
50
+ * @inheritDoc
51
+ */
52
+ refresh() {
53
+ const editor = this.editor;
54
+ this.value = this._getValue();
55
+ const selectedElement = editor.model.document.selection.getSelectedElement();
56
+ this.isEnabled =
57
+ !!selectedElement &&
58
+ this._canEdit(selectedElement) &&
59
+ !this._checkIfElementIsBeingProcessed(selectedElement);
60
+ }
61
+ /**
62
+ * Opens the CKBox Image Editor dialog for editing the image.
63
+ */
64
+ execute() {
65
+ if (this._getValue()) {
66
+ return;
67
+ }
68
+ const wrapper = createElement(document, 'div', { class: 'ck ckbox-wrapper' });
69
+ this._wrapper = wrapper;
70
+ this.value = true;
71
+ document.body.appendChild(this._wrapper);
72
+ const imageElement = this.editor.model.document.selection.getSelectedElement();
73
+ const processingState = {
74
+ element: imageElement,
75
+ controller: new AbortController()
76
+ };
77
+ this._prepareOptions(processingState).then(options => window.CKBox.mountImageEditor(wrapper, options), error => {
78
+ const editor = this.editor;
79
+ const t = editor.t;
80
+ const notification = editor.plugins.get(Notification);
81
+ notification.showWarning(t('Failed to determine category of edited image.'), {
82
+ namespace: 'ckbox'
83
+ });
84
+ console.error(error);
85
+ this._handleImageEditorClose();
86
+ });
87
+ }
88
+ /**
89
+ * @inheritDoc
90
+ */
91
+ destroy() {
92
+ this._handleImageEditorClose();
93
+ this._prepareOptions.abort();
94
+ this._updateUiDelayed.cancel();
95
+ for (const state of this._processInProgress.values()) {
96
+ state.controller.abort();
97
+ }
98
+ super.destroy();
99
+ }
100
+ /**
101
+ * Indicates if the CKBox Image Editor dialog is already opened.
102
+ */
103
+ _getValue() {
104
+ return this._wrapper !== null;
105
+ }
106
+ /**
107
+ * Creates the options object for the CKBox Image Editor dialog.
108
+ */
109
+ async _prepareOptionsAbortable(signal, state) {
110
+ const editor = this.editor;
111
+ const ckboxConfig = editor.config.get('ckbox');
112
+ const ckboxUtils = editor.plugins.get(CKBoxUtils);
113
+ const { element } = state;
114
+ let imageMountOptions;
115
+ const ckboxImageId = element.getAttribute('ckboxImageId');
116
+ if (ckboxImageId) {
117
+ imageMountOptions = {
118
+ assetId: ckboxImageId
119
+ };
120
+ }
121
+ else {
122
+ const imageUrl = new URL(element.getAttribute('src'), document.baseURI).href;
123
+ const uploadCategoryId = await ckboxUtils.getCategoryIdForFile(imageUrl, { signal });
124
+ imageMountOptions = {
125
+ imageUrl,
126
+ uploadCategoryId
127
+ };
128
+ }
129
+ return {
130
+ ...imageMountOptions,
131
+ imageEditing: {
132
+ allowOverwrite: false
133
+ },
134
+ tokenUrl: ckboxConfig.tokenUrl,
135
+ ...(ckboxConfig.serviceOrigin && { serviceOrigin: ckboxConfig.serviceOrigin }),
136
+ onClose: () => this._handleImageEditorClose(),
137
+ onSave: (asset) => this._handleImageEditorSave(state, asset)
138
+ };
139
+ }
140
+ /**
141
+ * Initializes event lister for an event of removing an image.
142
+ */
143
+ _prepareListeners() {
144
+ // Abort editing processing when the image has been removed.
145
+ this.listenTo(this.editor.model.document, 'change:data', () => {
146
+ const processingStates = this._getProcessingStatesOfDeletedImages();
147
+ processingStates.forEach(processingState => {
148
+ processingState.controller.abort();
149
+ });
150
+ });
151
+ }
152
+ /**
153
+ * Gets processing states of images that have been deleted in the mean time.
154
+ */
155
+ _getProcessingStatesOfDeletedImages() {
156
+ const states = [];
157
+ for (const state of this._processInProgress.values()) {
158
+ if (state.element.root.rootName == '$graveyard') {
159
+ states.push(state);
160
+ }
161
+ }
162
+ return states;
163
+ }
164
+ _checkIfElementIsBeingProcessed(selectedElement) {
165
+ for (const { element } of this._processInProgress) {
166
+ if (isEqual(element, selectedElement)) {
167
+ return true;
168
+ }
169
+ }
170
+ return false;
171
+ }
172
+ /**
173
+ * Closes the CKBox Image Editor dialog.
174
+ */
175
+ _handleImageEditorClose() {
176
+ if (!this._wrapper) {
177
+ return;
178
+ }
179
+ this._wrapper.remove();
180
+ this._wrapper = null;
181
+ this.editor.editing.view.focus();
182
+ this._updateUiDelayed();
183
+ this.refresh();
184
+ }
185
+ /**
186
+ * Save edited image. In case server respond with "success" replace with edited image,
187
+ * otherwise show notification error.
188
+ */
189
+ _handleImageEditorSave(state, asset) {
190
+ const t = this.editor.locale.t;
191
+ const notification = this.editor.plugins.get(Notification);
192
+ const pendingActions = this.editor.plugins.get(PendingActions);
193
+ const action = pendingActions.add(t('Processing the edited image.'));
194
+ this._processInProgress.add(state);
195
+ this._showImageProcessingIndicator(state.element, asset);
196
+ this.refresh();
197
+ this._waitForAssetProcessed(asset.data.id, state.controller.signal)
198
+ .then(asset => {
199
+ this._replaceImage(state.element, asset);
200
+ }, error => {
201
+ // Remove processing indicator. It was added only to ViewElement.
202
+ this.editor.editing.reconvertItem(state.element);
203
+ if (state.controller.signal.aborted) {
204
+ return;
205
+ }
206
+ if (!error || error instanceof CKEditorError) {
207
+ notification.showWarning(t('Server failed to process the image.'), {
208
+ namespace: 'ckbox'
209
+ });
210
+ }
211
+ else {
212
+ console.error(error);
213
+ }
214
+ }).finally(() => {
215
+ this._processInProgress.delete(state);
216
+ pendingActions.remove(action);
217
+ this.refresh();
218
+ });
219
+ }
220
+ /**
221
+ * Get asset's status on server. If server responds with "success" status then
222
+ * image is already proceeded and ready for saving.
223
+ */
224
+ async _getAssetStatusFromServer(id, signal) {
225
+ const ckboxUtils = this.editor.plugins.get(CKBoxUtils);
226
+ const url = new URL('assets/' + id, this.editor.config.get('ckbox.serviceOrigin'));
227
+ const response = await sendHttpRequest({
228
+ url,
229
+ signal,
230
+ authorization: (await ckboxUtils.getToken()).value
231
+ });
232
+ const status = response.metadata.metadataProcessingStatus;
233
+ if (!status || status == 'queued') {
234
+ /**
235
+ * Image has not been processed yet.
236
+ *
237
+ * @error ckbox-image-not-processed
238
+ */
239
+ throw new CKEditorError('ckbox-image-not-processed');
240
+ }
241
+ return { data: { ...response } };
242
+ }
243
+ /**
244
+ * Waits for an asset to be processed.
245
+ * It retries retrieving asset status from the server in case of failure.
246
+ */
247
+ async _waitForAssetProcessed(id, signal) {
248
+ const result = await retry(() => this._getAssetStatusFromServer(id, signal), {
249
+ signal,
250
+ maxAttempts: 5
251
+ });
252
+ if (result.data.metadata.metadataProcessingStatus != 'success') {
253
+ /**
254
+ * The image processing failed.
255
+ *
256
+ * @error ckbox-image-processing-failed
257
+ */
258
+ throw new CKEditorError('ckbox-image-processing-failed');
259
+ }
260
+ return result;
261
+ }
262
+ /**
263
+ * Shows processing indicator while image is processing.
264
+ *
265
+ * @param asset Data about certain asset.
266
+ */
267
+ _showImageProcessingIndicator(element, asset) {
268
+ const editor = this.editor;
269
+ editor.editing.view.change(writer => {
270
+ const imageElementView = editor.editing.mapper.toViewElement(element);
271
+ const imageUtils = this.editor.plugins.get('ImageUtils');
272
+ const img = imageUtils.findViewImgElement(imageElementView);
273
+ writer.removeStyle('aspect-ratio', img);
274
+ writer.setAttribute('width', asset.data.metadata.width, img);
275
+ writer.setAttribute('height', asset.data.metadata.height, img);
276
+ writer.setStyle('width', `${asset.data.metadata.width}px`, img);
277
+ writer.setStyle('height', `${asset.data.metadata.height}px`, img);
278
+ writer.addClass('image-processing', imageElementView);
279
+ });
280
+ }
281
+ /**
282
+ * Replace the edited image with the new one.
283
+ */
284
+ _replaceImage(element, asset) {
285
+ const editor = this.editor;
286
+ const { imageFallbackUrl, imageSources, imageWidth, imageHeight, imagePlaceholder } = prepareImageAssetAttributes(asset);
287
+ const previousSelectionRanges = Array.from(editor.model.document.selection.getRanges());
288
+ editor.model.change(writer => {
289
+ writer.setSelection(element, 'on');
290
+ editor.execute('insertImage', {
291
+ imageType: element.is('element', 'imageInline') ? 'imageInline' : null,
292
+ source: {
293
+ src: imageFallbackUrl,
294
+ sources: imageSources,
295
+ width: imageWidth,
296
+ height: imageHeight,
297
+ ...(imagePlaceholder ? { placeholder: imagePlaceholder } : null),
298
+ ...(element.hasAttribute('alt') ? { alt: element.getAttribute('alt') } : null)
299
+ }
300
+ });
301
+ const previousChildren = element.getChildren();
302
+ element = editor.model.document.selection.getSelectedElement();
303
+ for (const child of previousChildren) {
304
+ writer.append(writer.cloneElement(child), element);
305
+ }
306
+ writer.setAttribute('ckboxImageId', asset.data.id, element);
307
+ writer.setSelection(previousSelectionRanges);
308
+ });
309
+ }
310
+ }
@@ -0,0 +1,32 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2024, 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/ckboximageedit/ckboximageeditediting
7
+ */
8
+ import { PendingActions, Plugin } from 'ckeditor5/src/core.js';
9
+ import { Notification } from 'ckeditor5/src/ui.js';
10
+ import CKBoxEditing from '../ckboxediting.js';
11
+ import CKBoxUtils from '../ckboxutils.js';
12
+ /**
13
+ * The CKBox image edit editing plugin.
14
+ */
15
+ export default class CKBoxImageEditEditing extends Plugin {
16
+ /**
17
+ * @inheritDoc
18
+ */
19
+ static get pluginName(): "CKBoxImageEditEditing";
20
+ /**
21
+ * @inheritDoc
22
+ */
23
+ static get isOfficialPlugin(): true;
24
+ /**
25
+ * @inheritDoc
26
+ */
27
+ static get requires(): readonly [typeof CKBoxEditing, typeof CKBoxUtils, typeof PendingActions, typeof Notification, "ImageUtils", "ImageEditing"];
28
+ /**
29
+ * @inheritDoc
30
+ */
31
+ init(): void;
32
+ }
@@ -0,0 +1,42 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2024, 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/ckboximageedit/ckboximageeditediting
7
+ */
8
+ import { PendingActions, Plugin } from 'ckeditor5/src/core.js';
9
+ import { Notification } from 'ckeditor5/src/ui.js';
10
+ import CKBoxImageEditCommand from './ckboximageeditcommand.js';
11
+ import CKBoxEditing from '../ckboxediting.js';
12
+ import CKBoxUtils from '../ckboxutils.js';
13
+ /**
14
+ * The CKBox image edit editing plugin.
15
+ */
16
+ export default class CKBoxImageEditEditing extends Plugin {
17
+ /**
18
+ * @inheritDoc
19
+ */
20
+ static get pluginName() {
21
+ return 'CKBoxImageEditEditing';
22
+ }
23
+ /**
24
+ * @inheritDoc
25
+ */
26
+ static get isOfficialPlugin() {
27
+ return true;
28
+ }
29
+ /**
30
+ * @inheritDoc
31
+ */
32
+ static get requires() {
33
+ return [CKBoxEditing, CKBoxUtils, PendingActions, Notification, 'ImageUtils', 'ImageEditing'];
34
+ }
35
+ /**
36
+ * @inheritDoc
37
+ */
38
+ init() {
39
+ const { editor } = this;
40
+ editor.commands.add('ckboxImageEdit', new CKBoxImageEditCommand(editor));
41
+ }
42
+ }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2024, 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/ckboximageedit/ckboximageeditui
7
+ */
8
+ import { Plugin } from 'ckeditor5/src/core.js';
9
+ /**
10
+ * The UI plugin of the CKBox image edit feature.
11
+ *
12
+ * It registers the `'ckboxImageEdit'` UI button in the editor's {@link module:ui/componentfactory~ComponentFactory component factory}
13
+ * that allows you to open the CKBox dialog and edit the image.
14
+ */
15
+ export default class CKBoxImageEditUI extends Plugin {
16
+ /**
17
+ * @inheritDoc
18
+ */
19
+ static get pluginName(): "CKBoxImageEditUI";
20
+ /**
21
+ * @inheritDoc
22
+ */
23
+ static get isOfficialPlugin(): true;
24
+ /**
25
+ * @inheritDoc
26
+ */
27
+ init(): void;
28
+ }
@@ -0,0 +1,57 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2024, 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/ckboximageedit/ckboximageeditui
7
+ */
8
+ import { Plugin } from 'ckeditor5/src/core.js';
9
+ import { ButtonView } from 'ckeditor5/src/ui.js';
10
+ import ckboxImageEditIcon from '../../theme/icons/ckbox-image-edit.svg';
11
+ /**
12
+ * The UI plugin of the CKBox image edit feature.
13
+ *
14
+ * It registers the `'ckboxImageEdit'` UI button in the editor's {@link module:ui/componentfactory~ComponentFactory component factory}
15
+ * that allows you to open the CKBox dialog and edit the image.
16
+ */
17
+ export default class CKBoxImageEditUI extends Plugin {
18
+ /**
19
+ * @inheritDoc
20
+ */
21
+ static get pluginName() {
22
+ return 'CKBoxImageEditUI';
23
+ }
24
+ /**
25
+ * @inheritDoc
26
+ */
27
+ static get isOfficialPlugin() {
28
+ return true;
29
+ }
30
+ /**
31
+ * @inheritDoc
32
+ */
33
+ init() {
34
+ const editor = this.editor;
35
+ editor.ui.componentFactory.add('ckboxImageEdit', locale => {
36
+ const command = editor.commands.get('ckboxImageEdit');
37
+ const uploadImageCommand = editor.commands.get('uploadImage');
38
+ const view = new ButtonView(locale);
39
+ const t = locale.t;
40
+ view.set({
41
+ icon: ckboxImageEditIcon,
42
+ tooltip: true
43
+ });
44
+ view.bind('label').to(uploadImageCommand, 'isAccessAllowed', isAccessAllowed => isAccessAllowed ?
45
+ t('Edit image') :
46
+ t('You have no image editing permissions.'));
47
+ view.bind('isOn').to(command, 'value', command, 'isEnabled', (value, isEnabled) => value && isEnabled);
48
+ view.bind('isEnabled').to(command);
49
+ // Execute the command.
50
+ this.listenTo(view, 'execute', () => {
51
+ editor.execute('ckboxImageEdit');
52
+ editor.editing.view.focus();
53
+ });
54
+ return view;
55
+ });
56
+ }
57
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2024, 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 type { Element } from 'ckeditor5/src/engine.js';
6
+ import type { CKBoxConfig } from '../ckboxconfig.js';
7
+ /**
8
+ * @internal
9
+ */
10
+ export declare function createEditabilityChecker(allowExternalImagesEditing: CKBoxConfig['allowExternalImagesEditing']): (element: Element) => boolean;
@@ -0,0 +1,48 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2024, 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/ckboximageedit/utils
7
+ */
8
+ import { global } from 'ckeditor5/src/utils.js';
9
+ /**
10
+ * @internal
11
+ */
12
+ export function createEditabilityChecker(allowExternalImagesEditing) {
13
+ const checkUrl = createUrlChecker(allowExternalImagesEditing);
14
+ return element => {
15
+ const isImageElement = element.is('element', 'imageInline') ||
16
+ element.is('element', 'imageBlock');
17
+ if (!isImageElement) {
18
+ return false;
19
+ }
20
+ if (element.hasAttribute('ckboxImageId')) {
21
+ return true;
22
+ }
23
+ if (element.hasAttribute('src')) {
24
+ return checkUrl(element.getAttribute('src'));
25
+ }
26
+ return false;
27
+ };
28
+ }
29
+ function createUrlChecker(allowExternalImagesEditing) {
30
+ if (Array.isArray(allowExternalImagesEditing)) {
31
+ const urlMatchers = allowExternalImagesEditing.map(createUrlChecker);
32
+ return src => urlMatchers.some(matcher => matcher(src));
33
+ }
34
+ if (allowExternalImagesEditing == 'origin') {
35
+ const origin = global.window.location.origin;
36
+ return src => new URL(src, global.document.baseURI).origin == origin;
37
+ }
38
+ if (typeof allowExternalImagesEditing == 'function') {
39
+ return allowExternalImagesEditing;
40
+ }
41
+ if (allowExternalImagesEditing instanceof RegExp) {
42
+ return src => !!(src.match(allowExternalImagesEditing) ||
43
+ src.replace(/^https?:\/\//, '').match(allowExternalImagesEditing));
44
+ }
45
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
46
+ const shouldBeUndefned = allowExternalImagesEditing;
47
+ return () => false;
48
+ }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2024, 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/ckboximageedit
7
+ */
8
+ import { Plugin } from 'ckeditor5/src/core.js';
9
+ import CKBoxImageEditEditing from './ckboximageedit/ckboximageeditediting.js';
10
+ import CKBoxImageEditUI from './ckboximageedit/ckboximageeditui.js';
11
+ import '../theme/ckboximageedit.css';
12
+ /**
13
+ * The CKBox image edit feature.
14
+ */
15
+ export default class CKBoxImageEdit extends Plugin {
16
+ /**
17
+ * @inheritDoc
18
+ */
19
+ static get pluginName(): "CKBoxImageEdit";
20
+ /**
21
+ * @inheritDoc
22
+ */
23
+ static get isOfficialPlugin(): true;
24
+ /**
25
+ * @inheritDoc
26
+ */
27
+ static get requires(): readonly [typeof CKBoxImageEditEditing, typeof CKBoxImageEditUI];
28
+ }
@@ -0,0 +1,34 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2024, 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/ckboximageedit
7
+ */
8
+ import { Plugin } from 'ckeditor5/src/core.js';
9
+ import CKBoxImageEditEditing from './ckboximageedit/ckboximageeditediting.js';
10
+ import CKBoxImageEditUI from './ckboximageedit/ckboximageeditui.js';
11
+ import '../theme/ckboximageedit.css';
12
+ /**
13
+ * The CKBox image edit feature.
14
+ */
15
+ export default class CKBoxImageEdit extends Plugin {
16
+ /**
17
+ * @inheritDoc
18
+ */
19
+ static get pluginName() {
20
+ return 'CKBoxImageEdit';
21
+ }
22
+ /**
23
+ * @inheritDoc
24
+ */
25
+ static get isOfficialPlugin() {
26
+ return true;
27
+ }
28
+ /**
29
+ * @inheritDoc
30
+ */
31
+ static get requires() {
32
+ return [CKBoxImageEditEditing, CKBoxImageEditUI];
33
+ }
34
+ }
@@ -0,0 +1,56 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2024, 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/ckboxui
7
+ */
8
+ import { Plugin } from 'ckeditor5/src/core.js';
9
+ /**
10
+ * Introduces UI components for the `CKBox` plugin.
11
+ *
12
+ * The plugin introduces two UI components to the {@link module:ui/componentfactory~ComponentFactory UI component factory}:
13
+ *
14
+ * * the `'ckbox'` toolbar button,
15
+ * * the `'menuBar:ckbox'` menu bar component, which is by default added to the `'Insert'` menu.
16
+ *
17
+ * It also integrates with the `insertImage` toolbar component and `menuBar:insertImage` menu component.
18
+ */
19
+ export default class CKBoxUI extends Plugin {
20
+ /**
21
+ * @inheritDoc
22
+ */
23
+ static get pluginName(): "CKBoxUI";
24
+ /**
25
+ * @inheritDoc
26
+ */
27
+ static get isOfficialPlugin(): true;
28
+ /**
29
+ * @inheritDoc
30
+ */
31
+ afterInit(): void;
32
+ /**
33
+ * Creates the base for various kinds of the button component provided by this feature.
34
+ */
35
+ private _createButton;
36
+ /**
37
+ * Creates a simple toolbar button for files management, with an icon and a tooltip.
38
+ */
39
+ private _createFileToolbarButton;
40
+ /**
41
+ * Creates a simple toolbar button for images management, with an icon and a tooltip.
42
+ */
43
+ private _createImageToolbarButton;
44
+ /**
45
+ * Creates a button for images management for the dropdown view, with an icon, text and no tooltip.
46
+ */
47
+ private _createImageDropdownButton;
48
+ /**
49
+ * Creates a button for files management for the menu bar.
50
+ */
51
+ private _createFileMenuBarButton;
52
+ /**
53
+ * Creates a button for images management for the menu bar.
54
+ */
55
+ private _createImageMenuBarButton;
56
+ }