@ckeditor/ckeditor5-image 29.0.0 → 31.0.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 (88) hide show
  1. package/LICENSE.md +1 -1
  2. package/README.md +1 -1
  3. package/build/image.js +1 -1
  4. package/build/translations/ar.js +1 -0
  5. package/build/translations/ast.js +1 -0
  6. package/build/translations/az.js +1 -0
  7. package/build/translations/bg.js +1 -0
  8. package/build/translations/cs.js +1 -0
  9. package/build/translations/da.js +1 -0
  10. package/build/translations/de-ch.js +1 -0
  11. package/build/translations/de.js +1 -0
  12. package/build/translations/el.js +1 -0
  13. package/build/translations/en-au.js +1 -0
  14. package/build/translations/en-gb.js +1 -0
  15. package/build/translations/eo.js +1 -0
  16. package/build/translations/es.js +1 -0
  17. package/build/translations/et.js +1 -0
  18. package/build/translations/eu.js +1 -0
  19. package/build/translations/fa.js +1 -0
  20. package/build/translations/fi.js +1 -0
  21. package/build/translations/fr.js +1 -0
  22. package/build/translations/gl.js +1 -0
  23. package/build/translations/he.js +1 -0
  24. package/build/translations/hi.js +1 -0
  25. package/build/translations/hr.js +1 -0
  26. package/build/translations/hu.js +1 -0
  27. package/build/translations/id.js +1 -0
  28. package/build/translations/it.js +1 -0
  29. package/build/translations/ja.js +1 -0
  30. package/build/translations/km.js +1 -0
  31. package/build/translations/kn.js +1 -0
  32. package/build/translations/ko.js +1 -0
  33. package/build/translations/ku.js +1 -0
  34. package/build/translations/lt.js +1 -0
  35. package/build/translations/lv.js +1 -0
  36. package/build/translations/nb.js +1 -0
  37. package/build/translations/ne.js +1 -0
  38. package/build/translations/nl.js +1 -0
  39. package/build/translations/no.js +1 -0
  40. package/build/translations/pl.js +1 -0
  41. package/build/translations/pt-br.js +1 -0
  42. package/build/translations/pt.js +1 -0
  43. package/build/translations/ro.js +1 -0
  44. package/build/translations/ru.js +1 -0
  45. package/build/translations/si.js +1 -0
  46. package/build/translations/sk.js +1 -0
  47. package/build/translations/sq.js +1 -0
  48. package/build/translations/sr-latn.js +1 -0
  49. package/build/translations/sr.js +1 -0
  50. package/build/translations/sv.js +1 -0
  51. package/build/translations/th.js +1 -0
  52. package/build/translations/tk.js +1 -0
  53. package/build/translations/tr.js +1 -0
  54. package/build/translations/ug.js +1 -0
  55. package/build/translations/uk.js +1 -0
  56. package/build/translations/vi.js +1 -0
  57. package/build/translations/zh-cn.js +1 -0
  58. package/build/translations/zh.js +1 -0
  59. package/ckeditor5-metadata.json +233 -0
  60. package/lang/translations/de.po +6 -6
  61. package/lang/translations/gl.po +3 -3
  62. package/lang/translations/hu.po +3 -3
  63. package/lang/translations/it.po +3 -3
  64. package/lang/translations/nl.po +2 -2
  65. package/lang/translations/ru.po +3 -3
  66. package/lang/translations/sr-latn.po +3 -3
  67. package/lang/translations/sr.po +3 -3
  68. package/package.json +35 -33
  69. package/src/autoimage.js +4 -1
  70. package/src/image/converters.js +174 -8
  71. package/src/image/imageblockediting.js +16 -9
  72. package/src/image/imageinlineediting.js +15 -9
  73. package/src/image/imagetypecommand.js +1 -1
  74. package/src/image/insertimagecommand.js +19 -5
  75. package/src/image/ui/utils.js +2 -1
  76. package/src/image/utils.js +5 -10
  77. package/src/imageblock.js +1 -1
  78. package/src/imagecaption/imagecaptionediting.js +2 -12
  79. package/src/imageinline.js +1 -1
  80. package/src/imageresize/imageresizehandles.js +6 -2
  81. package/src/imagestyle/converters.js +2 -1
  82. package/src/imageupload/imageuploadediting.js +2 -2
  83. package/src/imageupload/imageuploadprogress.js +2 -2
  84. package/src/imageutils.js +8 -16
  85. package/src/pictureediting.js +149 -0
  86. package/theme/image.css +7 -0
  87. package/CHANGELOG.md +0 -423
  88. package/build/image.js.map +0 -1
@@ -25,7 +25,7 @@ import { createImageTypeRegExp } from './utils';
25
25
  * The editing part of the image upload feature. It registers the `'uploadImage'` command
26
26
  * and the `imageUpload` command as an aliased name.
27
27
  *
28
- * When an image is uploaded, it fires the {@link ~ImageUploadEditing#event:uploadComplete `uploadComplete` event}
28
+ * When an image is uploaded, it fires the {@link ~ImageUploadEditing#event:uploadComplete `uploadComplete`} event
29
29
  * that allows adding custom attributes to the {@link module:engine/model/element~Element image element}.
30
30
  *
31
31
  * @extends module:core/plugin~Plugin
@@ -291,7 +291,7 @@ export default class ImageUploadEditing extends Plugin {
291
291
  /* istanbul ignore next */
292
292
  if ( env.isSafari ) {
293
293
  const viewFigure = editor.editing.mapper.toViewElement( imageElement );
294
- const viewImg = imageUtils.getViewImageFromWidget( viewFigure );
294
+ const viewImg = imageUtils.findViewImgElement( viewFigure );
295
295
 
296
296
  editor.editing.view.once( 'render', () => {
297
297
  // Early returns just to be safe. There might be some code ran
@@ -157,7 +157,7 @@ function _showPlaceholder( imageUtils, placeholder, viewFigure, writer ) {
157
157
  writer.addClass( 'ck-image-upload-placeholder', viewFigure );
158
158
  }
159
159
 
160
- const viewImg = imageUtils.getViewImageFromWidget( viewFigure );
160
+ const viewImg = imageUtils.findViewImgElement( viewFigure );
161
161
 
162
162
  if ( viewImg.getAttribute( 'src' ) !== placeholder ) {
163
163
  writer.setAttribute( 'src', placeholder, viewImg );
@@ -285,7 +285,7 @@ function _removeUIElement( viewFigure, writer, uniqueProperty ) {
285
285
  // @param {module:upload/filerepository~FileLoader} loader
286
286
  function _displayLocalImage( imageUtils, viewFigure, writer, loader ) {
287
287
  if ( loader.data ) {
288
- const viewImg = imageUtils.getViewImageFromWidget( viewFigure );
288
+ const viewImg = imageUtils.findViewImgElement( viewFigure );
289
289
 
290
290
  writer.setAttribute( 'src', loader.data, viewImg );
291
291
  }
package/src/imageutils.js CHANGED
@@ -190,7 +190,7 @@ export default class ImageUtils extends Plugin {
190
190
  writer.setCustomProperty( 'image', true, viewElement );
191
191
 
192
192
  const labelCreator = () => {
193
- const imgElement = this.getViewImageFromWidget( viewElement );
193
+ const imgElement = this.findViewImgElement( viewElement );
194
194
  const altText = imgElement.getAttribute( 'alt' );
195
195
 
196
196
  return altText ? `${ altText } ${ label }` : label;
@@ -231,33 +231,25 @@ export default class ImageUtils extends Plugin {
231
231
  }
232
232
 
233
233
  /**
234
- * Get view `<img>` element from the view widget (`<figure>`).
234
+ * Get the view `<img>` from another view element, e.g. a widget (`<figure class="image">`), a link (`<a>`).
235
235
  *
236
- * Assuming that image is always a first child of a widget (ie. `figureView.getChild( 0 )`) is unsafe as other features might
237
- * inject their own elements to the widget.
236
+ * The `<img>` can be located deep in other elements, so this helper performs a deep tree search.
238
237
  *
239
- * The `<img>` can be wrapped to other elements, e.g. `<a>`. Nested check required.
240
- *
241
- * @protected
242
238
  * @param {module:engine/view/element~Element} figureView
243
239
  * @returns {module:engine/view/element~Element}
244
240
  */
245
- getViewImageFromWidget( figureView ) {
241
+ findViewImgElement( figureView ) {
246
242
  if ( this.isInlineImageView( figureView ) ) {
247
243
  return figureView;
248
244
  }
249
245
 
250
- const figureChildren = [];
246
+ const editingView = this.editor.editing.view;
251
247
 
252
- for ( const figureChild of figureView.getChildren() ) {
253
- figureChildren.push( figureChild );
254
-
255
- if ( figureChild.is( 'element' ) ) {
256
- figureChildren.push( ...figureChild.getChildren() );
248
+ for ( const { item } of editingView.createRangeIn( figureView ) ) {
249
+ if ( this.isInlineImageView( item ) ) {
250
+ return item;
257
251
  }
258
252
  }
259
-
260
- return figureChildren.find( this.isInlineImageView );
261
253
  }
262
254
  }
263
255
 
@@ -0,0 +1,149 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
+ */
5
+
6
+ /**
7
+ * @module image/pictureediting
8
+ */
9
+
10
+ import { Plugin } from 'ckeditor5/src/core';
11
+
12
+ import ImageEditing from './image/imageediting';
13
+ import ImageUtils from './imageutils';
14
+ import {
15
+ downcastSourcesAttribute,
16
+ upcastPicture
17
+ } from './image/converters';
18
+
19
+ /**
20
+ * This plugin enables the [`<picture>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/picture) element support in the editor.
21
+ *
22
+ * * It enables the `sources` model attribute on `imageBlock` and `imageInline` model elements
23
+ * (brought by {@link module:image/imageblock~ImageBlock} and {@link module:image/imageinline~ImageInline}, respectively).
24
+ * * It translates the `sources` model element to the view (also: data) structure that may look as follows:
25
+ *
26
+ * <p>Inline image using picture:
27
+ * <picture>
28
+ * <source media="(min-width: 800px)" srcset="image-large.webp" type="image/webp">
29
+ * <source media="(max-width: 800px)" srcset="image-small.webp" type="image/webp">
30
+ * <!-- Other sources as specified in the "sources" model attribute... -->
31
+ * <img src="image.png" alt="An image using picture" />
32
+ * </picture>
33
+ * </p>
34
+ *
35
+ * <p>Block image using picture:</p>
36
+ * <figure class="image">
37
+ * <picture>
38
+ * <source media="(min-width: 800px)" srcset="image-large.webp" type="image/webp">
39
+ * <source media="(max-width: 800px)" srcset="image-small.webp" type="image/webp">
40
+ * <!-- Other sources as specified in the "sources" model attribute... -->
41
+ * <img src="image.png" alt="An image using picture" />
42
+ * </picture>
43
+ * <figcaption>Caption of the image</figcaption>
44
+ * </figure>
45
+ *
46
+ * **Note:** The value of the `sources` {@glink framework/guides/architecture/editing-engine#changing-the-model model attribute}
47
+ * in both examples equals:
48
+ *
49
+ * [
50
+ * {
51
+ * media: '(min-width: 800px)',
52
+ * srcset: 'image-large.webp',
53
+ * type: 'image/webp'
54
+ * },
55
+ * {
56
+ * media: '(max-width: 800px)',
57
+ * srcset: 'image-small.webp',
58
+ * type: 'image/webp'
59
+ * }
60
+ * ]
61
+ *
62
+ * * It integrates with the {@link module:image/imageupload~ImageUpload} plugin so images uploaded in the editor
63
+ * automatically render using `<picture>` if the {@glink features/images/image-upload/image-upload upload adapter}
64
+ * supports image sources and provides neccessary data.
65
+ *
66
+ * @private
67
+ * @extends module:core/plugin~Plugin
68
+ */
69
+ export default class PictureEditing extends Plugin {
70
+ /**
71
+ * @inheritDoc
72
+ */
73
+ static get requires() {
74
+ return [ ImageEditing, ImageUtils ];
75
+ }
76
+
77
+ /**
78
+ * @inheritDoc
79
+ */
80
+ static get pluginName() {
81
+ return 'PictureEditing';
82
+ }
83
+
84
+ /**
85
+ * @inheritDoc
86
+ */
87
+ afterInit() {
88
+ const editor = this.editor;
89
+
90
+ if ( editor.plugins.has( 'ImageBlockEditing' ) ) {
91
+ editor.model.schema.extend( 'imageBlock', {
92
+ allowAttributes: [ 'sources' ]
93
+ } );
94
+ }
95
+
96
+ if ( editor.plugins.has( 'ImageInlineEditing' ) ) {
97
+ editor.model.schema.extend( 'imageInline', {
98
+ allowAttributes: [ 'sources' ]
99
+ } );
100
+ }
101
+
102
+ this._setupConversion();
103
+ this._setupImageUploadEditingIntegration();
104
+ }
105
+
106
+ /**
107
+ * Configures conversion pipelines to support upcasting and downcasting images using the `<picture>` view element
108
+ * and the model `sources` attribute.
109
+ *
110
+ * @private
111
+ */
112
+ _setupConversion() {
113
+ const editor = this.editor;
114
+ const conversion = editor.conversion;
115
+ const imageUtils = editor.plugins.get( 'ImageUtils' );
116
+
117
+ conversion.for( 'upcast' ).add( upcastPicture( imageUtils ) );
118
+ conversion.for( 'downcast' ).add( downcastSourcesAttribute( imageUtils ) );
119
+ }
120
+
121
+ /**
122
+ * Makes it possible for uploaded images to get the `sources` model attribute and the `<picture>...</picture>`
123
+ * view structure out-of-the-box if relevant data is provided along the
124
+ * {@link module:image/imageupload/imageuploadediting~ImageUploadEditing#event:uploadComplete} event.
125
+ *
126
+ * @private
127
+ */
128
+ _setupImageUploadEditingIntegration() {
129
+ const editor = this.editor;
130
+
131
+ if ( !editor.plugins.has( 'ImageUploadEditing' ) ) {
132
+ return;
133
+ }
134
+
135
+ this.listenTo( editor.plugins.get( 'ImageUploadEditing' ), 'uploadComplete', ( evt, { imageElement, data } ) => {
136
+ const sources = data.sources;
137
+
138
+ if ( !sources ) {
139
+ return;
140
+ }
141
+
142
+ editor.model.change( writer => {
143
+ writer.setAttributes( {
144
+ sources
145
+ }, imageElement );
146
+ } );
147
+ } );
148
+ }
149
+ }
package/theme/image.css CHANGED
@@ -46,6 +46,13 @@
46
46
  /* This is required by Safari to resize images in a sensible way. Without this, the browser breaks the ratio. */
47
47
  align-items: flex-start;
48
48
 
49
+ /* When the picture is present it must act as a flex container to let the img resize properly */
50
+ & picture {
51
+ display: flex;
52
+ }
53
+
54
+ /* When the picture is present, it must act like a resizable img. */
55
+ & picture,
49
56
  & img {
50
57
  /* This is necessary for the img to span the entire .image-inline wrapper and to resize properly. */
51
58
  flex-grow: 1;