@ckeditor/ckeditor5-image 28.0.0 → 30.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.
- package/LICENSE.md +1 -1
- package/README.md +3 -3
- package/build/image.js +1 -1
- package/build/translations/ar.js +1 -0
- package/build/translations/ast.js +1 -0
- package/build/translations/az.js +1 -0
- package/build/translations/bg.js +1 -0
- package/build/translations/cs.js +1 -0
- package/build/translations/da.js +1 -0
- package/build/translations/de-ch.js +1 -0
- package/build/translations/de.js +1 -0
- package/build/translations/el.js +1 -0
- package/build/translations/en-au.js +1 -0
- package/build/translations/en-gb.js +1 -0
- package/build/translations/eo.js +1 -0
- package/build/translations/es.js +1 -0
- package/build/translations/et.js +1 -0
- package/build/translations/eu.js +1 -0
- package/build/translations/fa.js +1 -0
- package/build/translations/fi.js +1 -0
- package/build/translations/fr.js +1 -0
- package/build/translations/gl.js +1 -0
- package/build/translations/he.js +1 -0
- package/build/translations/hi.js +1 -0
- package/build/translations/hr.js +1 -0
- package/build/translations/hu.js +1 -0
- package/build/translations/id.js +1 -0
- package/build/translations/it.js +1 -0
- package/build/translations/ja.js +1 -0
- package/build/translations/km.js +1 -0
- package/build/translations/kn.js +1 -0
- package/build/translations/ko.js +1 -0
- package/build/translations/ku.js +1 -0
- package/build/translations/lt.js +1 -0
- package/build/translations/lv.js +1 -0
- package/build/translations/nb.js +1 -0
- package/build/translations/ne.js +1 -0
- package/build/translations/nl.js +1 -0
- package/build/translations/no.js +1 -0
- package/build/translations/pl.js +1 -0
- package/build/translations/pt-br.js +1 -0
- package/build/translations/pt.js +1 -0
- package/build/translations/ro.js +1 -0
- package/build/translations/ru.js +1 -0
- package/build/translations/si.js +1 -0
- package/build/translations/sk.js +1 -0
- package/build/translations/sq.js +1 -0
- package/build/translations/sr-latn.js +1 -0
- package/build/translations/sr.js +1 -0
- package/build/translations/sv.js +1 -0
- package/build/translations/th.js +1 -0
- package/build/translations/tk.js +1 -0
- package/build/translations/tr.js +1 -0
- package/build/translations/ug.js +1 -0
- package/build/translations/uk.js +1 -0
- package/build/translations/vi.js +1 -0
- package/build/translations/zh-cn.js +1 -0
- package/build/translations/zh.js +1 -0
- package/ckeditor5-metadata.json +233 -0
- package/lang/contexts.json +3 -0
- package/lang/translations/ar.po +12 -0
- package/lang/translations/ast.po +12 -0
- package/lang/translations/az.po +12 -0
- package/lang/translations/bg.po +12 -0
- package/lang/translations/cs.po +12 -0
- package/lang/translations/da.po +12 -0
- package/lang/translations/de-ch.po +12 -0
- package/lang/translations/de.po +15 -3
- package/lang/translations/el.po +12 -0
- package/lang/translations/en-au.po +12 -0
- package/lang/translations/en-gb.po +12 -0
- package/lang/translations/en.po +12 -0
- package/lang/translations/eo.po +12 -0
- package/lang/translations/es.po +12 -0
- package/lang/translations/et.po +12 -0
- package/lang/translations/eu.po +12 -0
- package/lang/translations/fa.po +12 -0
- package/lang/translations/fi.po +12 -0
- package/lang/translations/fr.po +12 -0
- package/lang/translations/gl.po +12 -0
- package/lang/translations/he.po +12 -0
- package/lang/translations/hi.po +12 -0
- package/lang/translations/hr.po +12 -0
- package/lang/translations/hu.po +13 -1
- package/lang/translations/id.po +21 -9
- package/lang/translations/it.po +12 -0
- package/lang/translations/ja.po +12 -0
- package/lang/translations/km.po +12 -0
- package/lang/translations/kn.po +12 -0
- package/lang/translations/ko.po +12 -0
- package/lang/translations/ku.po +12 -0
- package/lang/translations/lt.po +12 -0
- package/lang/translations/lv.po +12 -0
- package/lang/translations/nb.po +12 -0
- package/lang/translations/ne.po +12 -0
- package/lang/translations/nl.po +14 -2
- package/lang/translations/no.po +12 -0
- package/lang/translations/pl.po +20 -8
- package/lang/translations/pt-br.po +12 -0
- package/lang/translations/pt.po +12 -0
- package/lang/translations/ro.po +21 -9
- package/lang/translations/ru.po +12 -0
- package/lang/translations/si.po +12 -0
- package/lang/translations/sk.po +12 -0
- package/lang/translations/sq.po +12 -0
- package/lang/translations/sr-latn.po +12 -0
- package/lang/translations/sr.po +12 -0
- package/lang/translations/sv.po +12 -0
- package/lang/translations/th.po +12 -0
- package/lang/translations/tk.po +12 -0
- package/lang/translations/tr.po +12 -0
- package/lang/translations/ug.po +12 -0
- package/lang/translations/uk.po +12 -0
- package/lang/translations/vi.po +12 -0
- package/lang/translations/zh-cn.po +12 -0
- package/lang/translations/zh.po +12 -0
- package/package.json +36 -29
- package/src/autoimage.js +9 -4
- package/src/image/converters.js +191 -15
- package/src/image/imageblockediting.js +182 -0
- package/src/image/imageediting.js +13 -70
- package/src/image/imageinlineediting.js +207 -0
- package/src/image/imagetypecommand.js +105 -0
- package/src/image/insertimagecommand.js +77 -10
- package/src/image/ui/utils.js +5 -4
- package/src/image/utils.js +65 -121
- package/src/image.js +7 -19
- package/src/imageblock.js +46 -0
- package/src/imagecaption/imagecaptionediting.js +183 -227
- package/src/imagecaption/imagecaptionui.js +78 -0
- package/src/imagecaption/toggleimagecaptioncommand.js +165 -0
- package/src/imagecaption/utils.js +25 -40
- package/src/imagecaption.js +3 -2
- package/src/imageinline.js +46 -0
- package/src/imageinsert/imageinsertui.js +5 -6
- package/src/imageinsert.js +16 -4
- package/src/imageresize/imageresizebuttons.js +1 -1
- package/src/imageresize/imageresizeediting.js +21 -8
- package/src/imageresize/imageresizehandles.js +30 -8
- package/src/imageresize/resizeimagecommand.js +8 -5
- package/src/imagestyle/converters.js +26 -17
- package/src/imagestyle/imagestylecommand.js +73 -33
- package/src/imagestyle/imagestyleediting.js +113 -52
- package/src/imagestyle/imagestyleui.js +197 -31
- package/src/imagestyle/utils.js +300 -85
- package/src/imagestyle.js +218 -47
- package/src/imagetextalternative/imagetextalternativecommand.js +10 -7
- package/src/imagetextalternative/imagetextalternativeediting.js +9 -1
- package/src/imagetextalternative/imagetextalternativeui.js +2 -2
- package/src/imagetextalternative.js +1 -1
- package/src/imagetoolbar.js +33 -11
- package/src/imageupload/imageuploadediting.js +90 -30
- package/src/imageupload/imageuploadprogress.js +17 -9
- package/src/imageupload/imageuploadui.js +1 -1
- package/src/imageupload/uploadimagecommand.js +50 -24
- package/src/imageupload/utils.js +3 -2
- package/src/imageupload.js +1 -1
- package/src/imageutils.js +342 -0
- package/src/pictureediting.js +149 -0
- package/theme/image.css +101 -21
- package/theme/imagecaption.css +24 -2
- package/theme/imageresize.css +11 -0
- package/theme/imagestyle.css +76 -0
- package/theme/imageuploadicon.css +8 -2
- package/theme/imageuploadprogress.css +12 -8
- package/CHANGELOG.md +0 -423
- package/build/image.js.map +0 -1
|
@@ -0,0 +1,165 @@
|
|
|
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/imagecaption/toggleimagecaptioncommand
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { Command } from 'ckeditor5/src/core';
|
|
11
|
+
|
|
12
|
+
import ImageBlockEditing from '../image/imageblockediting';
|
|
13
|
+
import { getCaptionFromImageModelElement, getCaptionFromModelSelection } from './utils';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* The toggle image caption command.
|
|
17
|
+
*
|
|
18
|
+
* This command is registered by {@link module:image/imagecaption/imagecaptionediting~ImageCaptionEditing} as the
|
|
19
|
+
* `'toggleImageCaption'` editor command.
|
|
20
|
+
*
|
|
21
|
+
* Executing this command:
|
|
22
|
+
*
|
|
23
|
+
* * either adds or removes the image caption of a selected image (depending on whether the caption is present or not),
|
|
24
|
+
* * removes the image caption if the selection is anchored in one.
|
|
25
|
+
*
|
|
26
|
+
* // Toggle the presence of the caption.
|
|
27
|
+
* editor.execute( 'toggleImageCaption' );
|
|
28
|
+
*
|
|
29
|
+
* **Note**: Upon executing this command, the selection will be set on the image if previously anchored in the caption element.
|
|
30
|
+
*
|
|
31
|
+
* **Note**: You can move the selection to the caption right away as it shows up upon executing this command by using
|
|
32
|
+
* the `focusCaptionOnShow` option:
|
|
33
|
+
*
|
|
34
|
+
* editor.execute( 'toggleImageCaption', { focusCaptionOnShow: true } );
|
|
35
|
+
*
|
|
36
|
+
* @extends module:core/command~Command
|
|
37
|
+
*/
|
|
38
|
+
export default class ToggleImageCaptionCommand extends Command {
|
|
39
|
+
/**
|
|
40
|
+
* @inheritDoc
|
|
41
|
+
*/
|
|
42
|
+
refresh() {
|
|
43
|
+
const editor = this.editor;
|
|
44
|
+
const imageUtils = editor.plugins.get( 'ImageUtils' );
|
|
45
|
+
|
|
46
|
+
// Only block images can get captions.
|
|
47
|
+
if ( !editor.plugins.has( ImageBlockEditing ) ) {
|
|
48
|
+
this.isEnabled = false;
|
|
49
|
+
this.value = false;
|
|
50
|
+
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const selection = editor.model.document.selection;
|
|
55
|
+
const selectedElement = selection.getSelectedElement();
|
|
56
|
+
|
|
57
|
+
if ( !selectedElement ) {
|
|
58
|
+
const ancestorCaptionElement = getCaptionFromModelSelection( imageUtils, selection );
|
|
59
|
+
|
|
60
|
+
this.isEnabled = !!ancestorCaptionElement;
|
|
61
|
+
this.value = !!ancestorCaptionElement;
|
|
62
|
+
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Block images support captions by default but the command should also be enabled for inline
|
|
67
|
+
// images because toggling the caption when one is selected should convert it into a block image.
|
|
68
|
+
this.isEnabled = this.editor.plugins.get( 'ImageUtils' ).isImage( selectedElement );
|
|
69
|
+
|
|
70
|
+
if ( !this.isEnabled ) {
|
|
71
|
+
this.value = false;
|
|
72
|
+
} else {
|
|
73
|
+
this.value = !!getCaptionFromImageModelElement( selectedElement );
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Executes the command.
|
|
79
|
+
*
|
|
80
|
+
* editor.execute( 'toggleImageCaption' );
|
|
81
|
+
*
|
|
82
|
+
* @param {Object} [options] Options for the executed command.
|
|
83
|
+
* @param {String} [options.focusCaptionOnShow] When true and the caption shows up, the selection will be moved into it straight away.
|
|
84
|
+
* @fires execute
|
|
85
|
+
*/
|
|
86
|
+
execute( options = {} ) {
|
|
87
|
+
const { focusCaptionOnShow } = options;
|
|
88
|
+
|
|
89
|
+
this.editor.model.change( writer => {
|
|
90
|
+
if ( this.value ) {
|
|
91
|
+
this._hideImageCaption( writer );
|
|
92
|
+
} else {
|
|
93
|
+
this._showImageCaption( writer, focusCaptionOnShow );
|
|
94
|
+
}
|
|
95
|
+
} );
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Shows the caption of the `<imageBlock>` or `<imageInline>`. Also:
|
|
100
|
+
*
|
|
101
|
+
* * it converts `<imageInline>` to `<imageBlock>` to show the caption,
|
|
102
|
+
* * it attempts to restore the caption content from the `ImageCaptionEditing` caption registry,
|
|
103
|
+
* * it moves the selection to the caption right away, it the `focusCaptionOnShow` option was set.
|
|
104
|
+
*
|
|
105
|
+
* @private
|
|
106
|
+
* @param {module:engine/model/writer~Writer} writer
|
|
107
|
+
*/
|
|
108
|
+
_showImageCaption( writer, focusCaptionOnShow ) {
|
|
109
|
+
const model = this.editor.model;
|
|
110
|
+
const selection = model.document.selection;
|
|
111
|
+
const imageCaptionEditing = this.editor.plugins.get( 'ImageCaptionEditing' );
|
|
112
|
+
|
|
113
|
+
let selectedImage = selection.getSelectedElement();
|
|
114
|
+
|
|
115
|
+
const savedCaption = imageCaptionEditing._getSavedCaption( selectedImage );
|
|
116
|
+
|
|
117
|
+
// Convert imageInline -> image first.
|
|
118
|
+
if ( this.editor.plugins.get( 'ImageUtils' ).isInlineImage( selectedImage ) ) {
|
|
119
|
+
this.editor.execute( 'imageTypeBlock' );
|
|
120
|
+
|
|
121
|
+
// Executing the command created a new model element. Let's pick it again.
|
|
122
|
+
selectedImage = selection.getSelectedElement();
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Try restoring the caption from the ImageCaptionEditing plugin storage.
|
|
126
|
+
const newCaptionElement = savedCaption || writer.createElement( 'caption' );
|
|
127
|
+
|
|
128
|
+
writer.append( newCaptionElement, selectedImage );
|
|
129
|
+
|
|
130
|
+
if ( focusCaptionOnShow ) {
|
|
131
|
+
writer.setSelection( newCaptionElement, 'in' );
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Hides the caption of a selected image (or an image caption the selection is anchored to).
|
|
137
|
+
*
|
|
138
|
+
* The content of the caption is stored in the `ImageCaptionEditing` caption registry to make this
|
|
139
|
+
* a reversible action.
|
|
140
|
+
*
|
|
141
|
+
* @private
|
|
142
|
+
* @param {module:engine/model/writer~Writer} writer
|
|
143
|
+
*/
|
|
144
|
+
_hideImageCaption( writer ) {
|
|
145
|
+
const editor = this.editor;
|
|
146
|
+
const selection = editor.model.document.selection;
|
|
147
|
+
const imageCaptionEditing = editor.plugins.get( 'ImageCaptionEditing' );
|
|
148
|
+
const imageUtils = editor.plugins.get( 'ImageUtils' );
|
|
149
|
+
let selectedImage = selection.getSelectedElement();
|
|
150
|
+
let captionElement;
|
|
151
|
+
|
|
152
|
+
if ( selectedImage ) {
|
|
153
|
+
captionElement = getCaptionFromImageModelElement( selectedImage );
|
|
154
|
+
} else {
|
|
155
|
+
captionElement = getCaptionFromModelSelection( imageUtils, selection );
|
|
156
|
+
selectedImage = captionElement.parent;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Store the caption content so it can be restored quickly if the user changes their mind even if they toggle image<->imageInline.
|
|
160
|
+
imageCaptionEditing._saveCaption( selectedImage, captionElement );
|
|
161
|
+
|
|
162
|
+
writer.setSelection( selectedImage, 'on' );
|
|
163
|
+
writer.remove( captionElement );
|
|
164
|
+
}
|
|
165
|
+
}
|
|
@@ -7,48 +7,13 @@
|
|
|
7
7
|
* @module image/imagecaption/utils
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import { enablePlaceholder } from 'ckeditor5/src/engine';
|
|
11
|
-
import { toWidgetEditable } from 'ckeditor5/src/widget';
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Returns a function that creates a caption editable element for the given {@link module:engine/view/document~Document}.
|
|
15
|
-
*
|
|
16
|
-
* @param {module:engine/view/view~View} view
|
|
17
|
-
* @param {String} placeholderText The text to be displayed when the caption is empty.
|
|
18
|
-
* @returns {Function}
|
|
19
|
-
*/
|
|
20
|
-
export function captionElementCreator( view, placeholderText ) {
|
|
21
|
-
return writer => {
|
|
22
|
-
const editable = writer.createEditableElement( 'figcaption' );
|
|
23
|
-
writer.setCustomProperty( 'imageCaption', true, editable );
|
|
24
|
-
|
|
25
|
-
enablePlaceholder( {
|
|
26
|
-
view,
|
|
27
|
-
element: editable,
|
|
28
|
-
text: placeholderText
|
|
29
|
-
} );
|
|
30
|
-
|
|
31
|
-
return toWidgetEditable( editable, writer );
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Returns `true` if a given view element is the image caption editable.
|
|
37
|
-
*
|
|
38
|
-
* @param {module:engine/view/element~Element} viewElement
|
|
39
|
-
* @returns {Boolean}
|
|
40
|
-
*/
|
|
41
|
-
export function isCaption( viewElement ) {
|
|
42
|
-
return !!viewElement.getCustomProperty( 'imageCaption' );
|
|
43
|
-
}
|
|
44
|
-
|
|
45
10
|
/**
|
|
46
11
|
* Returns the caption model element from a given image element. Returns `null` if no caption is found.
|
|
47
12
|
*
|
|
48
13
|
* @param {module:engine/model/element~Element} imageModelElement
|
|
49
14
|
* @returns {module:engine/model/element~Element|null}
|
|
50
15
|
*/
|
|
51
|
-
export function
|
|
16
|
+
export function getCaptionFromImageModelElement( imageModelElement ) {
|
|
52
17
|
for ( const node of imageModelElement.getChildren() ) {
|
|
53
18
|
if ( !!node && node.is( 'element', 'caption' ) ) {
|
|
54
19
|
return node;
|
|
@@ -58,19 +23,39 @@ export function getCaptionFromImage( imageModelElement ) {
|
|
|
58
23
|
return null;
|
|
59
24
|
}
|
|
60
25
|
|
|
26
|
+
/**
|
|
27
|
+
* Returns the caption model element for a model selection. Returns `null` if the selection has no caption element ancestor.
|
|
28
|
+
*
|
|
29
|
+
* @param {module:image/imageutils~ImageUtils} imageUtils
|
|
30
|
+
* @param {module:engine/model/selection~Selection} selection
|
|
31
|
+
* @returns {module:engine/model/element~Element|null}
|
|
32
|
+
*/
|
|
33
|
+
export function getCaptionFromModelSelection( imageUtils, selection ) {
|
|
34
|
+
const captionElement = selection.getFirstPosition().findAncestor( 'caption' );
|
|
35
|
+
|
|
36
|
+
if ( !captionElement ) {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if ( imageUtils.isBlockImage( captionElement.parent ) ) {
|
|
41
|
+
return captionElement;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
|
|
61
47
|
/**
|
|
62
48
|
* {@link module:engine/view/matcher~Matcher} pattern. Checks if a given element is a `<figcaption>` element that is placed
|
|
63
49
|
* inside the image `<figure>` element.
|
|
64
50
|
*
|
|
51
|
+
* @param {module:image/imageutils~ImageUtils} imageUtils
|
|
65
52
|
* @param {module:engine/view/element~Element} element
|
|
66
53
|
* @returns {Object|null} Returns the object accepted by {@link module:engine/view/matcher~Matcher} or `null` if the element
|
|
67
54
|
* cannot be matched.
|
|
68
55
|
*/
|
|
69
|
-
export function
|
|
70
|
-
const parent = element.parent;
|
|
71
|
-
|
|
56
|
+
export function matchImageCaptionViewElement( imageUtils, element ) {
|
|
72
57
|
// Convert only captions for images.
|
|
73
|
-
if ( element.name == 'figcaption' &&
|
|
58
|
+
if ( element.name == 'figcaption' && imageUtils.isBlockImageView( element.parent ) ) {
|
|
74
59
|
return { name: true };
|
|
75
60
|
}
|
|
76
61
|
|
package/src/imagecaption.js
CHANGED
|
@@ -9,13 +9,14 @@
|
|
|
9
9
|
|
|
10
10
|
import { Plugin } from 'ckeditor5/src/core';
|
|
11
11
|
import ImageCaptionEditing from './imagecaption/imagecaptionediting';
|
|
12
|
+
import ImageCaptionUI from './imagecaption/imagecaptionui';
|
|
12
13
|
|
|
13
14
|
import '../theme/imagecaption.css';
|
|
14
15
|
|
|
15
16
|
/**
|
|
16
17
|
* The image caption plugin.
|
|
17
18
|
*
|
|
18
|
-
* For a detailed overview, check the {@glink features/
|
|
19
|
+
* For a detailed overview, check the {@glink features/images/images-captions image caption} documentation.
|
|
19
20
|
*
|
|
20
21
|
* @extends module:core/plugin~Plugin
|
|
21
22
|
*/
|
|
@@ -24,7 +25,7 @@ export default class ImageCaption extends Plugin {
|
|
|
24
25
|
* @inheritDoc
|
|
25
26
|
*/
|
|
26
27
|
static get requires() {
|
|
27
|
-
return [ ImageCaptionEditing ];
|
|
28
|
+
return [ ImageCaptionEditing, ImageCaptionUI ];
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
/**
|
|
@@ -0,0 +1,46 @@
|
|
|
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/imageinline
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { Plugin } from 'ckeditor5/src/core';
|
|
11
|
+
import { Widget } from 'ckeditor5/src/widget';
|
|
12
|
+
|
|
13
|
+
import ImageTextAlternative from './imagetextalternative';
|
|
14
|
+
import ImageInlineEditing from './image/imageinlineediting';
|
|
15
|
+
|
|
16
|
+
import '../theme/image.css';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* The image inline plugin.
|
|
20
|
+
*
|
|
21
|
+
* This is a "glue" plugin which loads the following plugins:
|
|
22
|
+
*
|
|
23
|
+
* * {@link module:image/image/imageinlineediting~ImageInlineEditing},
|
|
24
|
+
* * {@link module:image/imagetextalternative~ImageTextAlternative}.
|
|
25
|
+
*
|
|
26
|
+
* Usually, it is used in conjunction with other plugins from this package. See the {@glink api/image package page}
|
|
27
|
+
* for more information.
|
|
28
|
+
*
|
|
29
|
+
* @extends module:core/plugin~Plugin
|
|
30
|
+
*/
|
|
31
|
+
export default class ImageInline extends Plugin {
|
|
32
|
+
/**
|
|
33
|
+
* @inheritDoc
|
|
34
|
+
*/
|
|
35
|
+
static get requires() {
|
|
36
|
+
return [ ImageInlineEditing, Widget, ImageTextAlternative ];
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* @inheritDoc
|
|
41
|
+
*/
|
|
42
|
+
static get pluginName() {
|
|
43
|
+
return 'ImageInline';
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
@@ -11,13 +11,11 @@ import { Plugin } from 'ckeditor5/src/core';
|
|
|
11
11
|
import ImageInsertPanelView from './ui/imageinsertpanelview';
|
|
12
12
|
import { prepareIntegrations } from './utils';
|
|
13
13
|
|
|
14
|
-
import { isImage } from '../image/utils';
|
|
15
|
-
|
|
16
14
|
/**
|
|
17
15
|
* The image insert dropdown plugin.
|
|
18
16
|
*
|
|
19
|
-
* For a detailed overview, check the {@glink features/image-upload/image-upload Image upload feature}
|
|
20
|
-
* and {@glink features/image#inserting-images-via-source-url Insert images via source URL} documentation.
|
|
17
|
+
* For a detailed overview, check the {@glink features/images/image-upload/image-upload Image upload feature}
|
|
18
|
+
* and {@glink features/images/image-upload/images-inserting#inserting-images-via-source-url Insert images via source URL} documentation.
|
|
21
19
|
*
|
|
22
20
|
* Adds the `'insertImage'` dropdown to the {@link module:ui/componentfactory~ComponentFactory UI component factory}
|
|
23
21
|
* and also the `imageInsert` dropdown as an alias for backward compatibility.
|
|
@@ -92,6 +90,7 @@ export default class ImageInsertUI extends Plugin {
|
|
|
92
90
|
const insertButtonView = imageInsertView.insertButtonView;
|
|
93
91
|
const insertImageViaUrlForm = imageInsertView.getIntegration( 'insertImageViaUrl' );
|
|
94
92
|
const panelView = dropdownView.panelView;
|
|
93
|
+
const imageUtils = this.editor.plugins.get( 'ImageUtils' );
|
|
95
94
|
|
|
96
95
|
dropdownView.bind( 'isEnabled' ).to( command );
|
|
97
96
|
|
|
@@ -107,7 +106,7 @@ export default class ImageInsertUI extends Plugin {
|
|
|
107
106
|
if ( dropdownView.isOpen ) {
|
|
108
107
|
imageInsertView.focus();
|
|
109
108
|
|
|
110
|
-
if ( isImage( selectedElement ) ) {
|
|
109
|
+
if ( imageUtils.isImage( selectedElement ) ) {
|
|
111
110
|
imageInsertView.imageURLInputValue = selectedElement.getAttribute( 'src' );
|
|
112
111
|
insertButtonView.label = t( 'Update' );
|
|
113
112
|
insertImageViaUrlForm.label = t( 'Update image URL' );
|
|
@@ -137,7 +136,7 @@ export default class ImageInsertUI extends Plugin {
|
|
|
137
136
|
function onSubmit() {
|
|
138
137
|
const selectedElement = editor.model.document.selection.getSelectedElement();
|
|
139
138
|
|
|
140
|
-
if ( isImage( selectedElement ) ) {
|
|
139
|
+
if ( imageUtils.isImage( selectedElement ) ) {
|
|
141
140
|
editor.model.change( writer => {
|
|
142
141
|
writer.setAttribute( 'src', imageInsertView.imageURLInputValue, selectedElement );
|
|
143
142
|
writer.removeAttribute( 'srcset', selectedElement );
|
package/src/imageinsert.js
CHANGED
|
@@ -14,8 +14,8 @@ import ImageInsertUI from './imageinsert/imageinsertui';
|
|
|
14
14
|
/**
|
|
15
15
|
* The image insert plugin.
|
|
16
16
|
*
|
|
17
|
-
* For a detailed overview, check the {@glink features/image-upload/image-upload Image upload feature}
|
|
18
|
-
* and {@glink features/image#inserting-images-via-source-url Insert images via source URL} documentation.
|
|
17
|
+
* For a detailed overview, check the {@glink features/images/image-upload/image-upload Image upload feature}
|
|
18
|
+
* and {@glink features/images/image-upload/images-inserting#inserting-images-via-source-url Insert images via source URL} documentation.
|
|
19
19
|
*
|
|
20
20
|
* This plugin does not do anything directly, but it loads a set of specific plugins
|
|
21
21
|
* to enable image uploading or inserting via implemented integrations:
|
|
@@ -44,7 +44,6 @@ export default class ImageInsert extends Plugin {
|
|
|
44
44
|
/**
|
|
45
45
|
* The image insert configuration.
|
|
46
46
|
*
|
|
47
|
-
* @protected
|
|
48
47
|
* @member {module:image/imageinsert~ImageInsertConfig} module:image/image~ImageConfig#insert
|
|
49
48
|
*/
|
|
50
49
|
|
|
@@ -64,7 +63,6 @@ export default class ImageInsert extends Plugin {
|
|
|
64
63
|
*
|
|
65
64
|
* See {@link module:core/editor/editorconfig~EditorConfig all editor options}.
|
|
66
65
|
*
|
|
67
|
-
* @protected
|
|
68
66
|
* @interface module:image/imageinsert~ImageInsertConfig
|
|
69
67
|
*/
|
|
70
68
|
|
|
@@ -90,6 +88,20 @@ export default class ImageInsert extends Plugin {
|
|
|
90
88
|
* }
|
|
91
89
|
* };
|
|
92
90
|
*
|
|
91
|
+
* @protected
|
|
93
92
|
* @member {Array.<String>} module:image/imageinsert~ImageInsertConfig#integrations
|
|
94
93
|
* @default [ 'insertImageViaUrl' ]
|
|
95
94
|
*/
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* This options allows to override the image type used by the {@link module:image/image/insertimagecommand~InsertImageCommand} when the user
|
|
98
|
+
* inserts new images into the editor content. By default, this option is unset which means the editor will choose the optimal image type
|
|
99
|
+
* based on the context of the insertion (e.g. the current selection and availability of plugins)
|
|
100
|
+
*
|
|
101
|
+
* Available options are:
|
|
102
|
+
*
|
|
103
|
+
* * `'block'` – all images inserted into the editor will be block (requires the {@link module:image/imageblock~ImageBlock} plugin),
|
|
104
|
+
* * `'inline'` – all images inserted into the editor will be inline (requires the {@link module:image/imageinline~ImageInline} plugin).
|
|
105
|
+
*
|
|
106
|
+
* @member {'inline'|'block'|undefined} module:image/imageinsert~ImageInsertConfig#type
|
|
107
|
+
*/
|
|
@@ -268,7 +268,7 @@ function getIsOnButtonCallback( value ) {
|
|
|
268
268
|
* * If you configure the feature using the resize dropdown, this name will be used for a list item in the dropdown.
|
|
269
269
|
* @property {String} value The value of the resize option without the unit
|
|
270
270
|
* ({@link module:image/image~ImageConfig#resizeUnit configured separately}). `null` resets an image to its original size.
|
|
271
|
-
* @property {String} [
|
|
271
|
+
* @property {String} [icon] An icon used by an individual resize button (see the `name` property to learn more).
|
|
272
272
|
* Available icons are: `'small'`, `'medium'`, `'large'`, `'original'`.
|
|
273
273
|
* @property {String} [label] An option label displayed in the dropdown or, if the feature is configured using
|
|
274
274
|
* individual buttons, a {@link module:ui/button/buttonview~ButtonView#tooltip} and an ARIA attribute of a button.
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { Plugin } from 'ckeditor5/src/core';
|
|
11
|
+
import ImageUtils from '../imageutils';
|
|
11
12
|
import ResizeImageCommand from './resizeimagecommand';
|
|
12
13
|
|
|
13
14
|
/**
|
|
@@ -19,6 +20,13 @@ import ResizeImageCommand from './resizeimagecommand';
|
|
|
19
20
|
* @extends module:core/plugin~Plugin
|
|
20
21
|
*/
|
|
21
22
|
export default class ImageResizeEditing extends Plugin {
|
|
23
|
+
/**
|
|
24
|
+
* @inheritDoc
|
|
25
|
+
*/
|
|
26
|
+
static get requires() {
|
|
27
|
+
return [ ImageUtils ];
|
|
28
|
+
}
|
|
29
|
+
|
|
22
30
|
/**
|
|
23
31
|
* @inheritDoc
|
|
24
32
|
*/
|
|
@@ -65,7 +73,8 @@ export default class ImageResizeEditing extends Plugin {
|
|
|
65
73
|
const resizeImageCommand = new ResizeImageCommand( editor );
|
|
66
74
|
|
|
67
75
|
this._registerSchema();
|
|
68
|
-
this._registerConverters();
|
|
76
|
+
this._registerConverters( 'imageBlock' );
|
|
77
|
+
this._registerConverters( 'imageInline' );
|
|
69
78
|
|
|
70
79
|
// Register `resizeImage` command and add `imageResize` command as an alias for backward compatibility.
|
|
71
80
|
editor.commands.add( 'resizeImage', resizeImageCommand );
|
|
@@ -76,23 +85,27 @@ export default class ImageResizeEditing extends Plugin {
|
|
|
76
85
|
* @private
|
|
77
86
|
*/
|
|
78
87
|
_registerSchema() {
|
|
79
|
-
this.editor.
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
88
|
+
if ( this.editor.plugins.has( 'ImageBlockEditing' ) ) {
|
|
89
|
+
this.editor.model.schema.extend( 'imageBlock', { allowAttributes: 'width' } );
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if ( this.editor.plugins.has( 'ImageInlineEditing' ) ) {
|
|
93
|
+
this.editor.model.schema.extend( 'imageInline', { allowAttributes: 'width' } );
|
|
94
|
+
}
|
|
83
95
|
}
|
|
84
96
|
|
|
85
97
|
/**
|
|
86
98
|
* Registers image resize converters.
|
|
87
99
|
*
|
|
88
100
|
* @private
|
|
101
|
+
* @param {'imageBlock'|'imageInline'} imageType The type of the image.
|
|
89
102
|
*/
|
|
90
|
-
_registerConverters() {
|
|
103
|
+
_registerConverters( imageType ) {
|
|
91
104
|
const editor = this.editor;
|
|
92
105
|
|
|
93
106
|
// Dedicated converter to propagate image's attribute to the img tag.
|
|
94
107
|
editor.conversion.for( 'downcast' ).add( dispatcher =>
|
|
95
|
-
dispatcher.on(
|
|
108
|
+
dispatcher.on( `attribute:width:${ imageType }`, ( evt, data, conversionApi ) => {
|
|
96
109
|
if ( !conversionApi.consumable.consume( data.item, evt.name ) ) {
|
|
97
110
|
return;
|
|
98
111
|
}
|
|
@@ -113,7 +126,7 @@ export default class ImageResizeEditing extends Plugin {
|
|
|
113
126
|
editor.conversion.for( 'upcast' )
|
|
114
127
|
.attributeToAttribute( {
|
|
115
128
|
view: {
|
|
116
|
-
name: 'figure',
|
|
129
|
+
name: imageType === 'imageBlock' ? 'figure' : 'img',
|
|
117
130
|
styles: {
|
|
118
131
|
width: /.+/
|
|
119
132
|
}
|
|
@@ -12,6 +12,18 @@ import { WidgetResize } from 'ckeditor5/src/widget';
|
|
|
12
12
|
|
|
13
13
|
import ImageLoadObserver from '../image/imageloadobserver';
|
|
14
14
|
|
|
15
|
+
const RESIZABLE_IMAGES_CSS_SELECTOR =
|
|
16
|
+
'figure.image.ck-widget > img,' +
|
|
17
|
+
'figure.image.ck-widget > picture > img,' +
|
|
18
|
+
'figure.image.ck-widget > a > img,' +
|
|
19
|
+
'figure.image.ck-widget > a > picture > img,' +
|
|
20
|
+
'span.image-inline.ck-widget > img,' +
|
|
21
|
+
'span.image-inline.ck-widget > picture > img';
|
|
22
|
+
|
|
23
|
+
const IMAGE_WIDGETS_CLASSES_MATCH_REGEXP = /(image|image-inline)/;
|
|
24
|
+
|
|
25
|
+
const RESIZED_IMAGE_CLASS = 'image_resized';
|
|
26
|
+
|
|
15
27
|
/**
|
|
16
28
|
* The image resize by handles feature.
|
|
17
29
|
*
|
|
@@ -58,12 +70,13 @@ export default class ImageResizeHandles extends Plugin {
|
|
|
58
70
|
|
|
59
71
|
this.listenTo( editingView.document, 'imageLoaded', ( evt, domEvent ) => {
|
|
60
72
|
// The resizer must be attached only to images loaded by the `ImageInsert`, `ImageUpload` or `LinkImage` plugins.
|
|
61
|
-
if ( !domEvent.target.matches(
|
|
73
|
+
if ( !domEvent.target.matches( RESIZABLE_IMAGES_CSS_SELECTOR ) ) {
|
|
62
74
|
return;
|
|
63
75
|
}
|
|
64
76
|
|
|
65
|
-
const
|
|
66
|
-
const
|
|
77
|
+
const domConverter = editor.editing.view.domConverter;
|
|
78
|
+
const imageView = domConverter.domToView( domEvent.target );
|
|
79
|
+
const widgetView = imageView.findAncestor( { classes: IMAGE_WIDGETS_CLASSES_MATCH_REGEXP } );
|
|
67
80
|
let resizer = this.editor.plugins.get( WidgetResize ).getResizerByViewElement( widgetView );
|
|
68
81
|
|
|
69
82
|
if ( resizer ) {
|
|
@@ -89,25 +102,34 @@ export default class ImageResizeHandles extends Plugin {
|
|
|
89
102
|
getHandleHost( domWidgetElement ) {
|
|
90
103
|
return domWidgetElement.querySelector( 'img' );
|
|
91
104
|
},
|
|
92
|
-
getResizeHost(
|
|
93
|
-
|
|
105
|
+
getResizeHost() {
|
|
106
|
+
// Return the model image element parent to avoid setting an inline element (<a>/<span>) as a resize host.
|
|
107
|
+
return domConverter.viewToDom( mapper.toViewElement( imageModel.parent ) );
|
|
94
108
|
},
|
|
95
109
|
// TODO consider other positions.
|
|
96
110
|
isCentered() {
|
|
97
111
|
const imageStyle = imageModel.getAttribute( 'imageStyle' );
|
|
98
112
|
|
|
99
|
-
return !imageStyle || imageStyle == '
|
|
113
|
+
return !imageStyle || imageStyle == 'block' || imageStyle == 'alignCenter';
|
|
100
114
|
},
|
|
101
115
|
|
|
102
116
|
onCommit( newValue ) {
|
|
117
|
+
// Get rid of the CSS class in case the command execution that follows is unsuccessful
|
|
118
|
+
// (e.g. Track Changes can override it and the new dimensions will not apply). Otherwise,
|
|
119
|
+
// the presence of the class and the absence of the width style will cause it to take 100%
|
|
120
|
+
// of the horizontal space.
|
|
121
|
+
editingView.change( writer => {
|
|
122
|
+
writer.removeClass( RESIZED_IMAGE_CLASS, widgetView );
|
|
123
|
+
} );
|
|
124
|
+
|
|
103
125
|
editor.execute( 'resizeImage', { width: newValue } );
|
|
104
126
|
}
|
|
105
127
|
} );
|
|
106
128
|
|
|
107
129
|
resizer.on( 'updateSize', () => {
|
|
108
|
-
if ( !widgetView.hasClass(
|
|
130
|
+
if ( !widgetView.hasClass( RESIZED_IMAGE_CLASS ) ) {
|
|
109
131
|
editingView.change( writer => {
|
|
110
|
-
writer.addClass(
|
|
132
|
+
writer.addClass( RESIZED_IMAGE_CLASS, widgetView );
|
|
111
133
|
} );
|
|
112
134
|
}
|
|
113
135
|
} );
|
|
@@ -8,7 +8,6 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { Command } from 'ckeditor5/src/core';
|
|
11
|
-
import { isImage } from '../image/utils';
|
|
12
11
|
|
|
13
12
|
/**
|
|
14
13
|
* The resize image command. Currently, it only supports the width attribute.
|
|
@@ -20,9 +19,11 @@ export default class ResizeImageCommand extends Command {
|
|
|
20
19
|
* @inheritDoc
|
|
21
20
|
*/
|
|
22
21
|
refresh() {
|
|
23
|
-
const
|
|
22
|
+
const editor = this.editor;
|
|
23
|
+
const imageUtils = editor.plugins.get( 'ImageUtils' );
|
|
24
|
+
const element = imageUtils.getClosestSelectedImageElement( editor.model.document.selection );
|
|
24
25
|
|
|
25
|
-
this.isEnabled =
|
|
26
|
+
this.isEnabled = !!element;
|
|
26
27
|
|
|
27
28
|
if ( !element || !element.hasAttribute( 'width' ) ) {
|
|
28
29
|
this.value = null;
|
|
@@ -48,8 +49,10 @@ export default class ResizeImageCommand extends Command {
|
|
|
48
49
|
* @fires execute
|
|
49
50
|
*/
|
|
50
51
|
execute( options ) {
|
|
51
|
-
const
|
|
52
|
-
const
|
|
52
|
+
const editor = this.editor;
|
|
53
|
+
const model = editor.model;
|
|
54
|
+
const imageUtils = editor.plugins.get( 'ImageUtils' );
|
|
55
|
+
const imageElement = imageUtils.getClosestSelectedImageElement( model.document.selection );
|
|
53
56
|
|
|
54
57
|
this.value = {
|
|
55
58
|
width: options.width,
|