@ckeditor/ckeditor5-image 40.0.0 → 40.2.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 (253) hide show
  1. package/CHANGELOG.md +25 -25
  2. package/LICENSE.md +3 -3
  3. package/build/image.js +2 -2
  4. package/build/translations/ar.js +1 -1
  5. package/build/translations/ast.js +1 -1
  6. package/build/translations/az.js +1 -1
  7. package/build/translations/bg.js +1 -1
  8. package/build/translations/bn.js +1 -1
  9. package/build/translations/bs.js +1 -1
  10. package/build/translations/ca.js +1 -1
  11. package/build/translations/cs.js +1 -1
  12. package/build/translations/da.js +1 -1
  13. package/build/translations/de-ch.js +1 -1
  14. package/build/translations/de.js +1 -1
  15. package/build/translations/el.js +1 -1
  16. package/build/translations/en-au.js +1 -1
  17. package/build/translations/en-gb.js +1 -1
  18. package/build/translations/eo.js +1 -1
  19. package/build/translations/es.js +1 -1
  20. package/build/translations/et.js +1 -1
  21. package/build/translations/eu.js +1 -1
  22. package/build/translations/fa.js +1 -1
  23. package/build/translations/fi.js +1 -1
  24. package/build/translations/fr.js +1 -1
  25. package/build/translations/gl.js +1 -1
  26. package/build/translations/he.js +1 -1
  27. package/build/translations/hi.js +1 -1
  28. package/build/translations/hr.js +1 -1
  29. package/build/translations/hu.js +1 -1
  30. package/build/translations/id.js +1 -1
  31. package/build/translations/it.js +1 -1
  32. package/build/translations/ja.js +1 -1
  33. package/build/translations/jv.js +1 -1
  34. package/build/translations/km.js +1 -1
  35. package/build/translations/kn.js +1 -1
  36. package/build/translations/ko.js +1 -1
  37. package/build/translations/ku.js +1 -1
  38. package/build/translations/lt.js +1 -1
  39. package/build/translations/lv.js +1 -1
  40. package/build/translations/ms.js +1 -1
  41. package/build/translations/nb.js +1 -1
  42. package/build/translations/ne.js +1 -1
  43. package/build/translations/nl.js +1 -1
  44. package/build/translations/no.js +1 -1
  45. package/build/translations/pl.js +1 -1
  46. package/build/translations/pt-br.js +1 -1
  47. package/build/translations/pt.js +1 -1
  48. package/build/translations/ro.js +1 -1
  49. package/build/translations/ru.js +1 -1
  50. package/build/translations/si.js +1 -1
  51. package/build/translations/sk.js +1 -1
  52. package/build/translations/sq.js +1 -1
  53. package/build/translations/sr-latn.js +1 -1
  54. package/build/translations/sr.js +1 -1
  55. package/build/translations/sv.js +1 -1
  56. package/build/translations/th.js +1 -1
  57. package/build/translations/tk.js +1 -1
  58. package/build/translations/tr.js +1 -1
  59. package/build/translations/tt.js +1 -1
  60. package/build/translations/ug.js +1 -1
  61. package/build/translations/uk.js +1 -1
  62. package/build/translations/ur.js +1 -1
  63. package/build/translations/uz.js +1 -1
  64. package/build/translations/vi.js +1 -1
  65. package/build/translations/zh-cn.js +1 -1
  66. package/build/translations/zh.js +1 -1
  67. package/ckeditor5-metadata.json +3 -3
  68. package/lang/contexts.json +5 -0
  69. package/lang/translations/ar.po +20 -0
  70. package/lang/translations/ast.po +20 -0
  71. package/lang/translations/az.po +20 -0
  72. package/lang/translations/bg.po +20 -0
  73. package/lang/translations/bn.po +20 -0
  74. package/lang/translations/bs.po +20 -0
  75. package/lang/translations/ca.po +20 -0
  76. package/lang/translations/cs.po +20 -0
  77. package/lang/translations/da.po +20 -0
  78. package/lang/translations/de-ch.po +20 -0
  79. package/lang/translations/de.po +20 -0
  80. package/lang/translations/el.po +20 -0
  81. package/lang/translations/en-au.po +20 -0
  82. package/lang/translations/en-gb.po +20 -0
  83. package/lang/translations/en.po +20 -0
  84. package/lang/translations/eo.po +20 -0
  85. package/lang/translations/es.po +20 -0
  86. package/lang/translations/et.po +20 -0
  87. package/lang/translations/eu.po +20 -0
  88. package/lang/translations/fa.po +20 -0
  89. package/lang/translations/fi.po +20 -0
  90. package/lang/translations/fr.po +20 -0
  91. package/lang/translations/gl.po +20 -0
  92. package/lang/translations/he.po +20 -0
  93. package/lang/translations/hi.po +20 -0
  94. package/lang/translations/hr.po +20 -0
  95. package/lang/translations/hu.po +20 -0
  96. package/lang/translations/id.po +20 -0
  97. package/lang/translations/it.po +20 -0
  98. package/lang/translations/ja.po +20 -0
  99. package/lang/translations/jv.po +20 -0
  100. package/lang/translations/km.po +20 -0
  101. package/lang/translations/kn.po +20 -0
  102. package/lang/translations/ko.po +20 -0
  103. package/lang/translations/ku.po +20 -0
  104. package/lang/translations/lt.po +20 -0
  105. package/lang/translations/lv.po +20 -0
  106. package/lang/translations/ms.po +20 -0
  107. package/lang/translations/nb.po +20 -0
  108. package/lang/translations/ne.po +20 -0
  109. package/lang/translations/nl.po +20 -0
  110. package/lang/translations/no.po +20 -0
  111. package/lang/translations/pl.po +20 -0
  112. package/lang/translations/pt-br.po +20 -0
  113. package/lang/translations/pt.po +20 -0
  114. package/lang/translations/ro.po +20 -0
  115. package/lang/translations/ru.po +20 -0
  116. package/lang/translations/si.po +20 -0
  117. package/lang/translations/sk.po +20 -0
  118. package/lang/translations/sq.po +20 -0
  119. package/lang/translations/sr-latn.po +20 -0
  120. package/lang/translations/sr.po +20 -0
  121. package/lang/translations/sv.po +20 -0
  122. package/lang/translations/th.po +20 -0
  123. package/lang/translations/tk.po +20 -0
  124. package/lang/translations/tr.po +20 -0
  125. package/lang/translations/tt.po +20 -0
  126. package/lang/translations/ug.po +21 -1
  127. package/lang/translations/uk.po +20 -0
  128. package/lang/translations/ur.po +20 -0
  129. package/lang/translations/uz.po +20 -0
  130. package/lang/translations/vi.po +20 -0
  131. package/lang/translations/zh-cn.po +20 -0
  132. package/lang/translations/zh.po +20 -0
  133. package/package.json +3 -3
  134. package/src/augmentation.d.ts +56 -56
  135. package/src/augmentation.js +5 -5
  136. package/src/autoimage.d.ts +52 -52
  137. package/src/autoimage.js +132 -132
  138. package/src/image/converters.d.ts +66 -66
  139. package/src/image/converters.js +232 -232
  140. package/src/image/imageblockediting.d.ts +59 -58
  141. package/src/image/imageblockediting.js +153 -152
  142. package/src/image/imageediting.d.ts +30 -30
  143. package/src/image/imageediting.js +63 -63
  144. package/src/image/imageinlineediting.d.ts +60 -59
  145. package/src/image/imageinlineediting.js +177 -176
  146. package/src/image/imageloadobserver.d.ts +48 -48
  147. package/src/image/imageloadobserver.js +52 -52
  148. package/src/image/imageplaceholder.d.ts +39 -0
  149. package/src/image/imageplaceholder.js +113 -0
  150. package/src/image/imagetypecommand.d.ts +44 -44
  151. package/src/image/imagetypecommand.js +80 -80
  152. package/src/image/insertimagecommand.d.ts +66 -66
  153. package/src/image/insertimagecommand.js +120 -120
  154. package/src/image/replaceimagesourcecommand.d.ts +51 -34
  155. package/src/image/replaceimagesourcecommand.js +75 -44
  156. package/src/image/ui/utils.d.ts +25 -25
  157. package/src/image/ui/utils.js +44 -44
  158. package/src/image/utils.d.ts +64 -64
  159. package/src/image/utils.js +121 -121
  160. package/src/image.d.ts +34 -34
  161. package/src/image.js +38 -38
  162. package/src/imageblock.d.ts +34 -33
  163. package/src/imageblock.js +38 -37
  164. package/src/imagecaption/imagecaptionediting.d.ts +89 -89
  165. package/src/imagecaption/imagecaptionediting.js +225 -225
  166. package/src/imagecaption/imagecaptionui.d.ts +26 -26
  167. package/src/imagecaption/imagecaptionui.js +61 -61
  168. package/src/imagecaption/imagecaptionutils.d.ts +38 -38
  169. package/src/imagecaption/imagecaptionutils.js +62 -62
  170. package/src/imagecaption/toggleimagecaptioncommand.d.ts +66 -66
  171. package/src/imagecaption/toggleimagecaptioncommand.js +138 -138
  172. package/src/imagecaption.d.ts +26 -26
  173. package/src/imagecaption.js +30 -30
  174. package/src/imageconfig.d.ts +712 -713
  175. package/src/imageconfig.js +5 -5
  176. package/src/imageinline.d.ts +34 -33
  177. package/src/imageinline.js +38 -37
  178. package/src/imageinsert/imageinsertui.d.ts +72 -44
  179. package/src/imageinsert/imageinsertui.js +174 -141
  180. package/src/imageinsert/imageinsertviaurlui.d.ts +44 -0
  181. package/src/imageinsert/imageinsertviaurlui.js +122 -0
  182. package/src/imageinsert/ui/imageinsertformview.d.ts +56 -0
  183. package/src/imageinsert/ui/imageinsertformview.js +112 -0
  184. package/src/imageinsert/ui/imageinserturlview.d.ts +107 -0
  185. package/src/imageinsert/ui/imageinserturlview.js +156 -0
  186. package/src/imageinsert.d.ts +33 -33
  187. package/src/imageinsert.js +37 -37
  188. package/src/imageinsertviaurl.d.ts +31 -30
  189. package/src/imageinsertviaurl.js +35 -34
  190. package/src/imageresize/imageresizebuttons.d.ts +67 -67
  191. package/src/imageresize/imageresizebuttons.js +217 -217
  192. package/src/imageresize/imageresizeediting.d.ts +37 -37
  193. package/src/imageresize/imageresizeediting.js +165 -165
  194. package/src/imageresize/imageresizehandles.d.ts +31 -31
  195. package/src/imageresize/imageresizehandles.js +114 -114
  196. package/src/imageresize/resizeimagecommand.d.ts +42 -42
  197. package/src/imageresize/resizeimagecommand.js +63 -63
  198. package/src/imageresize.d.ts +27 -27
  199. package/src/imageresize.js +31 -31
  200. package/src/imagesizeattributes.d.ts +34 -34
  201. package/src/imagesizeattributes.js +142 -143
  202. package/src/imagestyle/converters.d.ts +24 -24
  203. package/src/imagestyle/converters.js +79 -79
  204. package/src/imagestyle/imagestylecommand.d.ts +68 -68
  205. package/src/imagestyle/imagestylecommand.js +107 -107
  206. package/src/imagestyle/imagestyleediting.d.ts +50 -50
  207. package/src/imagestyle/imagestyleediting.js +108 -108
  208. package/src/imagestyle/imagestyleui.d.ts +56 -56
  209. package/src/imagestyle/imagestyleui.js +192 -192
  210. package/src/imagestyle/utils.d.ts +101 -101
  211. package/src/imagestyle/utils.js +329 -329
  212. package/src/imagestyle.d.ts +32 -32
  213. package/src/imagestyle.js +36 -36
  214. package/src/imagetextalternative/imagetextalternativecommand.d.ts +34 -34
  215. package/src/imagetextalternative/imagetextalternativecommand.js +44 -44
  216. package/src/imagetextalternative/imagetextalternativeediting.d.ts +28 -28
  217. package/src/imagetextalternative/imagetextalternativeediting.js +35 -35
  218. package/src/imagetextalternative/imagetextalternativeui.d.ts +68 -68
  219. package/src/imagetextalternative/imagetextalternativeui.js +173 -173
  220. package/src/imagetextalternative/ui/textalternativeformview.d.ts +90 -72
  221. package/src/imagetextalternative/ui/textalternativeformview.js +121 -121
  222. package/src/imagetextalternative.d.ts +29 -29
  223. package/src/imagetextalternative.js +33 -33
  224. package/src/imagetoolbar.d.ts +35 -35
  225. package/src/imagetoolbar.js +57 -57
  226. package/src/imageupload/imageuploadediting.d.ts +111 -111
  227. package/src/imageupload/imageuploadediting.js +337 -337
  228. package/src/imageupload/imageuploadprogress.d.ts +42 -42
  229. package/src/imageupload/imageuploadprogress.js +211 -211
  230. package/src/imageupload/imageuploadui.d.ts +23 -23
  231. package/src/imageupload/imageuploadui.js +81 -57
  232. package/src/imageupload/uploadimagecommand.d.ts +60 -60
  233. package/src/imageupload/uploadimagecommand.js +100 -100
  234. package/src/imageupload/utils.d.ts +33 -33
  235. package/src/imageupload/utils.js +112 -112
  236. package/src/imageupload.d.ts +32 -32
  237. package/src/imageupload.js +36 -36
  238. package/src/imageutils.d.ts +125 -125
  239. package/src/imageutils.js +306 -306
  240. package/src/index.d.ts +48 -48
  241. package/src/index.js +39 -39
  242. package/src/pictureediting.d.ts +88 -88
  243. package/src/pictureediting.js +130 -130
  244. package/theme/imageinsert.css +5 -17
  245. package/theme/imageplaceholder.css +10 -0
  246. package/build/image.js.map +0 -1
  247. package/src/imageinsert/ui/imageinsertformrowview.d.ts +0 -61
  248. package/src/imageinsert/ui/imageinsertformrowview.js +0 -54
  249. package/src/imageinsert/ui/imageinsertpanelview.d.ts +0 -106
  250. package/src/imageinsert/ui/imageinsertpanelview.js +0 -161
  251. package/src/imageinsert/utils.d.ts +0 -25
  252. package/src/imageinsert/utils.js +0 -58
  253. package/theme/imageinsertformrowview.css +0 -36
@@ -0,0 +1,122 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
+ */
5
+ /**
6
+ * @module image/imageinsert/imageinsertviaurlui
7
+ */
8
+ import { icons, Plugin } from 'ckeditor5/src/core';
9
+ import { ButtonView, CollapsibleView, DropdownButtonView } from 'ckeditor5/src/ui';
10
+ import ImageInsertUI from './imageinsertui';
11
+ import ImageInsertUrlView from './ui/imageinserturlview';
12
+ /**
13
+ * The image insert via URL plugin (UI part).
14
+ *
15
+ * For a detailed overview, check the {@glink features/images/images-inserting
16
+ * Insert images via source URL} documentation.
17
+ *
18
+ * This plugin registers the {@link module:image/imageinsert/imageinsertui~ImageInsertUI} integration for `url`.
19
+ */
20
+ export default class ImageInsertViaUrlUI extends Plugin {
21
+ /**
22
+ * @inheritDoc
23
+ */
24
+ static get pluginName() {
25
+ return 'ImageInsertViaUrlUI';
26
+ }
27
+ /**
28
+ * @inheritDoc
29
+ */
30
+ static get requires() {
31
+ return [ImageInsertUI];
32
+ }
33
+ /**
34
+ * @inheritDoc
35
+ */
36
+ init() {
37
+ this._imageInsertUI = this.editor.plugins.get('ImageInsertUI');
38
+ const insertImageCommand = this.editor.commands.get('insertImage');
39
+ this._imageInsertUI.registerIntegration({
40
+ name: 'url',
41
+ observable: insertImageCommand,
42
+ requiresForm: true,
43
+ buttonViewCreator: isOnlyOne => this._createInsertUrlButton(isOnlyOne),
44
+ formViewCreator: isOnlyOne => this._createInsertUrlView(isOnlyOne)
45
+ });
46
+ }
47
+ /**
48
+ * Creates the view displayed in the dropdown.
49
+ */
50
+ _createInsertUrlView(isOnlyOne) {
51
+ const editor = this.editor;
52
+ const locale = editor.locale;
53
+ const t = locale.t;
54
+ const replaceImageSourceCommand = editor.commands.get('replaceImageSource');
55
+ const insertImageCommand = editor.commands.get('insertImage');
56
+ const imageInsertUrlView = new ImageInsertUrlView(locale);
57
+ const collapsibleView = isOnlyOne ? null : new CollapsibleView(locale, [imageInsertUrlView]);
58
+ imageInsertUrlView.bind('isImageSelected').to(this._imageInsertUI);
59
+ imageInsertUrlView.bind('isEnabled').toMany([insertImageCommand, replaceImageSourceCommand], 'isEnabled', (...isEnabled) => (isEnabled.some(isCommandEnabled => isCommandEnabled)));
60
+ // Set initial value because integrations are created on first dropdown open.
61
+ imageInsertUrlView.imageURLInputValue = replaceImageSourceCommand.value || '';
62
+ this._imageInsertUI.dropdownView.on('change:isOpen', () => {
63
+ if (this._imageInsertUI.dropdownView.isOpen) {
64
+ // Make sure that each time the panel shows up, the URL field remains in sync with the value of
65
+ // the command. If the user typed in the input, then canceled and re-opened it without changing
66
+ // the value of the media command (e.g. because they didn't change the selection), they would see
67
+ // the old value instead of the actual value of the command.
68
+ imageInsertUrlView.imageURLInputValue = replaceImageSourceCommand.value || '';
69
+ if (collapsibleView) {
70
+ collapsibleView.isCollapsed = true;
71
+ }
72
+ }
73
+ // Note: Use the low priority to make sure the following listener starts working after the
74
+ // default action of the drop-down is executed (i.e. the panel showed up). Otherwise, the
75
+ // invisible form/input cannot be focused/selected.
76
+ }, { priority: 'low' });
77
+ imageInsertUrlView.on('submit', () => {
78
+ if (replaceImageSourceCommand.isEnabled) {
79
+ editor.execute('replaceImageSource', { source: imageInsertUrlView.imageURLInputValue });
80
+ }
81
+ else {
82
+ editor.execute('insertImage', { source: imageInsertUrlView.imageURLInputValue });
83
+ }
84
+ this._closePanel();
85
+ });
86
+ imageInsertUrlView.on('cancel', () => this._closePanel());
87
+ if (collapsibleView) {
88
+ collapsibleView.set({
89
+ isCollapsed: true
90
+ });
91
+ collapsibleView.bind('label').to(this._imageInsertUI, 'isImageSelected', isImageSelected => isImageSelected ?
92
+ t('Update image URL') :
93
+ t('Insert image via URL'));
94
+ return collapsibleView;
95
+ }
96
+ return imageInsertUrlView;
97
+ }
98
+ /**
99
+ * Creates the toolbar button.
100
+ */
101
+ _createInsertUrlButton(isOnlyOne) {
102
+ const ButtonClass = isOnlyOne ? DropdownButtonView : ButtonView;
103
+ const editor = this.editor;
104
+ const button = new ButtonClass(editor.locale);
105
+ const t = editor.locale.t;
106
+ button.set({
107
+ icon: icons.imageUrl,
108
+ tooltip: true
109
+ });
110
+ button.bind('label').to(this._imageInsertUI, 'isImageSelected', isImageSelected => isImageSelected ?
111
+ t('Update image URL') :
112
+ t('Insert image via URL'));
113
+ return button;
114
+ }
115
+ /**
116
+ * Closes the dropdown.
117
+ */
118
+ _closePanel() {
119
+ this.editor.editing.view.focus();
120
+ this._imageInsertUI.dropdownView.isOpen = false;
121
+ }
122
+ }
@@ -0,0 +1,56 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
+ */
5
+ /**
6
+ * @module image/imageinsert/ui/imageinsertformview
7
+ */
8
+ import { View, ViewCollection, FocusCycler } from 'ckeditor5/src/ui';
9
+ import { FocusTracker, KeystrokeHandler, type Locale } from 'ckeditor5/src/utils';
10
+ import '../../../theme/imageinsert.css';
11
+ /**
12
+ * The view displayed in the insert image dropdown.
13
+ *
14
+ * See {@link module:image/imageinsert/imageinsertui~ImageInsertUI}.
15
+ */
16
+ export default class ImageInsertFormView extends View {
17
+ /**
18
+ * Tracks information about DOM focus in the form.
19
+ */
20
+ readonly focusTracker: FocusTracker;
21
+ /**
22
+ * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.
23
+ */
24
+ readonly keystrokes: KeystrokeHandler;
25
+ /**
26
+ * A collection of views that can be focused in the form.
27
+ */
28
+ protected readonly _focusables: ViewCollection;
29
+ /**
30
+ * Helps cycling over {@link #_focusables} in the form.
31
+ */
32
+ protected readonly _focusCycler: FocusCycler;
33
+ /**
34
+ * A collection of the defined integrations for inserting the images.
35
+ */
36
+ private readonly children;
37
+ /**
38
+ * Creates a view for the dropdown panel of {@link module:image/imageinsert/imageinsertui~ImageInsertUI}.
39
+ *
40
+ * @param locale The localization services instance.
41
+ * @param integrations An integrations object that contains components (or tokens for components) to be shown in the panel view.
42
+ */
43
+ constructor(locale: Locale, integrations?: Array<View>);
44
+ /**
45
+ * @inheritDoc
46
+ */
47
+ render(): void;
48
+ /**
49
+ * @inheritDoc
50
+ */
51
+ destroy(): void;
52
+ /**
53
+ * Focuses the first {@link #_focusables focusable} in the form.
54
+ */
55
+ focus(): void;
56
+ }
@@ -0,0 +1,112 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
+ */
5
+ /**
6
+ * @module image/imageinsert/ui/imageinsertformview
7
+ */
8
+ import { View, ViewCollection, submitHandler, FocusCycler, CollapsibleView } from 'ckeditor5/src/ui';
9
+ import { FocusTracker, KeystrokeHandler } from 'ckeditor5/src/utils';
10
+ import '../../../theme/imageinsert.css';
11
+ /**
12
+ * The view displayed in the insert image dropdown.
13
+ *
14
+ * See {@link module:image/imageinsert/imageinsertui~ImageInsertUI}.
15
+ */
16
+ export default class ImageInsertFormView extends View {
17
+ /**
18
+ * Creates a view for the dropdown panel of {@link module:image/imageinsert/imageinsertui~ImageInsertUI}.
19
+ *
20
+ * @param locale The localization services instance.
21
+ * @param integrations An integrations object that contains components (or tokens for components) to be shown in the panel view.
22
+ */
23
+ constructor(locale, integrations = []) {
24
+ super(locale);
25
+ this.focusTracker = new FocusTracker();
26
+ this.keystrokes = new KeystrokeHandler();
27
+ this._focusables = new ViewCollection();
28
+ this.children = this.createCollection();
29
+ this._focusCycler = new FocusCycler({
30
+ focusables: this._focusables,
31
+ focusTracker: this.focusTracker,
32
+ keystrokeHandler: this.keystrokes,
33
+ actions: {
34
+ // Navigate form fields backwards using the Shift + Tab keystroke.
35
+ focusPrevious: 'shift + tab',
36
+ // Navigate form fields forwards using the Tab key.
37
+ focusNext: 'tab'
38
+ }
39
+ });
40
+ for (const view of integrations) {
41
+ this.children.add(view);
42
+ this._focusables.add(view);
43
+ if (view instanceof CollapsibleView) {
44
+ this._focusables.addMany(view.children);
45
+ }
46
+ }
47
+ if (this._focusables.length > 1) {
48
+ for (const view of this._focusables) {
49
+ if (isViewWithFocusCycler(view)) {
50
+ view.focusCycler.on('forwardCycle', evt => {
51
+ this._focusCycler.focusNext();
52
+ evt.stop();
53
+ });
54
+ view.focusCycler.on('backwardCycle', evt => {
55
+ this._focusCycler.focusPrevious();
56
+ evt.stop();
57
+ });
58
+ }
59
+ }
60
+ }
61
+ this.setTemplate({
62
+ tag: 'form',
63
+ attributes: {
64
+ class: [
65
+ 'ck',
66
+ 'ck-image-insert-form'
67
+ ],
68
+ tabindex: -1
69
+ },
70
+ children: this.children
71
+ });
72
+ }
73
+ /**
74
+ * @inheritDoc
75
+ */
76
+ render() {
77
+ super.render();
78
+ submitHandler({
79
+ view: this
80
+ });
81
+ for (const view of this._focusables) {
82
+ this.focusTracker.add(view.element);
83
+ }
84
+ // Start listening for the keystrokes coming from #element.
85
+ this.keystrokes.listenTo(this.element);
86
+ const stopPropagation = (data) => data.stopPropagation();
87
+ // Since the form is in the dropdown panel which is a child of the toolbar, the toolbar's
88
+ // keystroke handler would take over the key management in the URL input. We need to prevent
89
+ // this ASAP. Otherwise, the basic caret movement using the arrow keys will be impossible.
90
+ this.keystrokes.set('arrowright', stopPropagation);
91
+ this.keystrokes.set('arrowleft', stopPropagation);
92
+ this.keystrokes.set('arrowup', stopPropagation);
93
+ this.keystrokes.set('arrowdown', stopPropagation);
94
+ }
95
+ /**
96
+ * @inheritDoc
97
+ */
98
+ destroy() {
99
+ super.destroy();
100
+ this.focusTracker.destroy();
101
+ this.keystrokes.destroy();
102
+ }
103
+ /**
104
+ * Focuses the first {@link #_focusables focusable} in the form.
105
+ */
106
+ focus() {
107
+ this._focusCycler.focusFirst();
108
+ }
109
+ }
110
+ function isViewWithFocusCycler(view) {
111
+ return 'focusCycler' in view;
112
+ }
@@ -0,0 +1,107 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
+ */
5
+ import { ButtonView, View, FocusCycler, LabeledFieldView, type InputTextView } from 'ckeditor5/src/ui';
6
+ import { FocusTracker, KeystrokeHandler, type Locale } from 'ckeditor5/src/utils';
7
+ /**
8
+ * The insert an image via URL view.
9
+ *
10
+ * See {@link module:image/imageinsert/imageinsertviaurlui~ImageInsertViaUrlUI}.
11
+ */
12
+ export default class ImageInsertUrlView extends View {
13
+ /**
14
+ * The URL input field view.
15
+ */
16
+ urlInputView: LabeledFieldView<InputTextView>;
17
+ /**
18
+ * The "insert/update" button view.
19
+ */
20
+ insertButtonView: ButtonView;
21
+ /**
22
+ * The "cancel" button view.
23
+ */
24
+ cancelButtonView: ButtonView;
25
+ /**
26
+ * The value of the URL input.
27
+ *
28
+ * @observable
29
+ */
30
+ imageURLInputValue: string;
31
+ /**
32
+ * Observable property used to alter labels while some image is selected and when it is not.
33
+ *
34
+ * @observable
35
+ */
36
+ isImageSelected: boolean;
37
+ /**
38
+ * Observable property indicating whether the form interactive elements should be enabled.
39
+ *
40
+ * @observable
41
+ */
42
+ isEnabled: boolean;
43
+ /**
44
+ * Tracks information about DOM focus in the form.
45
+ */
46
+ readonly focusTracker: FocusTracker;
47
+ /**
48
+ * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.
49
+ */
50
+ readonly keystrokes: KeystrokeHandler;
51
+ /**
52
+ * Helps cycling over {@link #_focusables} in the form.
53
+ */
54
+ readonly focusCycler: FocusCycler;
55
+ /**
56
+ * A collection of views that can be focused in the form.
57
+ */
58
+ private readonly _focusables;
59
+ /**
60
+ * Creates a view for the dropdown panel of {@link module:image/imageinsert/imageinsertui~ImageInsertUI}.
61
+ *
62
+ * @param locale The localization services instance.
63
+ */
64
+ constructor(locale: Locale);
65
+ /**
66
+ * @inheritDoc
67
+ */
68
+ render(): void;
69
+ /**
70
+ * @inheritDoc
71
+ */
72
+ destroy(): void;
73
+ /**
74
+ * Creates the {@link #urlInputView}.
75
+ */
76
+ private _createUrlInputView;
77
+ /**
78
+ * Creates the {@link #insertButtonView}.
79
+ */
80
+ private _createInsertButton;
81
+ /**
82
+ * Creates the {@link #cancelButtonView}.
83
+ */
84
+ private _createCancelButton;
85
+ /**
86
+ * Focuses the view.
87
+ */
88
+ focus(direction: 1 | -1): void;
89
+ }
90
+ /**
91
+ * Fired when the form view is submitted.
92
+ *
93
+ * @eventName ~ImageInsertUrlView#submit
94
+ */
95
+ export type ImageInsertUrlViewSubmitEvent = {
96
+ name: 'submit';
97
+ args: [];
98
+ };
99
+ /**
100
+ * Fired when the form view is canceled.
101
+ *
102
+ * @eventName ~ImageInsertUrlView#cancel
103
+ */
104
+ export type ImageInsertUrlViewCancelEvent = {
105
+ name: 'cancel';
106
+ args: [];
107
+ };
@@ -0,0 +1,156 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
+ */
5
+ /**
6
+ * @module image/imageinsert/ui/imageinserturlview
7
+ */
8
+ import { icons } from 'ckeditor5/src/core';
9
+ import { ButtonView, View, ViewCollection, FocusCycler, LabeledFieldView, createLabeledInputText } from 'ckeditor5/src/ui';
10
+ import { FocusTracker, KeystrokeHandler } from 'ckeditor5/src/utils';
11
+ /**
12
+ * The insert an image via URL view.
13
+ *
14
+ * See {@link module:image/imageinsert/imageinsertviaurlui~ImageInsertViaUrlUI}.
15
+ */
16
+ export default class ImageInsertUrlView extends View {
17
+ /**
18
+ * Creates a view for the dropdown panel of {@link module:image/imageinsert/imageinsertui~ImageInsertUI}.
19
+ *
20
+ * @param locale The localization services instance.
21
+ */
22
+ constructor(locale) {
23
+ super(locale);
24
+ this.set('imageURLInputValue', '');
25
+ this.set('isImageSelected', false);
26
+ this.set('isEnabled', true);
27
+ this.focusTracker = new FocusTracker();
28
+ this.keystrokes = new KeystrokeHandler();
29
+ this._focusables = new ViewCollection();
30
+ this.focusCycler = new FocusCycler({
31
+ focusables: this._focusables,
32
+ focusTracker: this.focusTracker,
33
+ keystrokeHandler: this.keystrokes,
34
+ actions: {
35
+ // Navigate form fields backwards using the Shift + Tab keystroke.
36
+ focusPrevious: 'shift + tab',
37
+ // Navigate form fields forwards using the Tab key.
38
+ focusNext: 'tab'
39
+ }
40
+ });
41
+ this.urlInputView = this._createUrlInputView();
42
+ this.insertButtonView = this._createInsertButton();
43
+ this.cancelButtonView = this._createCancelButton();
44
+ this._focusables.addMany([
45
+ this.urlInputView,
46
+ this.insertButtonView,
47
+ this.cancelButtonView
48
+ ]);
49
+ this.setTemplate({
50
+ tag: 'div',
51
+ attributes: {
52
+ class: [
53
+ 'ck',
54
+ 'ck-image-insert-url'
55
+ ]
56
+ },
57
+ children: [
58
+ this.urlInputView,
59
+ {
60
+ tag: 'div',
61
+ attributes: {
62
+ class: [
63
+ 'ck',
64
+ 'ck-image-insert-url__action-row'
65
+ ]
66
+ },
67
+ children: [
68
+ this.insertButtonView,
69
+ this.cancelButtonView
70
+ ]
71
+ }
72
+ ]
73
+ });
74
+ }
75
+ /**
76
+ * @inheritDoc
77
+ */
78
+ render() {
79
+ super.render();
80
+ for (const view of this._focusables) {
81
+ this.focusTracker.add(view.element);
82
+ }
83
+ // Start listening for the keystrokes coming from #element.
84
+ this.keystrokes.listenTo(this.element);
85
+ }
86
+ /**
87
+ * @inheritDoc
88
+ */
89
+ destroy() {
90
+ super.destroy();
91
+ this.focusTracker.destroy();
92
+ this.keystrokes.destroy();
93
+ }
94
+ /**
95
+ * Creates the {@link #urlInputView}.
96
+ */
97
+ _createUrlInputView() {
98
+ const locale = this.locale;
99
+ const t = locale.t;
100
+ const urlInputView = new LabeledFieldView(locale, createLabeledInputText);
101
+ urlInputView.bind('label').to(this, 'isImageSelected', value => value ? t('Update image URL') : t('Insert image via URL'));
102
+ urlInputView.bind('isEnabled').to(this);
103
+ urlInputView.fieldView.placeholder = 'https://example.com/image.png';
104
+ urlInputView.fieldView.bind('value').to(this, 'imageURLInputValue', (value) => value || '');
105
+ urlInputView.fieldView.on('input', () => {
106
+ this.imageURLInputValue = urlInputView.fieldView.element.value.trim();
107
+ });
108
+ return urlInputView;
109
+ }
110
+ /**
111
+ * Creates the {@link #insertButtonView}.
112
+ */
113
+ _createInsertButton() {
114
+ const locale = this.locale;
115
+ const t = locale.t;
116
+ const insertButtonView = new ButtonView(locale);
117
+ insertButtonView.set({
118
+ icon: icons.check,
119
+ class: 'ck-button-save',
120
+ type: 'submit',
121
+ withText: true
122
+ });
123
+ insertButtonView.bind('label').to(this, 'isImageSelected', value => value ? t('Update') : t('Insert'));
124
+ insertButtonView.bind('isEnabled').to(this, 'imageURLInputValue', this, 'isEnabled', (...values) => values.every(value => value));
125
+ insertButtonView.delegate('execute').to(this, 'submit');
126
+ return insertButtonView;
127
+ }
128
+ /**
129
+ * Creates the {@link #cancelButtonView}.
130
+ */
131
+ _createCancelButton() {
132
+ const locale = this.locale;
133
+ const t = locale.t;
134
+ const cancelButtonView = new ButtonView(locale);
135
+ cancelButtonView.set({
136
+ label: t('Cancel'),
137
+ icon: icons.cancel,
138
+ class: 'ck-button-cancel',
139
+ withText: true
140
+ });
141
+ cancelButtonView.bind('isEnabled').to(this);
142
+ cancelButtonView.delegate('execute').to(this, 'cancel');
143
+ return cancelButtonView;
144
+ }
145
+ /**
146
+ * Focuses the view.
147
+ */
148
+ focus(direction) {
149
+ if (direction === -1) {
150
+ this.focusCycler.focusLast();
151
+ }
152
+ else {
153
+ this.focusCycler.focusFirst();
154
+ }
155
+ }
156
+ }
@@ -1,33 +1,33 @@
1
- /**
2
- * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
3
- * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
- */
5
- /**
6
- * @module image/imageinsert
7
- */
8
- import { Plugin } from 'ckeditor5/src/core';
9
- import ImageUpload from './imageupload';
10
- import ImageInsertViaUrl from './imageinsertviaurl';
11
- import ImageInsertUI from './imageinsert/imageinsertui';
12
- /**
13
- * The image insert plugin.
14
- *
15
- * For a detailed overview, check the {@glink features/images/image-upload/image-upload Image upload feature}
16
- * and {@glink features/images/images-inserting Insert images via source URL} documentation.
17
- *
18
- * This plugin does not do anything directly, but it loads a set of specific plugins
19
- * to enable image uploading or inserting via implemented integrations:
20
- *
21
- * * {@link module:image/imageupload~ImageUpload}
22
- * * {@link module:image/imageinsert/imageinsertui~ImageInsertUI}
23
- */
24
- export default class ImageInsert extends Plugin {
25
- /**
26
- * @inheritDoc
27
- */
28
- static get pluginName(): "ImageInsert";
29
- /**
30
- * @inheritDoc
31
- */
32
- static get requires(): readonly [typeof ImageUpload, typeof ImageInsertViaUrl, typeof ImageInsertUI];
33
- }
1
+ /**
2
+ * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
+ */
5
+ /**
6
+ * @module image/imageinsert
7
+ */
8
+ import { Plugin } from 'ckeditor5/src/core';
9
+ import ImageUpload from './imageupload';
10
+ import ImageInsertViaUrl from './imageinsertviaurl';
11
+ import ImageInsertUI from './imageinsert/imageinsertui';
12
+ /**
13
+ * The image insert plugin.
14
+ *
15
+ * For a detailed overview, check the {@glink features/images/image-upload/image-upload Image upload feature}
16
+ * and {@glink features/images/images-inserting Insert images via source URL} documentation.
17
+ *
18
+ * This plugin does not do anything directly, but it loads a set of specific plugins
19
+ * to enable image uploading or inserting via implemented integrations:
20
+ *
21
+ * * {@link module:image/imageupload~ImageUpload}
22
+ * * {@link module:image/imageinsert/imageinsertui~ImageInsertUI}
23
+ */
24
+ export default class ImageInsert extends Plugin {
25
+ /**
26
+ * @inheritDoc
27
+ */
28
+ static get pluginName(): "ImageInsert";
29
+ /**
30
+ * @inheritDoc
31
+ */
32
+ static get requires(): readonly [typeof ImageUpload, typeof ImageInsertViaUrl, typeof ImageInsertUI];
33
+ }