@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
|
@@ -8,18 +8,30 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { Plugin } from 'ckeditor5/src/core';
|
|
11
|
-
import { ButtonView } from 'ckeditor5/src/ui';
|
|
12
|
-
|
|
13
|
-
import
|
|
11
|
+
import { ButtonView, createDropdown, addToolbarToDropdown, SplitButtonView } from 'ckeditor5/src/ui';
|
|
12
|
+
import ImageStyleEditing from './imagestyleediting';
|
|
13
|
+
import utils from './utils';
|
|
14
|
+
import { isObject, identity } from 'lodash-es';
|
|
14
15
|
|
|
15
16
|
import '../../theme/imagestyle.css';
|
|
16
17
|
|
|
17
18
|
/**
|
|
18
19
|
* The image style UI plugin.
|
|
19
20
|
*
|
|
21
|
+
* It registers buttons corresponding to the {@link module:image/image~ImageConfig#styles} configuration.
|
|
22
|
+
* It also registers the {@link module:image/imagestyle/utils~DEFAULT_DROPDOWN_DEFINITIONS default drop-downs} and the
|
|
23
|
+
* custom drop-downs defined by the developer in the {@link module:image/image~ImageConfig#toolbar} configuration.
|
|
24
|
+
*
|
|
20
25
|
* @extends module:core/plugin~Plugin
|
|
21
26
|
*/
|
|
22
27
|
export default class ImageStyleUI extends Plugin {
|
|
28
|
+
/**
|
|
29
|
+
* @inheritDoc
|
|
30
|
+
*/
|
|
31
|
+
static get requires() {
|
|
32
|
+
return [ ImageStyleEditing ];
|
|
33
|
+
}
|
|
34
|
+
|
|
23
35
|
/**
|
|
24
36
|
* @inheritDoc
|
|
25
37
|
*/
|
|
@@ -31,8 +43,11 @@ export default class ImageStyleUI extends Plugin {
|
|
|
31
43
|
* Returns the default localized style titles provided by the plugin.
|
|
32
44
|
*
|
|
33
45
|
* The following localized titles corresponding with
|
|
34
|
-
* {@link module:image/imagestyle/utils~
|
|
46
|
+
* {@link module:image/imagestyle/utils~DEFAULT_OPTIONS} are available:
|
|
35
47
|
*
|
|
48
|
+
* * `'Wrap text'`,
|
|
49
|
+
* * `'Break text'`,
|
|
50
|
+
* * `'In line'`,
|
|
36
51
|
* * `'Full size image'`,
|
|
37
52
|
* * `'Side image'`,
|
|
38
53
|
* * `'Left aligned image'`,
|
|
@@ -45,6 +60,9 @@ export default class ImageStyleUI extends Plugin {
|
|
|
45
60
|
const t = this.editor.t;
|
|
46
61
|
|
|
47
62
|
return {
|
|
63
|
+
'Wrap text': t( 'Wrap text' ),
|
|
64
|
+
'Break text': t( 'Break text' ),
|
|
65
|
+
'In line': t( 'In line' ),
|
|
48
66
|
'Full size image': t( 'Full size image' ),
|
|
49
67
|
'Side image': t( 'Side image' ),
|
|
50
68
|
'Left aligned image': t( 'Left aligned image' ),
|
|
@@ -57,58 +75,142 @@ export default class ImageStyleUI extends Plugin {
|
|
|
57
75
|
* @inheritDoc
|
|
58
76
|
*/
|
|
59
77
|
init() {
|
|
60
|
-
const
|
|
61
|
-
const
|
|
78
|
+
const plugins = this.editor.plugins;
|
|
79
|
+
const toolbarConfig = this.editor.config.get( 'image.toolbar' ) || [];
|
|
80
|
+
|
|
81
|
+
const definedStyles = translateStyles(
|
|
82
|
+
plugins.get( 'ImageStyleEditing' ).normalizedStyles,
|
|
83
|
+
this.localizedDefaultStylesTitles
|
|
84
|
+
);
|
|
62
85
|
|
|
63
|
-
|
|
86
|
+
for ( const styleConfig of definedStyles ) {
|
|
87
|
+
this._createButton( styleConfig );
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const definedDropdowns = translateStyles(
|
|
91
|
+
[ ...toolbarConfig.filter( isObject ), ...utils.getDefaultDropdownDefinitions( plugins ) ],
|
|
92
|
+
this.localizedDefaultStylesTitles
|
|
93
|
+
);
|
|
64
94
|
|
|
65
|
-
for ( const
|
|
66
|
-
this.
|
|
95
|
+
for ( const dropdownConfig of definedDropdowns ) {
|
|
96
|
+
this._createDropdown( dropdownConfig, definedStyles );
|
|
67
97
|
}
|
|
68
98
|
}
|
|
69
99
|
|
|
70
100
|
/**
|
|
71
|
-
* Creates a
|
|
101
|
+
* Creates a dropdown and stores it in the editor {@link module:ui/componentfactory~ComponentFactory}.
|
|
72
102
|
*
|
|
73
103
|
* @private
|
|
74
|
-
* @param {module:image/imagestyle/
|
|
104
|
+
* @param {module:image/imagestyle/imagestyleui~ImageStyleDropdownDefinition} dropdownConfig
|
|
105
|
+
* @param {Array.<module:image/imagestyle~ImageStyleOptionDefinition>} definedStyles
|
|
75
106
|
*/
|
|
76
|
-
|
|
77
|
-
const
|
|
107
|
+
_createDropdown( dropdownConfig, definedStyles ) {
|
|
108
|
+
const factory = this.editor.ui.componentFactory;
|
|
109
|
+
|
|
110
|
+
factory.add( dropdownConfig.name, locale => {
|
|
111
|
+
let defaultButton;
|
|
112
|
+
|
|
113
|
+
const { defaultItem, items, title } = dropdownConfig;
|
|
114
|
+
const buttonViews = items
|
|
115
|
+
.filter( itemName => definedStyles.find( ( { name } ) => getUIComponentName( name ) === itemName ) )
|
|
116
|
+
.map( buttonName => {
|
|
117
|
+
const button = factory.create( buttonName );
|
|
118
|
+
|
|
119
|
+
if ( buttonName === defaultItem ) {
|
|
120
|
+
defaultButton = button;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return button;
|
|
124
|
+
} );
|
|
125
|
+
|
|
126
|
+
if ( items.length !== buttonViews.length ) {
|
|
127
|
+
utils.warnInvalidStyle( { dropdown: dropdownConfig } );
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const dropdownView = createDropdown( locale, SplitButtonView );
|
|
131
|
+
const splitButtonView = dropdownView.buttonView;
|
|
78
132
|
|
|
79
|
-
|
|
133
|
+
addToolbarToDropdown( dropdownView, buttonViews );
|
|
80
134
|
|
|
81
|
-
|
|
82
|
-
|
|
135
|
+
splitButtonView.set( {
|
|
136
|
+
label: getDropdownButtonTitle( title, defaultButton.label ),
|
|
137
|
+
class: null,
|
|
138
|
+
tooltip: true
|
|
139
|
+
} );
|
|
140
|
+
|
|
141
|
+
splitButtonView.bind( 'icon' ).toMany( buttonViews, 'isOn', ( ...areOn ) => {
|
|
142
|
+
const index = areOn.findIndex( identity );
|
|
143
|
+
|
|
144
|
+
return ( index < 0 ) ? defaultButton.icon : buttonViews[ index ].icon;
|
|
145
|
+
} );
|
|
146
|
+
|
|
147
|
+
splitButtonView.bind( 'label' ).toMany( buttonViews, 'isOn', ( ...areOn ) => {
|
|
148
|
+
const index = areOn.findIndex( identity );
|
|
149
|
+
|
|
150
|
+
return getDropdownButtonTitle( title, ( index < 0 ) ? defaultButton.label : buttonViews[ index ].label );
|
|
151
|
+
} );
|
|
152
|
+
|
|
153
|
+
splitButtonView.bind( 'isOn' ).toMany( buttonViews, 'isOn', ( ...areOn ) => areOn.some( identity ) );
|
|
154
|
+
|
|
155
|
+
splitButtonView.bind( 'class' )
|
|
156
|
+
.toMany( buttonViews, 'isOn', ( ...areOn ) => areOn.some( identity ) ? 'ck-splitbutton_flatten' : null );
|
|
157
|
+
|
|
158
|
+
splitButtonView.on( 'execute', () => {
|
|
159
|
+
if ( !buttonViews.some( ( { isOn } ) => isOn ) ) {
|
|
160
|
+
defaultButton.fire( 'execute' );
|
|
161
|
+
} else {
|
|
162
|
+
dropdownView.isOpen = !dropdownView.isOpen;
|
|
163
|
+
}
|
|
164
|
+
} );
|
|
165
|
+
|
|
166
|
+
dropdownView.bind( 'isEnabled' )
|
|
167
|
+
.toMany( buttonViews, 'isEnabled', ( ...areEnabled ) => areEnabled.some( identity ) );
|
|
168
|
+
|
|
169
|
+
return dropdownView;
|
|
170
|
+
} );
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Creates a button and stores it in the editor {@link module:ui/componentfactory~ComponentFactory}.
|
|
175
|
+
*
|
|
176
|
+
* @private
|
|
177
|
+
* @param {module:image/imagestyle~ImageStyleOptionDefinition} buttonConfig
|
|
178
|
+
*/
|
|
179
|
+
_createButton( buttonConfig ) {
|
|
180
|
+
const buttonName = buttonConfig.name;
|
|
181
|
+
|
|
182
|
+
this.editor.ui.componentFactory.add( getUIComponentName( buttonName ), locale => {
|
|
183
|
+
const command = this.editor.commands.get( 'imageStyle' );
|
|
83
184
|
const view = new ButtonView( locale );
|
|
84
185
|
|
|
85
186
|
view.set( {
|
|
86
|
-
label:
|
|
87
|
-
icon:
|
|
187
|
+
label: buttonConfig.title,
|
|
188
|
+
icon: buttonConfig.icon,
|
|
88
189
|
tooltip: true,
|
|
89
190
|
isToggleable: true
|
|
90
191
|
} );
|
|
91
192
|
|
|
92
193
|
view.bind( 'isEnabled' ).to( command, 'isEnabled' );
|
|
93
|
-
view.bind( 'isOn' ).to( command, 'value', value => value ===
|
|
94
|
-
|
|
95
|
-
this.listenTo( view, 'execute', () => {
|
|
96
|
-
editor.execute( 'imageStyle', { value: style.name } );
|
|
97
|
-
editor.editing.view.focus();
|
|
98
|
-
} );
|
|
194
|
+
view.bind( 'isOn' ).to( command, 'value', value => value === buttonName );
|
|
195
|
+
view.on( 'execute', this._executeCommand.bind( this, buttonName ) );
|
|
99
196
|
|
|
100
197
|
return view;
|
|
101
198
|
} );
|
|
102
199
|
}
|
|
200
|
+
|
|
201
|
+
_executeCommand( name ) {
|
|
202
|
+
this.editor.execute( 'imageStyle', { value: name } );
|
|
203
|
+
this.editor.editing.view.focus();
|
|
204
|
+
}
|
|
103
205
|
}
|
|
104
206
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
207
|
+
// Returns the translated `title` from the passed styles array.
|
|
208
|
+
//
|
|
209
|
+
// @param {Array.<module:image/imagestyle~ImageStyleOptionDefinition|
|
|
210
|
+
// module:image/imagestyle/imagestyleui~ImageStyleDropdownDefinition>} styles
|
|
211
|
+
// @param {Object.<String,String>} titles
|
|
212
|
+
//
|
|
213
|
+
// @returns {Array.<module:image/imagestyle~ImageStyleOptionDefinition|module:image/imagestyle/imagestyleui~ImageStyleDropdownDefinition>}
|
|
112
214
|
function translateStyles( styles, titles ) {
|
|
113
215
|
for ( const style of styles ) {
|
|
114
216
|
// Localize the titles of the styles, if a title corresponds with
|
|
@@ -120,3 +222,67 @@ function translateStyles( styles, titles ) {
|
|
|
120
222
|
|
|
121
223
|
return styles;
|
|
122
224
|
}
|
|
225
|
+
|
|
226
|
+
// Returns the image style component name with the "imageStyle:" prefix.
|
|
227
|
+
//
|
|
228
|
+
// @param {String} name
|
|
229
|
+
// @returns {String}
|
|
230
|
+
function getUIComponentName( name ) {
|
|
231
|
+
return `imageStyle:${ name }`;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// Returns title for the splitbutton containing the dropdown title and default action item title.
|
|
235
|
+
//
|
|
236
|
+
// @param {String|undefined} dropdownTitle
|
|
237
|
+
// @param {String} buttonTitle
|
|
238
|
+
// @returns {String}
|
|
239
|
+
function getDropdownButtonTitle( dropdownTitle, buttonTitle ) {
|
|
240
|
+
return ( dropdownTitle ? dropdownTitle + ': ' : '' ) + buttonTitle;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* # **The image style custom drop-down definition descriptor**
|
|
245
|
+
*
|
|
246
|
+
* This definition can be implemented in the {@link module:image/image~ImageConfig#toolbar image toolbar configuration}
|
|
247
|
+
* to define a completely custom drop-down in the image toolbar.
|
|
248
|
+
*
|
|
249
|
+
* ClassicEditor.create( editorElement, {
|
|
250
|
+
* image: { toolbar: [
|
|
251
|
+
* // One of the predefined drop-downs
|
|
252
|
+
* 'imageStyle:wrapText',
|
|
253
|
+
* // Custom drop-down
|
|
254
|
+
* {
|
|
255
|
+
* name: 'imageStyle:customDropdown',
|
|
256
|
+
* title: Custom drop-down title,
|
|
257
|
+
* items: [ 'imageStyle:alignLeft', 'imageStyle:alignRight' ],
|
|
258
|
+
* defaultItem: 'imageStyle:alignLeft'
|
|
259
|
+
* }
|
|
260
|
+
* ] }
|
|
261
|
+
* } );
|
|
262
|
+
*
|
|
263
|
+
* **Note:** At the moment it is possible to populate the custom drop-down with only the buttons registered by the `ImageStyle` plugin.
|
|
264
|
+
*
|
|
265
|
+
* The defined drop-down will be registered
|
|
266
|
+
* as the {@link module:ui/dropdown/dropdownview~DropdownView}
|
|
267
|
+
* with the {@link module:ui/dropdown/button/splitbuttonview~SplitButtonView} under the provided name in the
|
|
268
|
+
* {@link module:ui/componentfactory~ComponentFactory}
|
|
269
|
+
*
|
|
270
|
+
* @property {String} name The unique name of the drop-down. It is recommended to precede it with the "imageStyle:" prefix
|
|
271
|
+
* to avoid collision with the components' names registered by other plugins.
|
|
272
|
+
*
|
|
273
|
+
* @property {String} [title] The drop-down's title. It will be used as the split button label along with the title of the default item
|
|
274
|
+
* in the following manner: "Custom drop-down title: Default item title".
|
|
275
|
+
*
|
|
276
|
+
* Setting `title` to one of
|
|
277
|
+
* {@link module:image/imagestyle/imagestyleui~ImageStyleUI#localizedDefaultStylesTitles}
|
|
278
|
+
* will automatically translate it to the language of the editor.
|
|
279
|
+
*
|
|
280
|
+
* @property {Array.<String>} items The list of the names of the buttons that will be placed in the drop-down's toolbar.
|
|
281
|
+
* Each of the buttons has to be one of the {@link module:image/image~ImageConfig#styles default image style buttons}
|
|
282
|
+
* or to be defined as the {@link module:image/imagestyle~ImageStyleOptionDefinition image styling option}.
|
|
283
|
+
*
|
|
284
|
+
* @property {String} defaultItem The name of one of the buttons from the items list,
|
|
285
|
+
* which will be used as a default button for the drop-down's split button.
|
|
286
|
+
*
|
|
287
|
+
* @typedef {Object} module:image/imagestyle/imagestyleui~ImageStyleDropdownDefinition
|
|
288
|
+
*/
|