@ckeditor/ckeditor5-image 44.0.0 → 44.1.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (200) hide show
  1. package/build/image.js +1 -1
  2. package/dist/augmentation.d.ts +1 -1
  3. package/dist/autoimage.d.ts +1 -1
  4. package/dist/image/converters.d.ts +1 -1
  5. package/dist/image/imageblockediting.d.ts +1 -1
  6. package/dist/image/imageediting.d.ts +1 -1
  7. package/dist/image/imageinlineediting.d.ts +1 -1
  8. package/dist/image/imageloadobserver.d.ts +1 -1
  9. package/dist/image/imageplaceholder.d.ts +1 -1
  10. package/dist/image/imagetypecommand.d.ts +1 -1
  11. package/dist/image/insertimagecommand.d.ts +1 -1
  12. package/dist/image/replaceimagesourcecommand.d.ts +1 -1
  13. package/dist/image/ui/utils.d.ts +1 -1
  14. package/dist/image/utils.d.ts +1 -1
  15. package/dist/image.d.ts +1 -1
  16. package/dist/imageblock.d.ts +1 -1
  17. package/dist/imagecaption/imagecaptionediting.d.ts +1 -1
  18. package/dist/imagecaption/imagecaptionui.d.ts +1 -1
  19. package/dist/imagecaption/imagecaptionutils.d.ts +1 -1
  20. package/dist/imagecaption/toggleimagecaptioncommand.d.ts +1 -1
  21. package/dist/imagecaption.d.ts +1 -1
  22. package/dist/imageconfig.d.ts +1 -1
  23. package/dist/imageinline.d.ts +1 -1
  24. package/dist/imageinsert/imageinsertui.d.ts +1 -1
  25. package/dist/imageinsert/imageinsertviaurlui.d.ts +1 -1
  26. package/dist/imageinsert/ui/imageinsertformview.d.ts +1 -1
  27. package/dist/imageinsert/ui/imageinserturlview.d.ts +1 -1
  28. package/dist/imageinsert.d.ts +1 -1
  29. package/dist/imageinsertviaurl.d.ts +1 -1
  30. package/dist/imageresize/imagecustomresizeui.d.ts +1 -1
  31. package/dist/imageresize/imageresizebuttons.d.ts +1 -1
  32. package/dist/imageresize/imageresizeediting.d.ts +1 -1
  33. package/dist/imageresize/imageresizehandles.d.ts +1 -1
  34. package/dist/imageresize/resizeimagecommand.d.ts +1 -1
  35. package/dist/imageresize/ui/imagecustomresizeformview.d.ts +1 -1
  36. package/dist/imageresize/utils/getselectedimageeditornodes.d.ts +1 -1
  37. package/dist/imageresize/utils/getselectedimagepossibleresizerange.d.ts +1 -1
  38. package/dist/imageresize/utils/getselectedimagewidthinunits.d.ts +1 -1
  39. package/dist/imageresize/utils/tryparsedimensionwithunit.d.ts +1 -1
  40. package/dist/imageresize.d.ts +1 -1
  41. package/dist/imagesizeattributes.d.ts +1 -1
  42. package/dist/imagestyle/converters.d.ts +1 -1
  43. package/dist/imagestyle/imagestylecommand.d.ts +1 -1
  44. package/dist/imagestyle/imagestyleediting.d.ts +1 -1
  45. package/dist/imagestyle/imagestyleui.d.ts +1 -1
  46. package/dist/imagestyle/utils.d.ts +1 -1
  47. package/dist/imagestyle.d.ts +1 -1
  48. package/dist/imagetextalternative/imagetextalternativecommand.d.ts +1 -1
  49. package/dist/imagetextalternative/imagetextalternativeediting.d.ts +1 -1
  50. package/dist/imagetextalternative/imagetextalternativeui.d.ts +1 -1
  51. package/dist/imagetextalternative/ui/textalternativeformview.d.ts +1 -1
  52. package/dist/imagetextalternative.d.ts +1 -1
  53. package/dist/imagetoolbar.d.ts +1 -1
  54. package/dist/imageupload/imageuploadediting.d.ts +14 -1
  55. package/dist/imageupload/imageuploadprogress.d.ts +1 -1
  56. package/dist/imageupload/imageuploadui.d.ts +1 -1
  57. package/dist/imageupload/uploadimagecommand.d.ts +1 -1
  58. package/dist/imageupload/utils.d.ts +1 -1
  59. package/dist/imageupload.d.ts +1 -1
  60. package/dist/imageutils.d.ts +1 -1
  61. package/dist/index.css +16 -16
  62. package/dist/index.css.map +1 -1
  63. package/dist/index.d.ts +1 -1
  64. package/dist/index.js +158 -48
  65. package/dist/index.js.map +1 -1
  66. package/dist/pictureediting.d.ts +1 -1
  67. package/package.json +11 -11
  68. package/src/augmentation.d.ts +1 -1
  69. package/src/augmentation.js +1 -1
  70. package/src/autoimage.d.ts +1 -1
  71. package/src/autoimage.js +1 -1
  72. package/src/image/converters.d.ts +1 -1
  73. package/src/image/converters.js +1 -1
  74. package/src/image/imageblockediting.d.ts +1 -1
  75. package/src/image/imageblockediting.js +1 -1
  76. package/src/image/imageediting.d.ts +1 -1
  77. package/src/image/imageediting.js +1 -1
  78. package/src/image/imageinlineediting.d.ts +1 -1
  79. package/src/image/imageinlineediting.js +1 -1
  80. package/src/image/imageloadobserver.d.ts +1 -1
  81. package/src/image/imageloadobserver.js +1 -1
  82. package/src/image/imageplaceholder.d.ts +1 -1
  83. package/src/image/imageplaceholder.js +1 -1
  84. package/src/image/imagetypecommand.d.ts +1 -1
  85. package/src/image/imagetypecommand.js +1 -1
  86. package/src/image/insertimagecommand.d.ts +1 -1
  87. package/src/image/insertimagecommand.js +1 -1
  88. package/src/image/replaceimagesourcecommand.d.ts +1 -1
  89. package/src/image/replaceimagesourcecommand.js +1 -1
  90. package/src/image/ui/utils.d.ts +1 -1
  91. package/src/image/ui/utils.js +1 -1
  92. package/src/image/utils.d.ts +1 -1
  93. package/src/image/utils.js +1 -1
  94. package/src/image.d.ts +1 -1
  95. package/src/image.js +1 -1
  96. package/src/imageblock.d.ts +1 -1
  97. package/src/imageblock.js +1 -1
  98. package/src/imagecaption/imagecaptionediting.d.ts +1 -1
  99. package/src/imagecaption/imagecaptionediting.js +1 -1
  100. package/src/imagecaption/imagecaptionui.d.ts +1 -1
  101. package/src/imagecaption/imagecaptionui.js +1 -1
  102. package/src/imagecaption/imagecaptionutils.d.ts +1 -1
  103. package/src/imagecaption/imagecaptionutils.js +1 -1
  104. package/src/imagecaption/toggleimagecaptioncommand.d.ts +1 -1
  105. package/src/imagecaption/toggleimagecaptioncommand.js +1 -1
  106. package/src/imagecaption.d.ts +1 -1
  107. package/src/imagecaption.js +1 -1
  108. package/src/imageconfig.d.ts +1 -1
  109. package/src/imageconfig.js +1 -1
  110. package/src/imageinline.d.ts +1 -1
  111. package/src/imageinline.js +1 -1
  112. package/src/imageinsert/imageinsertui.d.ts +1 -1
  113. package/src/imageinsert/imageinsertui.js +1 -1
  114. package/src/imageinsert/imageinsertviaurlui.d.ts +1 -1
  115. package/src/imageinsert/imageinsertviaurlui.js +1 -1
  116. package/src/imageinsert/ui/imageinsertformview.d.ts +1 -1
  117. package/src/imageinsert/ui/imageinsertformview.js +1 -1
  118. package/src/imageinsert/ui/imageinserturlview.d.ts +1 -1
  119. package/src/imageinsert/ui/imageinserturlview.js +1 -1
  120. package/src/imageinsert.d.ts +1 -1
  121. package/src/imageinsert.js +1 -1
  122. package/src/imageinsertviaurl.d.ts +1 -1
  123. package/src/imageinsertviaurl.js +1 -1
  124. package/src/imageresize/imagecustomresizeui.d.ts +1 -1
  125. package/src/imageresize/imagecustomresizeui.js +1 -1
  126. package/src/imageresize/imageresizebuttons.d.ts +1 -1
  127. package/src/imageresize/imageresizebuttons.js +1 -1
  128. package/src/imageresize/imageresizeediting.d.ts +1 -1
  129. package/src/imageresize/imageresizeediting.js +1 -1
  130. package/src/imageresize/imageresizehandles.d.ts +1 -1
  131. package/src/imageresize/imageresizehandles.js +1 -1
  132. package/src/imageresize/resizeimagecommand.d.ts +1 -1
  133. package/src/imageresize/resizeimagecommand.js +1 -1
  134. package/src/imageresize/ui/imagecustomresizeformview.d.ts +1 -1
  135. package/src/imageresize/ui/imagecustomresizeformview.js +1 -1
  136. package/src/imageresize/utils/getselectedimageeditornodes.d.ts +1 -1
  137. package/src/imageresize/utils/getselectedimageeditornodes.js +1 -1
  138. package/src/imageresize/utils/getselectedimagepossibleresizerange.d.ts +1 -1
  139. package/src/imageresize/utils/getselectedimagepossibleresizerange.js +1 -1
  140. package/src/imageresize/utils/getselectedimagewidthinunits.d.ts +1 -1
  141. package/src/imageresize/utils/getselectedimagewidthinunits.js +1 -1
  142. package/src/imageresize/utils/tryparsedimensionwithunit.d.ts +1 -1
  143. package/src/imageresize/utils/tryparsedimensionwithunit.js +1 -1
  144. package/src/imageresize.d.ts +1 -1
  145. package/src/imageresize.js +1 -1
  146. package/src/imagesizeattributes.d.ts +1 -1
  147. package/src/imagesizeattributes.js +1 -1
  148. package/src/imagestyle/converters.d.ts +1 -1
  149. package/src/imagestyle/converters.js +1 -1
  150. package/src/imagestyle/imagestylecommand.d.ts +1 -1
  151. package/src/imagestyle/imagestylecommand.js +1 -1
  152. package/src/imagestyle/imagestyleediting.d.ts +1 -1
  153. package/src/imagestyle/imagestyleediting.js +1 -1
  154. package/src/imagestyle/imagestyleui.d.ts +1 -1
  155. package/src/imagestyle/imagestyleui.js +1 -1
  156. package/src/imagestyle/utils.d.ts +1 -1
  157. package/src/imagestyle/utils.js +1 -1
  158. package/src/imagestyle.d.ts +1 -1
  159. package/src/imagestyle.js +1 -1
  160. package/src/imagetextalternative/imagetextalternativecommand.d.ts +1 -1
  161. package/src/imagetextalternative/imagetextalternativecommand.js +1 -1
  162. package/src/imagetextalternative/imagetextalternativeediting.d.ts +1 -1
  163. package/src/imagetextalternative/imagetextalternativeediting.js +1 -1
  164. package/src/imagetextalternative/imagetextalternativeui.d.ts +1 -1
  165. package/src/imagetextalternative/imagetextalternativeui.js +1 -1
  166. package/src/imagetextalternative/ui/textalternativeformview.d.ts +1 -1
  167. package/src/imagetextalternative/ui/textalternativeformview.js +1 -1
  168. package/src/imagetextalternative.d.ts +1 -1
  169. package/src/imagetextalternative.js +1 -1
  170. package/src/imagetoolbar.d.ts +1 -1
  171. package/src/imagetoolbar.js +1 -1
  172. package/src/imageupload/imageuploadediting.d.ts +14 -1
  173. package/src/imageupload/imageuploadediting.js +143 -43
  174. package/src/imageupload/imageuploadprogress.d.ts +1 -1
  175. package/src/imageupload/imageuploadprogress.js +1 -1
  176. package/src/imageupload/imageuploadui.d.ts +1 -1
  177. package/src/imageupload/imageuploadui.js +1 -1
  178. package/src/imageupload/uploadimagecommand.d.ts +1 -1
  179. package/src/imageupload/uploadimagecommand.js +1 -1
  180. package/src/imageupload/utils.d.ts +1 -1
  181. package/src/imageupload/utils.js +1 -1
  182. package/src/imageupload.d.ts +1 -1
  183. package/src/imageupload.js +1 -1
  184. package/src/imageutils.d.ts +1 -1
  185. package/src/imageutils.js +1 -1
  186. package/src/index.d.ts +1 -1
  187. package/src/index.js +1 -1
  188. package/src/pictureediting.d.ts +1 -1
  189. package/src/pictureediting.js +1 -1
  190. package/theme/image.css +1 -1
  191. package/theme/imagecaption.css +1 -1
  192. package/theme/imagecustomresizeform.css +1 -1
  193. package/theme/imageinsert.css +1 -1
  194. package/theme/imageplaceholder.css +1 -1
  195. package/theme/imageresize.css +1 -1
  196. package/theme/imagestyle.css +1 -1
  197. package/theme/imageuploadicon.css +1 -1
  198. package/theme/imageuploadloader.css +1 -1
  199. package/theme/imageuploadprogress.css +1 -1
  200. package/theme/textalternativeform.css +1 -1
package/dist/index.js CHANGED
@@ -3554,6 +3554,12 @@ const IMAGE_URL_REGEXP = new RegExp(String(/^(http(s)?:\/\/)?[\w-]+\.[\w.~:/[\]@
3554
3554
  * element (reference) and resolve the upload for the correct model element (instead of the one that landed in the `$graveyard`
3555
3555
  * after image type changed).
3556
3556
  */ _uploadImageElements;
3557
+ /**
3558
+ * An internal mapping of {@link module:upload/filerepository~FileLoader#id file loader UIDs} and
3559
+ * upload responses for handling images dragged during their upload process. When such images are later
3560
+ * dropped, their original upload IDs no longer exist in the registry (as the original upload completed).
3561
+ * This map preserves the upload responses to properly handle such cases.
3562
+ */ _uploadedImages = new Map();
3557
3563
  /**
3558
3564
  * @inheritDoc
3559
3565
  */ constructor(editor){
@@ -3593,7 +3599,41 @@ const IMAGE_URL_REGEXP = new RegExp(String(/^(http(s)?:\/\/)?[\w-]+\.[\w.~:/[\]@
3593
3599
  key: 'uploadId'
3594
3600
  },
3595
3601
  model: 'uploadId'
3596
- });
3602
+ })// Handle the case when the image is not fully uploaded yet but it's being moved.
3603
+ // See more: https://github.com/ckeditor/ckeditor5/pull/17327
3604
+ .add((dispatcher)=>dispatcher.on('element:img', (evt, data, conversionApi)=>{
3605
+ if (!conversionApi.consumable.test(data.viewItem, {
3606
+ attributes: [
3607
+ 'data-ck-upload-id'
3608
+ ]
3609
+ })) {
3610
+ return;
3611
+ }
3612
+ const uploadId = data.viewItem.getAttribute('data-ck-upload-id');
3613
+ if (!uploadId) {
3614
+ return;
3615
+ }
3616
+ const [modelElement] = Array.from(data.modelRange.getItems({
3617
+ shallow: true
3618
+ }));
3619
+ const loader = fileRepository.loaders.get(uploadId);
3620
+ if (modelElement) {
3621
+ // Handle case when `uploadId` is set on the image element but the loader is not present in the registry.
3622
+ // It may happen when the image was successfully uploaded and the loader was removed from the registry.
3623
+ // It's still present in the `_uploadedImages` map though. It's why we do not place this line in the condition below.
3624
+ conversionApi.writer.setAttribute('uploadId', uploadId, modelElement);
3625
+ conversionApi.consumable.consume(data.viewItem, {
3626
+ attributes: [
3627
+ 'data-ck-upload-id'
3628
+ ]
3629
+ });
3630
+ if (loader && loader.data) {
3631
+ conversionApi.writer.setAttribute('uploadStatus', loader.status, modelElement);
3632
+ }
3633
+ }
3634
+ }, {
3635
+ priority: 'low'
3636
+ }));
3597
3637
  // Handle pasted images.
3598
3638
  // For every image file, a new file loader is created and a placeholder image is
3599
3639
  // inserted into the content. Then, those images are uploaded once they appear in the model
@@ -3685,13 +3725,38 @@ const IMAGE_URL_REGEXP = new RegExp(String(/^(http(s)?:\/\/)?[\w-]+\.[\w.~:/[\]@
3685
3725
  // Check if the image is loaded on this client.
3686
3726
  const loader = fileRepository.loaders.get(uploadId);
3687
3727
  if (!loader) {
3728
+ // If the loader does not exist, it means that the image was already uploaded
3729
+ // and the loader promise was removed from the registry. In that scenario we need
3730
+ // to restore response object from the internal map.
3731
+ if (!isInsertedInGraveyard && this._uploadedImages.has(uploadId)) {
3732
+ // Fire `uploadComplete` to set proper attributes on the image element.
3733
+ editor.model.enqueueChange({
3734
+ isUndoable: false
3735
+ }, (writer)=>{
3736
+ writer.setAttribute('uploadStatus', 'complete', imageElement);
3737
+ this.fire('uploadComplete', {
3738
+ data: this._uploadedImages.get(uploadId),
3739
+ imageElement: imageElement
3740
+ });
3741
+ });
3742
+ // While it makes sense to remove the image from the `_uploadedImages` map here,
3743
+ // it's counterintuitive for the user that pastes image in uploading several times.
3744
+ // It'll work the first time, but the next time the image will be empty because the
3745
+ // `_uploadedImages` no longer contain the response.
3746
+ }
3688
3747
  continue;
3689
3748
  }
3690
3749
  if (isInsertedInGraveyard) {
3691
3750
  // If the image was inserted to the graveyard for good (**not** replaced by another image),
3692
3751
  // only then abort the loading process.
3693
3752
  if (!insertedImagesIds.has(uploadId)) {
3694
- loader.abort();
3753
+ // ... but abort it only if all remain images that share the same loader are in the graveyard too.
3754
+ // This is to prevent situation when we have two images in uploading state and one of them is being
3755
+ // placed in the graveyard (e.g. using undo). The other one should not be aborted.
3756
+ const allImagesThatShareUploaderInGraveyard = Array.from(this._uploadImageElements.get(uploadId)).every((element)=>element.root.rootName == '$graveyard');
3757
+ if (allImagesThatShareUploaderInGraveyard) {
3758
+ loader.abort();
3759
+ }
3695
3760
  }
3696
3761
  } else {
3697
3762
  // Remember the upload id of the inserted image. If it acted as a replacement for another
@@ -3702,7 +3767,13 @@ const IMAGE_URL_REGEXP = new RegExp(String(/^(http(s)?:\/\/)?[\w-]+\.[\w.~:/[\]@
3702
3767
  // can later resolve in the context of the correct model element. The model element could
3703
3768
  // change for the same upload if one image was replaced by another (e.g. image type was changed),
3704
3769
  // so this may also replace an existing mapping.
3705
- this._uploadImageElements.set(uploadId, imageElement);
3770
+ if (!this._uploadImageElements.has(uploadId)) {
3771
+ this._uploadImageElements.set(uploadId, new Set([
3772
+ imageElement
3773
+ ]));
3774
+ } else {
3775
+ this._uploadImageElements.get(uploadId).add(imageElement);
3776
+ }
3706
3777
  if (loader.status == 'idle') {
3707
3778
  // If the image was inserted into content and has not been loaded yet, start loading it.
3708
3779
  this._readAndUpload(loader);
@@ -3739,6 +3810,7 @@ const IMAGE_URL_REGEXP = new RegExp(String(/^(http(s)?:\/\/)?[\w-]+\.[\w.~:/[\]@
3739
3810
  'uploadStatus'
3740
3811
  ]
3741
3812
  });
3813
+ this._registerConverters('imageBlock');
3742
3814
  }
3743
3815
  if (this.editor.plugins.has('ImageInlineEditing')) {
3744
3816
  schema.extend('imageInline', {
@@ -3747,6 +3819,7 @@ const IMAGE_URL_REGEXP = new RegExp(String(/^(http(s)?:\/\/)?[\w-]+\.[\w.~:/[\]@
3747
3819
  'uploadStatus'
3748
3820
  ]
3749
3821
  });
3822
+ this._registerConverters('imageInline');
3750
3823
  }
3751
3824
  }
3752
3825
  /**
@@ -3766,55 +3839,61 @@ const IMAGE_URL_REGEXP = new RegExp(String(/^(http(s)?:\/\/)?[\w-]+\.[\w.~:/[\]@
3766
3839
  model.enqueueChange({
3767
3840
  isUndoable: false
3768
3841
  }, (writer)=>{
3769
- writer.setAttribute('uploadStatus', 'reading', imageUploadElements.get(loader.id));
3842
+ const elements = imageUploadElements.get(loader.id);
3843
+ for (const element of elements){
3844
+ writer.setAttribute('uploadStatus', 'reading', element);
3845
+ }
3770
3846
  });
3771
3847
  return loader.read().then(()=>{
3772
3848
  const promise = loader.upload();
3773
- const imageElement = imageUploadElements.get(loader.id);
3774
- // Force re–paint in Safari. Without it, the image will display with a wrong size.
3775
- // https://github.com/ckeditor/ckeditor5/issues/1975
3776
- /* istanbul ignore next -- @preserve */ if (env.isSafari) {
3777
- const viewFigure = editor.editing.mapper.toViewElement(imageElement);
3778
- const viewImg = imageUtils.findViewImgElement(viewFigure);
3779
- editor.editing.view.once('render', ()=>{
3780
- // Early returns just to be safe. There might be some code ran
3781
- // in between the outer scope and this callback.
3782
- if (!viewImg.parent) {
3783
- return;
3784
- }
3785
- const domFigure = editor.editing.view.domConverter.mapViewToDom(viewImg.parent);
3786
- if (!domFigure) {
3787
- return;
3788
- }
3789
- const originalDisplay = domFigure.style.display;
3790
- domFigure.style.display = 'none';
3791
- // Make sure this line will never be removed during minification for having "no effect".
3792
- domFigure._ckHack = domFigure.offsetHeight;
3793
- domFigure.style.display = originalDisplay;
3794
- });
3795
- }
3796
3849
  if (editor.ui) {
3797
3850
  editor.ui.ariaLiveAnnouncer.announce(t('Uploading image'));
3798
3851
  }
3799
- model.enqueueChange({
3800
- isUndoable: false
3801
- }, (writer)=>{
3802
- writer.setAttribute('uploadStatus', 'uploading', imageElement);
3803
- });
3852
+ for (const imageElement of imageUploadElements.get(loader.id)){
3853
+ // Force re–paint in Safari. Without it, the image will display with a wrong size.
3854
+ // https://github.com/ckeditor/ckeditor5/issues/1975
3855
+ /* istanbul ignore next -- @preserve */ if (env.isSafari) {
3856
+ const viewFigure = editor.editing.mapper.toViewElement(imageElement);
3857
+ const viewImg = imageUtils.findViewImgElement(viewFigure);
3858
+ editor.editing.view.once('render', ()=>{
3859
+ // Early returns just to be safe. There might be some code ran
3860
+ // in between the outer scope and this callback.
3861
+ if (!viewImg.parent) {
3862
+ return;
3863
+ }
3864
+ const domFigure = editor.editing.view.domConverter.mapViewToDom(viewImg.parent);
3865
+ if (!domFigure) {
3866
+ return;
3867
+ }
3868
+ const originalDisplay = domFigure.style.display;
3869
+ domFigure.style.display = 'none';
3870
+ // Make sure this line will never be removed during minification for having "no effect".
3871
+ domFigure._ckHack = domFigure.offsetHeight;
3872
+ domFigure.style.display = originalDisplay;
3873
+ });
3874
+ }
3875
+ model.enqueueChange({
3876
+ isUndoable: false
3877
+ }, (writer)=>{
3878
+ writer.setAttribute('uploadStatus', 'uploading', imageElement);
3879
+ });
3880
+ }
3804
3881
  return promise;
3805
3882
  }).then((data)=>{
3806
3883
  model.enqueueChange({
3807
3884
  isUndoable: false
3808
3885
  }, (writer)=>{
3809
- const imageElement = imageUploadElements.get(loader.id);
3810
- writer.setAttribute('uploadStatus', 'complete', imageElement);
3886
+ for (const imageElement of imageUploadElements.get(loader.id)){
3887
+ writer.setAttribute('uploadStatus', 'complete', imageElement);
3888
+ this.fire('uploadComplete', {
3889
+ data,
3890
+ imageElement
3891
+ });
3892
+ }
3811
3893
  if (editor.ui) {
3812
3894
  editor.ui.ariaLiveAnnouncer.announce(t('Image upload complete'));
3813
3895
  }
3814
- this.fire('uploadComplete', {
3815
- data,
3816
- imageElement
3817
- });
3896
+ this._uploadedImages.set(loader.id, data);
3818
3897
  });
3819
3898
  clean();
3820
3899
  }).catch((error)=>{
@@ -3837,11 +3916,12 @@ const IMAGE_URL_REGEXP = new RegExp(String(/^(http(s)?:\/\/)?[\w-]+\.[\w.~:/[\]@
3837
3916
  model.enqueueChange({
3838
3917
  isUndoable: false
3839
3918
  }, (writer)=>{
3840
- const node = imageUploadElements.get(loader.id);
3841
- // Handle situation when the image has been removed and then `abort` exception was thrown.
3842
- // See: https://github.com/cksource/ckeditor5-commercial/issues/6817
3843
- if (node && node.root.rootName !== '$graveyard') {
3844
- writer.remove(node);
3919
+ for (const imageElement of imageUploadElements.get(loader.id)){
3920
+ // Handle situation when the image has been removed and then `abort` exception was thrown.
3921
+ // See: https://github.com/cksource/ckeditor5-commercial/issues/6817
3922
+ if (imageElement.root.rootName !== '$graveyard') {
3923
+ writer.remove(imageElement);
3924
+ }
3845
3925
  }
3846
3926
  });
3847
3927
  clean();
@@ -3850,9 +3930,10 @@ const IMAGE_URL_REGEXP = new RegExp(String(/^(http(s)?:\/\/)?[\w-]+\.[\w.~:/[\]@
3850
3930
  model.enqueueChange({
3851
3931
  isUndoable: false
3852
3932
  }, (writer)=>{
3853
- const imageElement = imageUploadElements.get(loader.id);
3854
- writer.removeAttribute('uploadId', imageElement);
3855
- writer.removeAttribute('uploadStatus', imageElement);
3933
+ for (const imageElement of imageUploadElements.get(loader.id)){
3934
+ writer.removeAttribute('uploadId', imageElement);
3935
+ writer.removeAttribute('uploadStatus', imageElement);
3936
+ }
3856
3937
  imageUploadElements.delete(loader.id);
3857
3938
  });
3858
3939
  fileRepository.destroyLoader(loader);
@@ -3886,6 +3967,35 @@ const IMAGE_URL_REGEXP = new RegExp(String(/^(http(s)?:\/\/)?[\w-]+\.[\w.~:/[\]@
3886
3967
  writer.setAttributes(attributes, image);
3887
3968
  }
3888
3969
  }
3970
+ /**
3971
+ * Registers image upload converters.
3972
+ *
3973
+ * @param imageType The type of the image.
3974
+ */ _registerConverters(imageType) {
3975
+ const { conversion, plugins } = this.editor;
3976
+ const fileRepository = plugins.get(FileRepository);
3977
+ const imageUtils = plugins.get(ImageUtils);
3978
+ // It sets `data-ck-upload-id` attribute on the view image elements that are not fully uploaded.
3979
+ // It avoids the situation when image disappears when it's being moved and upload is not finished yet.
3980
+ // See more: https://github.com/ckeditor/ckeditor5/issues/16967
3981
+ conversion.for('dataDowncast').add((dispatcher)=>{
3982
+ dispatcher.on(`attribute:uploadId:${imageType}`, (evt, data, conversionApi)=>{
3983
+ if (!conversionApi.consumable.test(data.item, evt.name)) {
3984
+ return;
3985
+ }
3986
+ const loader = fileRepository.loaders.get(data.attributeNewValue);
3987
+ if (!loader || !loader.data) {
3988
+ return null;
3989
+ }
3990
+ const viewElement = conversionApi.mapper.toViewElement(data.item);
3991
+ const img = imageUtils.findViewImgElement(viewElement);
3992
+ if (img) {
3993
+ conversionApi.consumable.consume(data.item, evt.name);
3994
+ conversionApi.writer.setAttribute('data-ck-upload-id', loader.id, img);
3995
+ }
3996
+ });
3997
+ });
3998
+ }
3889
3999
  }
3890
4000
  /**
3891
4001
  * Returns `true` if non-empty `text/html` is included in the data transfer.
@@ -4837,7 +4947,7 @@ const RESIZED_IMAGE_CLASS = 'image_resized';
4837
4947
 
4838
4948
  /**
4839
4949
  * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
4840
- * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4950
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
4841
4951
  */ /**
4842
4952
  * @module image/imageresize/utils/tryparsedimensionwithunit
4843
4953
  */ /**
@@ -4890,7 +5000,7 @@ const RESIZED_IMAGE_CLASS = 'image_resized';
4890
5000
 
4891
5001
  /**
4892
5002
  * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
4893
- * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
5003
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
4894
5004
  */ /**
4895
5005
  * @module image/imageresize/utils/getselectedimageeditornodes
4896
5006
  */ /**