@ckeditor/ckeditor5-image 47.6.1 → 48.0.0-alpha.1

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 (289) hide show
  1. package/LICENSE.md +1 -1
  2. package/ckeditor5-metadata.json +25 -25
  3. package/{src → dist}/autoimage.d.ts +4 -4
  4. package/{src → dist}/image/converters.d.ts +1 -1
  5. package/{src → dist}/image/imageblockediting.d.ts +2 -2
  6. package/{src → dist}/image/imageediting.d.ts +1 -1
  7. package/{src → dist}/image/imageinlineediting.d.ts +2 -2
  8. package/{src → dist}/image/imageloadobserver.d.ts +1 -1
  9. package/{src → dist}/image/imageplaceholder.d.ts +1 -1
  10. package/{src → dist}/image/imagetypecommand.d.ts +2 -2
  11. package/{src → dist}/image/insertimagecommand.d.ts +2 -2
  12. package/{src → dist}/image/replaceimagesourcecommand.d.ts +2 -2
  13. package/{src → dist}/image/ui/utils.d.ts +2 -2
  14. package/{src → dist}/image/utils.d.ts +2 -2
  15. package/{src → dist}/image.d.ts +1 -1
  16. package/{src → dist}/imageblock.d.ts +2 -2
  17. package/{src → dist}/imagecaption/imagecaptionediting.d.ts +2 -2
  18. package/{src → dist}/imagecaption/imagecaptionui.d.ts +1 -1
  19. package/{src → dist}/imagecaption/imagecaptionutils.d.ts +2 -2
  20. package/{src → dist}/imagecaption/toggleimagecaptioncommand.d.ts +1 -1
  21. package/{src → dist}/imagecaption.d.ts +1 -1
  22. package/{src → dist}/imageconfig.d.ts +25 -16
  23. package/{src → dist}/imageinline.d.ts +2 -2
  24. package/{src → dist}/imageinsert/imageinsertui.d.ts +3 -3
  25. package/{src → dist}/imageinsert/imageinsertviaurlui.d.ts +2 -2
  26. package/{src → dist}/imageinsert/ui/imageinsertformview.d.ts +2 -2
  27. package/{src → dist}/imageinsert/ui/imageinserturlview.d.ts +2 -2
  28. package/{src → dist}/imageinsert.d.ts +1 -1
  29. package/{src → dist}/imageinsertviaurl.d.ts +1 -1
  30. package/{src → dist}/imageresize/imagecustomresizeui.d.ts +2 -2
  31. package/{src → dist}/imageresize/imageresizebuttons.d.ts +1 -1
  32. package/{src → dist}/imageresize/imageresizeediting.d.ts +1 -1
  33. package/{src → dist}/imageresize/imageresizehandles.d.ts +2 -2
  34. package/{src → dist}/imageresize/resizeimagecommand.d.ts +1 -1
  35. package/{src → dist}/imageresize/ui/imagecustomresizeformview.d.ts +2 -4
  36. package/{src → dist}/imageresize/utils/getselectedimageeditornodes.d.ts +2 -2
  37. package/{src → dist}/imageresize/utils/getselectedimagepossibleresizerange.d.ts +1 -1
  38. package/{src → dist}/imageresize/utils/getselectedimagewidthinunits.d.ts +1 -1
  39. package/{src → dist}/imageresize.d.ts +1 -1
  40. package/{src → dist}/imagesizeattributes.d.ts +1 -1
  41. package/{src → dist}/imagestyle/converters.d.ts +2 -2
  42. package/{src → dist}/imagestyle/imagestylecommand.d.ts +2 -2
  43. package/{src → dist}/imagestyle/imagestyleediting.d.ts +1 -1
  44. package/{src → dist}/imagestyle/imagestyleui.d.ts +1 -1
  45. package/{src → dist}/imagestyle/utils.d.ts +1 -1
  46. package/{src → dist}/imagestyle.d.ts +1 -1
  47. package/{src → dist}/imagetextalternative/imagetextalternativecommand.d.ts +1 -1
  48. package/{src → dist}/imagetextalternative/imagetextalternativeediting.d.ts +1 -1
  49. package/{src → dist}/imagetextalternative/imagetextalternativeui.d.ts +2 -2
  50. package/{src → dist}/imagetextalternative/ui/textalternativeformview.d.ts +2 -4
  51. package/{src → dist}/imagetextalternative.d.ts +1 -1
  52. package/{src → dist}/imagetoolbar.d.ts +2 -2
  53. package/{src → dist}/imageupload/imageuploadediting.d.ts +5 -5
  54. package/{src → dist}/imageupload/imageuploadprogress.d.ts +1 -1
  55. package/{src → dist}/imageupload/imageuploadui.d.ts +1 -1
  56. package/{src → dist}/imageupload/uploadimagecommand.d.ts +2 -2
  57. package/{src → dist}/imageupload/utils.d.ts +1 -1
  58. package/{src → dist}/imageupload.d.ts +1 -1
  59. package/{src → dist}/imageutils.d.ts +2 -2
  60. package/dist/index-content.css +97 -100
  61. package/dist/index-editor.css +313 -190
  62. package/dist/index.css +388 -458
  63. package/dist/index.css.map +1 -1
  64. package/dist/index.js +1 -2
  65. package/dist/index.js.map +1 -1
  66. package/{src → dist}/pictureediting.d.ts +1 -1
  67. package/package.json +29 -53
  68. package/build/image.js +0 -5
  69. package/build/translations/af.js +0 -1
  70. package/build/translations/ar.js +0 -1
  71. package/build/translations/ast.js +0 -1
  72. package/build/translations/az.js +0 -1
  73. package/build/translations/be.js +0 -1
  74. package/build/translations/bg.js +0 -1
  75. package/build/translations/bn.js +0 -1
  76. package/build/translations/bs.js +0 -1
  77. package/build/translations/ca.js +0 -1
  78. package/build/translations/cs.js +0 -1
  79. package/build/translations/da.js +0 -1
  80. package/build/translations/de-ch.js +0 -1
  81. package/build/translations/de.js +0 -1
  82. package/build/translations/el.js +0 -1
  83. package/build/translations/en-au.js +0 -1
  84. package/build/translations/en-gb.js +0 -1
  85. package/build/translations/eo.js +0 -1
  86. package/build/translations/es-co.js +0 -1
  87. package/build/translations/es.js +0 -1
  88. package/build/translations/et.js +0 -1
  89. package/build/translations/eu.js +0 -1
  90. package/build/translations/fa.js +0 -1
  91. package/build/translations/fi.js +0 -1
  92. package/build/translations/fr.js +0 -1
  93. package/build/translations/gl.js +0 -1
  94. package/build/translations/gu.js +0 -1
  95. package/build/translations/he.js +0 -1
  96. package/build/translations/hi.js +0 -1
  97. package/build/translations/hr.js +0 -1
  98. package/build/translations/hu.js +0 -1
  99. package/build/translations/hy.js +0 -1
  100. package/build/translations/id.js +0 -1
  101. package/build/translations/it.js +0 -1
  102. package/build/translations/ja.js +0 -1
  103. package/build/translations/jv.js +0 -1
  104. package/build/translations/kk.js +0 -1
  105. package/build/translations/km.js +0 -1
  106. package/build/translations/kn.js +0 -1
  107. package/build/translations/ko.js +0 -1
  108. package/build/translations/ku.js +0 -1
  109. package/build/translations/lt.js +0 -1
  110. package/build/translations/lv.js +0 -1
  111. package/build/translations/ms.js +0 -1
  112. package/build/translations/nb.js +0 -1
  113. package/build/translations/ne.js +0 -1
  114. package/build/translations/nl.js +0 -1
  115. package/build/translations/no.js +0 -1
  116. package/build/translations/oc.js +0 -1
  117. package/build/translations/pl.js +0 -1
  118. package/build/translations/pt-br.js +0 -1
  119. package/build/translations/pt.js +0 -1
  120. package/build/translations/ro.js +0 -1
  121. package/build/translations/ru.js +0 -1
  122. package/build/translations/si.js +0 -1
  123. package/build/translations/sk.js +0 -1
  124. package/build/translations/sl.js +0 -1
  125. package/build/translations/sq.js +0 -1
  126. package/build/translations/sr-latn.js +0 -1
  127. package/build/translations/sr.js +0 -1
  128. package/build/translations/sv.js +0 -1
  129. package/build/translations/th.js +0 -1
  130. package/build/translations/ti.js +0 -1
  131. package/build/translations/tk.js +0 -1
  132. package/build/translations/tr.js +0 -1
  133. package/build/translations/tt.js +0 -1
  134. package/build/translations/ug.js +0 -1
  135. package/build/translations/uk.js +0 -1
  136. package/build/translations/ur.js +0 -1
  137. package/build/translations/uz.js +0 -1
  138. package/build/translations/vi.js +0 -1
  139. package/build/translations/zh-cn.js +0 -1
  140. package/build/translations/zh.js +0 -1
  141. package/lang/contexts.json +0 -48
  142. package/lang/translations/af.po +0 -196
  143. package/lang/translations/ar.po +0 -196
  144. package/lang/translations/ast.po +0 -196
  145. package/lang/translations/az.po +0 -196
  146. package/lang/translations/be.po +0 -196
  147. package/lang/translations/bg.po +0 -196
  148. package/lang/translations/bn.po +0 -196
  149. package/lang/translations/bs.po +0 -196
  150. package/lang/translations/ca.po +0 -196
  151. package/lang/translations/cs.po +0 -196
  152. package/lang/translations/da.po +0 -196
  153. package/lang/translations/de-ch.po +0 -196
  154. package/lang/translations/de.po +0 -196
  155. package/lang/translations/el.po +0 -196
  156. package/lang/translations/en-au.po +0 -196
  157. package/lang/translations/en-gb.po +0 -196
  158. package/lang/translations/en.po +0 -196
  159. package/lang/translations/eo.po +0 -196
  160. package/lang/translations/es-co.po +0 -196
  161. package/lang/translations/es.po +0 -196
  162. package/lang/translations/et.po +0 -196
  163. package/lang/translations/eu.po +0 -196
  164. package/lang/translations/fa.po +0 -196
  165. package/lang/translations/fi.po +0 -196
  166. package/lang/translations/fr.po +0 -196
  167. package/lang/translations/gl.po +0 -196
  168. package/lang/translations/gu.po +0 -196
  169. package/lang/translations/he.po +0 -196
  170. package/lang/translations/hi.po +0 -196
  171. package/lang/translations/hr.po +0 -196
  172. package/lang/translations/hu.po +0 -196
  173. package/lang/translations/hy.po +0 -196
  174. package/lang/translations/id.po +0 -196
  175. package/lang/translations/it.po +0 -196
  176. package/lang/translations/ja.po +0 -196
  177. package/lang/translations/jv.po +0 -196
  178. package/lang/translations/kk.po +0 -196
  179. package/lang/translations/km.po +0 -196
  180. package/lang/translations/kn.po +0 -196
  181. package/lang/translations/ko.po +0 -196
  182. package/lang/translations/ku.po +0 -196
  183. package/lang/translations/lt.po +0 -196
  184. package/lang/translations/lv.po +0 -196
  185. package/lang/translations/ms.po +0 -196
  186. package/lang/translations/nb.po +0 -196
  187. package/lang/translations/ne.po +0 -196
  188. package/lang/translations/nl.po +0 -196
  189. package/lang/translations/no.po +0 -196
  190. package/lang/translations/oc.po +0 -196
  191. package/lang/translations/pl.po +0 -196
  192. package/lang/translations/pt-br.po +0 -196
  193. package/lang/translations/pt.po +0 -196
  194. package/lang/translations/ro.po +0 -196
  195. package/lang/translations/ru.po +0 -196
  196. package/lang/translations/si.po +0 -196
  197. package/lang/translations/sk.po +0 -196
  198. package/lang/translations/sl.po +0 -196
  199. package/lang/translations/sq.po +0 -196
  200. package/lang/translations/sr-latn.po +0 -196
  201. package/lang/translations/sr.po +0 -196
  202. package/lang/translations/sv.po +0 -196
  203. package/lang/translations/th.po +0 -196
  204. package/lang/translations/ti.po +0 -196
  205. package/lang/translations/tk.po +0 -196
  206. package/lang/translations/tr.po +0 -196
  207. package/lang/translations/tt.po +0 -196
  208. package/lang/translations/ug.po +0 -196
  209. package/lang/translations/uk.po +0 -196
  210. package/lang/translations/ur.po +0 -196
  211. package/lang/translations/uz.po +0 -196
  212. package/lang/translations/vi.po +0 -196
  213. package/lang/translations/zh-cn.po +0 -196
  214. package/lang/translations/zh.po +0 -196
  215. package/src/augmentation.js +0 -5
  216. package/src/autoimage.js +0 -148
  217. package/src/image/converters.js +0 -236
  218. package/src/image/imageblockediting.js +0 -159
  219. package/src/image/imageediting.js +0 -69
  220. package/src/image/imageinlineediting.js +0 -178
  221. package/src/image/imageloadobserver.js +0 -52
  222. package/src/image/imageplaceholder.js +0 -119
  223. package/src/image/imagetypecommand.js +0 -84
  224. package/src/image/insertimagecommand.js +0 -125
  225. package/src/image/replaceimagesourcecommand.js +0 -75
  226. package/src/image/ui/utils.js +0 -46
  227. package/src/image/utils.js +0 -125
  228. package/src/image.js +0 -44
  229. package/src/imageblock.js +0 -44
  230. package/src/imagecaption/imagecaptionediting.js +0 -238
  231. package/src/imagecaption/imagecaptionui.js +0 -68
  232. package/src/imagecaption/imagecaptionutils.js +0 -68
  233. package/src/imagecaption/toggleimagecaptioncommand.js +0 -138
  234. package/src/imagecaption.js +0 -36
  235. package/src/imageconfig.js +0 -5
  236. package/src/imageinline.js +0 -44
  237. package/src/imageinsert/imageinsertui.js +0 -216
  238. package/src/imageinsert/imageinsertviaurlui.js +0 -175
  239. package/src/imageinsert/ui/imageinsertformview.js +0 -117
  240. package/src/imageinsert/ui/imageinserturlview.js +0 -102
  241. package/src/imageinsert.js +0 -43
  242. package/src/imageinsertviaurl.js +0 -41
  243. package/src/imageresize/imagecustomresizeui.js +0 -177
  244. package/src/imageresize/imageresizebuttons.js +0 -303
  245. package/src/imageresize/imageresizeediting.js +0 -206
  246. package/src/imageresize/imageresizehandles.js +0 -118
  247. package/src/imageresize/resizeimagecommand.js +0 -63
  248. package/src/imageresize/ui/imagecustomresizeformview.js +0 -264
  249. package/src/imageresize/utils/getselectedimageeditornodes.js +0 -25
  250. package/src/imageresize/utils/getselectedimagepossibleresizerange.js +0 -33
  251. package/src/imageresize/utils/getselectedimagewidthinunits.js +0 -42
  252. package/src/imageresize/utils/tryparsedimensionwithunit.js +0 -58
  253. package/src/imageresize.js +0 -38
  254. package/src/imagesizeattributes.js +0 -163
  255. package/src/imagestyle/converters.js +0 -118
  256. package/src/imagestyle/imagestylecommand.js +0 -117
  257. package/src/imagestyle/imagestyleediting.js +0 -127
  258. package/src/imagestyle/imagestyleui.js +0 -198
  259. package/src/imagestyle/utils.js +0 -333
  260. package/src/imagestyle.js +0 -42
  261. package/src/imagetextalternative/imagetextalternativecommand.js +0 -44
  262. package/src/imagetextalternative/imagetextalternativeediting.js +0 -41
  263. package/src/imagetextalternative/imagetextalternativeui.js +0 -183
  264. package/src/imagetextalternative/ui/textalternativeformview.js +0 -193
  265. package/src/imagetextalternative.js +0 -39
  266. package/src/imagetoolbar.js +0 -63
  267. package/src/imageupload/imageuploadediting.js +0 -482
  268. package/src/imageupload/imageuploadprogress.js +0 -222
  269. package/src/imageupload/imageuploadui.js +0 -135
  270. package/src/imageupload/uploadimagecommand.js +0 -110
  271. package/src/imageupload/utils.js +0 -114
  272. package/src/imageupload.js +0 -42
  273. package/src/imageutils.js +0 -309
  274. package/src/index.js +0 -67
  275. package/src/pictureediting.js +0 -136
  276. package/theme/image.css +0 -143
  277. package/theme/imagecaption.css +0 -53
  278. package/theme/imagecustomresizeform.css +0 -4
  279. package/theme/imageinsert.css +0 -14
  280. package/theme/imageplaceholder.css +0 -10
  281. package/theme/imageresize.css +0 -53
  282. package/theme/imagestyle.css +0 -120
  283. package/theme/imageuploadicon.css +0 -23
  284. package/theme/imageuploadloader.css +0 -18
  285. package/theme/imageuploadprogress.css +0 -19
  286. package/theme/textalternativeform.css +0 -4
  287. /package/{src → dist}/augmentation.d.ts +0 -0
  288. /package/{src → dist}/imageresize/utils/tryparsedimensionwithunit.d.ts +0 -0
  289. /package/{src → dist}/index.d.ts +0 -0
@@ -1,177 +0,0 @@
1
- /**
2
- * @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
3
- * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
4
- */
5
- /**
6
- * @module image/imageresize/imagecustomresizeui
7
- */
8
- import { Plugin } from 'ckeditor5/src/core.js';
9
- import { ContextualBalloon, clickOutsideHandler, CssTransitionDisablerMixin } from 'ckeditor5/src/ui.js';
10
- import { getBalloonPositionData } from '../image/ui/utils.js';
11
- import { getSelectedImageWidthInUnits } from './utils/getselectedimagewidthinunits.js';
12
- import { ImageCustomResizeFormView } from './ui/imagecustomresizeformview.js';
13
- import { getSelectedImagePossibleResizeRange } from './utils/getselectedimagepossibleresizerange.js';
14
- /**
15
- * The custom resize image UI plugin.
16
- *
17
- * The plugin uses the {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon}.
18
- */
19
- export class ImageCustomResizeUI extends Plugin {
20
- /**
21
- * The contextual balloon plugin instance.
22
- */
23
- _balloon;
24
- /**
25
- * A form containing a textarea and buttons, used to change the `alt` text value.
26
- */
27
- _form;
28
- /**
29
- * @inheritDoc
30
- */
31
- static get requires() {
32
- return [ContextualBalloon];
33
- }
34
- /**
35
- * @inheritDoc
36
- */
37
- static get pluginName() {
38
- return 'ImageCustomResizeUI';
39
- }
40
- /**
41
- * @inheritDoc
42
- */
43
- static get isOfficialPlugin() {
44
- return true;
45
- }
46
- /**
47
- * @inheritDoc
48
- */
49
- destroy() {
50
- super.destroy();
51
- // Destroy created UI components as they are not automatically destroyed (see ckeditor5#1341).
52
- if (this._form) {
53
- this._form.destroy();
54
- }
55
- }
56
- /**
57
- * Creates the {@link module:image/imageresize/ui/imagecustomresizeformview~ImageCustomResizeFormView}
58
- * form.
59
- */
60
- _createForm(unit) {
61
- const editor = this.editor;
62
- this._balloon = this.editor.plugins.get('ContextualBalloon');
63
- this._form = new (CssTransitionDisablerMixin(ImageCustomResizeFormView))(editor.locale, unit, getFormValidators(editor));
64
- // Render the form so its #element is available for clickOutsideHandler.
65
- this._form.render();
66
- this.listenTo(this._form, 'submit', () => {
67
- if (this._form.isValid()) {
68
- editor.execute('resizeImage', {
69
- width: this._form.sizeWithUnits
70
- });
71
- this._hideForm(true);
72
- }
73
- });
74
- // Update balloon position when form error label is added .
75
- this.listenTo(this._form.labeledInput, 'change:errorText', () => {
76
- editor.ui.update();
77
- });
78
- this.listenTo(this._form, 'cancel', () => {
79
- this._hideForm(true);
80
- });
81
- // Close on click outside of balloon panel element.
82
- clickOutsideHandler({
83
- emitter: this._form,
84
- activator: () => this._isVisible,
85
- contextElements: () => [this._balloon.view.element],
86
- callback: () => this._hideForm()
87
- });
88
- }
89
- /**
90
- * Shows the {@link #_form} in the {@link #_balloon}.
91
- *
92
- * @internal
93
- */
94
- _showForm(unit) {
95
- if (this._isVisible) {
96
- return;
97
- }
98
- if (!this._form) {
99
- this._createForm(unit);
100
- }
101
- const editor = this.editor;
102
- const labeledInput = this._form.labeledInput;
103
- this._form.disableCssTransitions();
104
- this._form.resetFormStatus();
105
- if (!this._isInBalloon) {
106
- this._balloon.add({
107
- view: this._form,
108
- position: getBalloonPositionData(editor)
109
- });
110
- }
111
- // Make sure that each time the panel shows up, the field remains in sync with the value of
112
- // the command. If the user typed in the input, then canceled the balloon (`labeledInput#value`
113
- // stays unaltered) and re-opened it without changing the value of the command, they would see the
114
- // old value instead of the actual value of the command.
115
- const currentParsedWidth = getSelectedImageWidthInUnits(editor, unit);
116
- const initialInputValue = currentParsedWidth ? currentParsedWidth.value.toFixed(1) : '';
117
- const possibleRange = getSelectedImagePossibleResizeRange(editor, unit);
118
- labeledInput.fieldView.value = labeledInput.fieldView.element.value = initialInputValue;
119
- if (possibleRange) {
120
- Object.assign(labeledInput.fieldView, {
121
- min: possibleRange.lower.toFixed(1),
122
- max: Math.ceil(possibleRange.upper).toFixed(1)
123
- });
124
- }
125
- this._form.labeledInput.fieldView.select();
126
- this._form.enableCssTransitions();
127
- }
128
- /**
129
- * Removes the {@link #_form} from the {@link #_balloon}.
130
- *
131
- * @param focusEditable Controls whether the editing view is focused afterwards.
132
- */
133
- _hideForm(focusEditable = false) {
134
- if (!this._isInBalloon) {
135
- return;
136
- }
137
- // Blur the input element before removing it from DOM to prevent issues in some browsers.
138
- // See https://github.com/ckeditor/ckeditor5/issues/1501.
139
- if (this._form.focusTracker.isFocused) {
140
- this._form.saveButtonView.focus();
141
- }
142
- this._balloon.remove(this._form);
143
- if (focusEditable) {
144
- this.editor.editing.view.focus();
145
- }
146
- }
147
- /**
148
- * Returns `true` when the {@link #_form} is the visible view in the {@link #_balloon}.
149
- */
150
- get _isVisible() {
151
- return !!this._balloon && this._balloon.visibleView === this._form;
152
- }
153
- /**
154
- * Returns `true` when the {@link #_form} is in the {@link #_balloon}.
155
- */
156
- get _isInBalloon() {
157
- return !!this._balloon && this._balloon.hasView(this._form);
158
- }
159
- }
160
- /**
161
- * Returns image resize form validation callbacks.
162
- *
163
- * @param editor Editor instance.
164
- */
165
- function getFormValidators(editor) {
166
- const t = editor.t;
167
- return [
168
- form => {
169
- if (form.rawSize.trim() === '') {
170
- return t('The value must not be empty.');
171
- }
172
- if (form.parsedSize === null) {
173
- return t('The value should be a plain number.');
174
- }
175
- }
176
- ];
177
- }
@@ -1,303 +0,0 @@
1
- /**
2
- * @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
3
- * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
4
- */
5
- /**
6
- * @module image/imageresize/imageresizebuttons
7
- */
8
- import { Plugin } from 'ckeditor5/src/core.js';
9
- import { ButtonView, DropdownButtonView, UIModel, createDropdown, addListToDropdown } from 'ckeditor5/src/ui.js';
10
- import { CKEditorError, Collection } from 'ckeditor5/src/utils.js';
11
- import { IconObjectSizeCustom, IconObjectSizeFull, IconObjectSizeLarge, IconObjectSizeMedium, IconObjectSizeSmall } from 'ckeditor5/src/icons.js';
12
- import { ImageResizeEditing } from './imageresizeediting.js';
13
- const RESIZE_ICONS = /* #__PURE__ */ (() => ({
14
- small: IconObjectSizeSmall,
15
- medium: IconObjectSizeMedium,
16
- large: IconObjectSizeLarge,
17
- custom: IconObjectSizeCustom,
18
- original: IconObjectSizeFull
19
- }))();
20
- /**
21
- * The image resize buttons plugin.
22
- *
23
- * It adds a possibility to resize images using the toolbar dropdown or individual buttons, depending on the plugin configuration.
24
- */
25
- export class ImageResizeButtons extends Plugin {
26
- /**
27
- * @inheritDoc
28
- */
29
- static get requires() {
30
- return [ImageResizeEditing];
31
- }
32
- /**
33
- * @inheritDoc
34
- */
35
- static get pluginName() {
36
- return 'ImageResizeButtons';
37
- }
38
- /**
39
- * @inheritDoc
40
- */
41
- static get isOfficialPlugin() {
42
- return true;
43
- }
44
- /**
45
- * The resize unit.
46
- * @default '%'
47
- */
48
- _resizeUnit;
49
- /**
50
- * @inheritDoc
51
- */
52
- constructor(editor) {
53
- super(editor);
54
- this._resizeUnit = editor.config.get('image.resizeUnit');
55
- }
56
- /**
57
- * @inheritDoc
58
- */
59
- init() {
60
- const editor = this.editor;
61
- const options = editor.config.get('image.resizeOptions');
62
- const command = editor.commands.get('resizeImage');
63
- this.bind('isEnabled').to(command);
64
- for (const option of options) {
65
- this._registerImageResizeButton(option);
66
- }
67
- this._registerImageResizeDropdown(options);
68
- }
69
- /**
70
- * A helper function that creates a standalone button component for the plugin.
71
- *
72
- * @param option A model of the resize option.
73
- */
74
- _registerImageResizeButton(option) {
75
- const editor = this.editor;
76
- const { name, value, icon } = option;
77
- editor.ui.componentFactory.add(name, locale => {
78
- const button = new ButtonView(locale);
79
- const command = editor.commands.get('resizeImage');
80
- const labelText = this._getOptionLabelValue(option, true);
81
- if (!RESIZE_ICONS[icon]) {
82
- /**
83
- * When configuring {@link module:image/imageconfig~ImageConfig#resizeOptions `config.image.resizeOptions`} for standalone
84
- * buttons, a valid `icon` token must be set for each option.
85
- *
86
- * See all valid options described in the
87
- * {@link module:image/imageconfig~ImageResizeOption plugin configuration}.
88
- *
89
- * @error imageresizebuttons-missing-icon
90
- * @param {module:image/imageconfig~ImageResizeOption} option Invalid image resize option.
91
- */
92
- throw new CKEditorError('imageresizebuttons-missing-icon', editor, option);
93
- }
94
- button.set({
95
- // Use the `label` property for a verbose description (because of ARIA).
96
- label: labelText,
97
- icon: RESIZE_ICONS[icon],
98
- tooltip: labelText,
99
- isToggleable: true
100
- });
101
- // Bind button to the command.
102
- button.bind('isEnabled').to(this);
103
- if (editor.plugins.has('ImageCustomResizeUI') && isCustomImageResizeOption(option)) {
104
- const customResizeUI = editor.plugins.get('ImageCustomResizeUI');
105
- this.listenTo(button, 'execute', () => {
106
- customResizeUI._showForm(this._resizeUnit);
107
- });
108
- }
109
- else {
110
- const optionValueWithUnit = value ? value + this._resizeUnit : null;
111
- button.bind('isOn').to(command, 'value', command, 'isEnabled', getIsOnButtonCallback(optionValueWithUnit));
112
- this.listenTo(button, 'execute', () => {
113
- editor.execute('resizeImage', { width: optionValueWithUnit });
114
- });
115
- }
116
- return button;
117
- });
118
- }
119
- /**
120
- * A helper function that creates a dropdown component for the plugin containing all the resize options defined in
121
- * the editor configuration.
122
- *
123
- * @param options An array of configured options.
124
- */
125
- _registerImageResizeDropdown(options) {
126
- const editor = this.editor;
127
- const t = editor.t;
128
- const originalSizeOption = options.find(option => !option.value);
129
- const componentCreator = (locale) => {
130
- const command = editor.commands.get('resizeImage');
131
- const dropdownView = createDropdown(locale, DropdownButtonView);
132
- const dropdownButton = dropdownView.buttonView;
133
- const accessibleLabel = t('Resize image');
134
- dropdownButton.set({
135
- tooltip: accessibleLabel,
136
- commandValue: originalSizeOption.value,
137
- icon: RESIZE_ICONS.medium,
138
- isToggleable: true,
139
- label: this._getOptionLabelValue(originalSizeOption),
140
- withText: true,
141
- class: 'ck-resize-image-button',
142
- ariaLabel: accessibleLabel,
143
- ariaLabelledBy: undefined
144
- });
145
- dropdownButton.bind('label').to(command, 'value', commandValue => {
146
- if (commandValue && commandValue.width) {
147
- return commandValue.width;
148
- }
149
- else {
150
- return this._getOptionLabelValue(originalSizeOption);
151
- }
152
- });
153
- dropdownView.bind('isEnabled').to(this);
154
- addListToDropdown(dropdownView, () => this._getResizeDropdownListItemDefinitions(options, command), {
155
- ariaLabel: t('Image resize list'),
156
- role: 'menu'
157
- });
158
- // Execute command when an item from the dropdown is selected.
159
- this.listenTo(dropdownView, 'execute', evt => {
160
- if ('onClick' in evt.source) {
161
- evt.source.onClick();
162
- }
163
- else {
164
- editor.execute(evt.source.commandName, { width: evt.source.commandValue });
165
- editor.editing.view.focus();
166
- }
167
- });
168
- return dropdownView;
169
- };
170
- // Register `resizeImage` dropdown and add `imageResize` dropdown as an alias for backward compatibility.
171
- editor.ui.componentFactory.add('resizeImage', componentCreator);
172
- editor.ui.componentFactory.add('imageResize', componentCreator);
173
- }
174
- /**
175
- * A helper function for creating an option label value string.
176
- *
177
- * @param option A resize option object.
178
- * @param forTooltip An optional flag for creating a tooltip label.
179
- * @returns A user-defined label combined from the numeric value and the resize unit or the default label
180
- * for reset options (`Original`).
181
- */
182
- _getOptionLabelValue(option, forTooltip = false) {
183
- const t = this.editor.t;
184
- if (option.label) {
185
- return option.label;
186
- }
187
- else if (forTooltip) {
188
- if (isCustomImageResizeOption(option)) {
189
- return t('Custom image size');
190
- }
191
- else if (option.value) {
192
- return t('Resize image to %0', option.value + this._resizeUnit);
193
- }
194
- else {
195
- return t('Resize image to the original size');
196
- }
197
- }
198
- else {
199
- if (isCustomImageResizeOption(option)) {
200
- return t('Custom');
201
- }
202
- else if (option.value) {
203
- return option.value + this._resizeUnit;
204
- }
205
- else {
206
- return t('Original');
207
- }
208
- }
209
- }
210
- /**
211
- * A helper function that parses the resize options and returns list item definitions ready for use in the dropdown.
212
- *
213
- * @param options The resize options.
214
- * @param command The resize image command.
215
- * @returns Dropdown item definitions.
216
- */
217
- _getResizeDropdownListItemDefinitions(options, command) {
218
- const { editor } = this;
219
- const itemDefinitions = new Collection();
220
- const optionsWithSerializedValues = options.map(option => {
221
- if (isCustomImageResizeOption(option)) {
222
- return {
223
- ...option,
224
- valueWithUnits: 'custom'
225
- };
226
- }
227
- if (!option.value) {
228
- return {
229
- ...option,
230
- valueWithUnits: null
231
- };
232
- }
233
- return {
234
- ...option,
235
- valueWithUnits: `${option.value}${this._resizeUnit}`
236
- };
237
- });
238
- for (const option of optionsWithSerializedValues) {
239
- let definition = null;
240
- if (editor.plugins.has('ImageCustomResizeUI') && isCustomImageResizeOption(option)) {
241
- const customResizeUI = editor.plugins.get('ImageCustomResizeUI');
242
- definition = {
243
- type: 'button',
244
- model: new UIModel({
245
- label: this._getOptionLabelValue(option),
246
- role: 'menuitemradio',
247
- withText: true,
248
- icon: null,
249
- onClick: () => {
250
- customResizeUI._showForm(this._resizeUnit);
251
- }
252
- })
253
- };
254
- const allDropdownValues = Object.values(optionsWithSerializedValues).map(option => option.valueWithUnits);
255
- definition.model.bind('isOn').to(command, 'value', command, 'isEnabled', getIsOnCustomButtonCallback(allDropdownValues));
256
- }
257
- else {
258
- definition = {
259
- type: 'button',
260
- model: new UIModel({
261
- commandName: 'resizeImage',
262
- commandValue: option.valueWithUnits,
263
- label: this._getOptionLabelValue(option),
264
- role: 'menuitemradio',
265
- withText: true,
266
- icon: null
267
- })
268
- };
269
- definition.model.bind('isOn').to(command, 'value', command, 'isEnabled', getIsOnButtonCallback(option.valueWithUnits));
270
- }
271
- definition.model.bind('isEnabled').to(command, 'isEnabled');
272
- itemDefinitions.add(definition);
273
- }
274
- return itemDefinitions;
275
- }
276
- }
277
- /**
278
- * A helper that checks if provided option triggers custom resize balloon.
279
- */
280
- function isCustomImageResizeOption(option) {
281
- return option.value === 'custom';
282
- }
283
- /**
284
- * A helper function for setting the `isOn` state of buttons in value bindings.
285
- */
286
- function getIsOnButtonCallback(value) {
287
- return (commandValue, isEnabled) => {
288
- const objectCommandValue = commandValue;
289
- if (objectCommandValue === undefined || !isEnabled) {
290
- return false;
291
- }
292
- if (value === null && objectCommandValue === value) {
293
- return true;
294
- }
295
- return objectCommandValue !== null && objectCommandValue.width === value;
296
- };
297
- }
298
- /**
299
- * A helper function for setting the `isOn` state of custom size button in value bindings.
300
- */
301
- function getIsOnCustomButtonCallback(allDropdownValues) {
302
- return (commandValue, isEnabled) => !allDropdownValues.some(dropdownValue => getIsOnButtonCallback(dropdownValue)(commandValue, isEnabled));
303
- }
@@ -1,206 +0,0 @@
1
- /**
2
- * @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
3
- * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
4
- */
5
- import { Plugin } from 'ckeditor5/src/core.js';
6
- import { ImageUtils } from '../imageutils.js';
7
- import { ResizeImageCommand } from './resizeimagecommand.js';
8
- import { widthAndHeightStylesAreBothSet } from '../image/utils.js';
9
- /**
10
- * The image resize editing feature.
11
- *
12
- * It adds the ability to resize each image using handles or manually by
13
- * {@link module:image/imageresize/imageresizebuttons~ImageResizeButtons} buttons.
14
- */
15
- export class ImageResizeEditing extends Plugin {
16
- /**
17
- * @inheritDoc
18
- */
19
- static get requires() {
20
- return [ImageUtils];
21
- }
22
- /**
23
- * @inheritDoc
24
- */
25
- static get pluginName() {
26
- return 'ImageResizeEditing';
27
- }
28
- /**
29
- * @inheritDoc
30
- * @internal
31
- */
32
- static get licenseFeatureCode() {
33
- return 'IR';
34
- }
35
- /**
36
- * @inheritDoc
37
- */
38
- static get isOfficialPlugin() {
39
- return true;
40
- }
41
- /**
42
- * @inheritDoc
43
- */
44
- static get isPremiumPlugin() {
45
- return true;
46
- }
47
- /**
48
- * @inheritDoc
49
- */
50
- constructor(editor) {
51
- super(editor);
52
- editor.config.define('image', {
53
- resizeUnit: '%',
54
- resizeOptions: [
55
- {
56
- name: 'resizeImage:original',
57
- value: null,
58
- icon: 'original'
59
- },
60
- {
61
- name: 'resizeImage:custom',
62
- value: 'custom',
63
- icon: 'custom'
64
- },
65
- {
66
- name: 'resizeImage:25',
67
- value: '25',
68
- icon: 'small'
69
- },
70
- {
71
- name: 'resizeImage:50',
72
- value: '50',
73
- icon: 'medium'
74
- },
75
- {
76
- name: 'resizeImage:75',
77
- value: '75',
78
- icon: 'large'
79
- }
80
- ]
81
- });
82
- }
83
- /**
84
- * @inheritDoc
85
- */
86
- init() {
87
- const editor = this.editor;
88
- const resizeImageCommand = new ResizeImageCommand(editor);
89
- this._registerConverters('imageBlock');
90
- this._registerConverters('imageInline');
91
- // Register `resizeImage` command and add `imageResize` command as an alias for backward compatibility.
92
- editor.commands.add('resizeImage', resizeImageCommand);
93
- editor.commands.add('imageResize', resizeImageCommand);
94
- }
95
- /**
96
- * @inheritDoc
97
- */
98
- afterInit() {
99
- this._registerSchema();
100
- }
101
- _registerSchema() {
102
- const schema = this.editor.model.schema;
103
- if (this.editor.plugins.has('ImageBlockEditing')) {
104
- schema.extend('imageBlock', { allowAttributes: ['resizedWidth', 'resizedHeight'] });
105
- schema.setAttributeProperties('resizedWidth', { isFormatting: true });
106
- schema.setAttributeProperties('resizedHeight', { isFormatting: true });
107
- }
108
- if (this.editor.plugins.has('ImageInlineEditing')) {
109
- schema.extend('imageInline', { allowAttributes: ['resizedWidth', 'resizedHeight'] });
110
- schema.setAttributeProperties('resizedWidth', { isFormatting: true });
111
- schema.setAttributeProperties('resizedHeight', { isFormatting: true });
112
- }
113
- }
114
- /**
115
- * Registers image resize converters.
116
- *
117
- * @param imageType The type of the image.
118
- */
119
- _registerConverters(imageType) {
120
- const editor = this.editor;
121
- const imageUtils = editor.plugins.get('ImageUtils');
122
- // Dedicated converter to propagate image's attribute to the img tag.
123
- editor.conversion.for('downcast').add(dispatcher => dispatcher.on(`attribute:resizedWidth:${imageType}`, (evt, data, conversionApi) => {
124
- if (!conversionApi.consumable.consume(data.item, evt.name)) {
125
- return;
126
- }
127
- const viewWriter = conversionApi.writer;
128
- const viewImg = conversionApi.mapper.toViewElement(data.item);
129
- if (data.attributeNewValue !== null) {
130
- viewWriter.setStyle('width', data.attributeNewValue, viewImg);
131
- viewWriter.addClass('image_resized', viewImg);
132
- }
133
- else {
134
- viewWriter.removeStyle('width', viewImg);
135
- viewWriter.removeClass('image_resized', viewImg);
136
- }
137
- }));
138
- editor.conversion.for('dataDowncast').attributeToAttribute({
139
- model: {
140
- name: imageType,
141
- key: 'resizedHeight'
142
- },
143
- view: modelAttributeValue => ({
144
- key: 'style',
145
- value: {
146
- 'height': modelAttributeValue
147
- }
148
- })
149
- });
150
- editor.conversion.for('editingDowncast').add(dispatcher => dispatcher.on(`attribute:resizedHeight:${imageType}`, (evt, data, conversionApi) => {
151
- if (!conversionApi.consumable.consume(data.item, evt.name)) {
152
- return;
153
- }
154
- const viewWriter = conversionApi.writer;
155
- const viewImg = conversionApi.mapper.toViewElement(data.item);
156
- const target = imageType === 'imageInline' ? imageUtils.findViewImgElement(viewImg) : viewImg;
157
- if (data.attributeNewValue !== null) {
158
- viewWriter.setStyle('height', data.attributeNewValue, target);
159
- }
160
- else {
161
- viewWriter.removeStyle('height', target);
162
- }
163
- }));
164
- editor.conversion.for('upcast')
165
- .attributeToAttribute({
166
- view: {
167
- name: imageType === 'imageBlock' ? 'figure' : 'img',
168
- styles: {
169
- width: /.+/
170
- }
171
- },
172
- model: {
173
- key: 'resizedWidth',
174
- value: (viewElement) => {
175
- if (widthAndHeightStylesAreBothSet(viewElement)) {
176
- return null;
177
- }
178
- return viewElement.getStyle('width');
179
- }
180
- }
181
- });
182
- editor.conversion.for('upcast')
183
- .attributeToAttribute({
184
- view: {
185
- name: imageType === 'imageBlock' ? 'figure' : 'img',
186
- styles: {
187
- height: /.+/
188
- }
189
- },
190
- model: {
191
- key: 'resizedHeight',
192
- value: (viewElement) => {
193
- if (widthAndHeightStylesAreBothSet(viewElement)) {
194
- return null;
195
- }
196
- return viewElement.getStyle('height');
197
- }
198
- }
199
- });
200
- editor.conversion.for('upcast').add(dispatcher => {
201
- dispatcher.on(`element:${imageType === 'imageBlock' ? 'figure' : 'img'}`, (evt, data, conversionApi) => {
202
- conversionApi.consumable.consume(data.viewItem, { classes: ['image_resized'] });
203
- });
204
- });
205
- }
206
- }