@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
|
@@ -12,8 +12,8 @@ import { first } from 'ckeditor5/src/utils';
|
|
|
12
12
|
/**
|
|
13
13
|
* Returns a converter for the `imageStyle` attribute. It can be used for adding, changing and removing the attribute.
|
|
14
14
|
*
|
|
15
|
-
* @param {
|
|
16
|
-
*
|
|
15
|
+
* @param {Array.<module:image/imagestyle~ImageStyleOptionDefinition>} styles
|
|
16
|
+
* An array containing available image style options.
|
|
17
17
|
* @returns {Function} A model-to-view attribute converter.
|
|
18
18
|
*/
|
|
19
19
|
export function modelToViewStyleAttribute( styles ) {
|
|
@@ -23,8 +23,8 @@ export function modelToViewStyleAttribute( styles ) {
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
// Check if there is class name associated with given value.
|
|
26
|
-
const newStyle =
|
|
27
|
-
const oldStyle =
|
|
26
|
+
const newStyle = getStyleDefinitionByName( data.attributeNewValue, styles );
|
|
27
|
+
const oldStyle = getStyleDefinitionByName( data.attributeOldValue, styles );
|
|
28
28
|
|
|
29
29
|
const viewElement = conversionApi.mapper.toViewElement( data.item );
|
|
30
30
|
const viewWriter = conversionApi.writer;
|
|
@@ -42,31 +42,40 @@ export function modelToViewStyleAttribute( styles ) {
|
|
|
42
42
|
/**
|
|
43
43
|
* Returns a view-to-model converter converting image CSS classes to a proper value in the model.
|
|
44
44
|
*
|
|
45
|
-
* @param {Array.<module:image/imagestyle
|
|
45
|
+
* @param {Array.<module:image/imagestyle~ImageStyleOptionDefinition>} styles
|
|
46
|
+
* Image style options for which the converter is created.
|
|
46
47
|
* @returns {Function} A view-to-model converter.
|
|
47
48
|
*/
|
|
48
49
|
export function viewToModelStyleAttribute( styles ) {
|
|
49
50
|
// Convert only non–default styles.
|
|
50
|
-
const
|
|
51
|
+
const nonDefaultStyles = {
|
|
52
|
+
imageInline: styles.filter( style => !style.isDefault && style.modelElements.includes( 'imageInline' ) ),
|
|
53
|
+
imageBlock: styles.filter( style => !style.isDefault && style.modelElements.includes( 'imageBlock' ) )
|
|
54
|
+
};
|
|
51
55
|
|
|
52
56
|
return ( evt, data, conversionApi ) => {
|
|
53
57
|
if ( !data.modelRange ) {
|
|
54
58
|
return;
|
|
55
59
|
}
|
|
56
60
|
|
|
57
|
-
const
|
|
61
|
+
const viewElement = data.viewItem;
|
|
58
62
|
const modelImageElement = first( data.modelRange.getItems() );
|
|
59
63
|
|
|
60
|
-
//
|
|
61
|
-
//
|
|
62
|
-
if (
|
|
64
|
+
// Run this converter only if an image has been found in the model.
|
|
65
|
+
// In some cases it may not be found (for example if we run this on a figure with different type than image).
|
|
66
|
+
if ( !modelImageElement ) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// ...and the `imageStyle` attribute is allowed for that element, otherwise stop conversion early.
|
|
71
|
+
if ( !conversionApi.schema.checkAttribute( modelImageElement, 'imageStyle' ) ) {
|
|
63
72
|
return;
|
|
64
73
|
}
|
|
65
74
|
|
|
66
|
-
// Convert
|
|
67
|
-
for ( const style of
|
|
68
|
-
// Try to consume class corresponding with style.
|
|
69
|
-
if ( conversionApi.consumable.consume(
|
|
75
|
+
// Convert styles one by one.
|
|
76
|
+
for ( const style of nonDefaultStyles[ modelImageElement.name ] ) {
|
|
77
|
+
// Try to consume class corresponding with the style.
|
|
78
|
+
if ( conversionApi.consumable.consume( viewElement, { classes: style.className } ) ) {
|
|
70
79
|
// And convert this style to model attribute.
|
|
71
80
|
conversionApi.writer.setAttribute( 'imageStyle', style.name, modelImageElement );
|
|
72
81
|
}
|
|
@@ -77,9 +86,9 @@ export function viewToModelStyleAttribute( styles ) {
|
|
|
77
86
|
// Returns the style with a given `name` from an array of styles.
|
|
78
87
|
//
|
|
79
88
|
// @param {String} name
|
|
80
|
-
// @param {Array.<module:image/imagestyle
|
|
81
|
-
// @returns {module:image/imagestyle
|
|
82
|
-
function
|
|
89
|
+
// @param {Array.<module:image/imagestyle~ImageStyleOptionDefinition> } styles
|
|
90
|
+
// @returns {module:image/imagestyle~ImageStyleOptionDefinition|undefined}
|
|
91
|
+
function getStyleDefinitionByName( name, styles ) {
|
|
83
92
|
for ( const style of styles ) {
|
|
84
93
|
if ( style.name === name ) {
|
|
85
94
|
return style;
|
|
@@ -8,90 +8,130 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { Command } from 'ckeditor5/src/core';
|
|
11
|
-
import { isImage } from '../image/utils';
|
|
12
11
|
|
|
13
12
|
/**
|
|
14
|
-
* The image style command. It is used to apply
|
|
13
|
+
* The image style command. It is used to apply {@link module:image/imagestyle~ImageStyleConfig#options image style option}
|
|
14
|
+
* to a selected image.
|
|
15
|
+
*
|
|
16
|
+
* **Note**: Executing this command may change the image model element if the desired style requires an image of a different
|
|
17
|
+
* type. See {@link module:image/imagestyle/imagestylecommand~ImageStyleCommand#execute} to learn more.
|
|
15
18
|
*
|
|
16
19
|
* @extends module:core/command~Command
|
|
17
20
|
*/
|
|
18
21
|
export default class ImageStyleCommand extends Command {
|
|
19
22
|
/**
|
|
20
|
-
* Creates an instance of the image style command.
|
|
23
|
+
* Creates an instance of the image style command. When executed, the command applies one of
|
|
24
|
+
* {@link module:image/imagestyle~ImageStyleConfig#options style options} to the currently selected image.
|
|
21
25
|
*
|
|
22
26
|
* @param {module:core/editor/editor~Editor} editor The editor instance.
|
|
23
|
-
* @param {Array.<module:image/imagestyle
|
|
27
|
+
* @param {Array.<module:image/imagestyle~ImageStyleOptionDefinition>} styles
|
|
28
|
+
* The style options that this command supports.
|
|
24
29
|
*/
|
|
25
30
|
constructor( editor, styles ) {
|
|
26
31
|
super( editor );
|
|
27
32
|
|
|
28
33
|
/**
|
|
29
|
-
*
|
|
34
|
+
* An object containing names of default style options for the inline and block images.
|
|
35
|
+
* If there is no default style option for the given image type in the configuration,
|
|
36
|
+
* the name will be `false`.
|
|
30
37
|
*
|
|
31
|
-
* @
|
|
32
|
-
* @type {
|
|
38
|
+
* @private
|
|
39
|
+
* @type {Object.<String,module:image/imagestyle~ImageStyleOptionDefinition#name>}
|
|
33
40
|
*/
|
|
34
|
-
this.
|
|
41
|
+
this._defaultStyles = {
|
|
42
|
+
imageBlock: false,
|
|
43
|
+
imageInline: false
|
|
44
|
+
};
|
|
35
45
|
|
|
36
46
|
/**
|
|
37
|
-
*
|
|
47
|
+
* The styles handled by this command.
|
|
38
48
|
*
|
|
39
|
-
* @
|
|
40
|
-
* @
|
|
49
|
+
* @private
|
|
50
|
+
* @type {module:image/imagestyle~ImageStyleConfig#options}
|
|
41
51
|
*/
|
|
42
|
-
this.
|
|
43
|
-
styles[ style.name ] = style;
|
|
44
|
-
|
|
52
|
+
this._styles = new Map( styles.map( style => {
|
|
45
53
|
if ( style.isDefault ) {
|
|
46
|
-
|
|
54
|
+
for ( const modelElementName of style.modelElements ) {
|
|
55
|
+
this._defaultStyles[ modelElementName ] = style.name;
|
|
56
|
+
}
|
|
47
57
|
}
|
|
48
58
|
|
|
49
|
-
return
|
|
50
|
-
}
|
|
59
|
+
return [ style.name, style ];
|
|
60
|
+
} ) );
|
|
51
61
|
}
|
|
52
62
|
|
|
53
63
|
/**
|
|
54
64
|
* @inheritDoc
|
|
55
65
|
*/
|
|
56
66
|
refresh() {
|
|
57
|
-
const
|
|
67
|
+
const editor = this.editor;
|
|
68
|
+
const imageUtils = editor.plugins.get( 'ImageUtils' );
|
|
69
|
+
const element = imageUtils.getClosestSelectedImageElement( this.editor.model.document.selection );
|
|
58
70
|
|
|
59
|
-
this.isEnabled =
|
|
71
|
+
this.isEnabled = !!element;
|
|
60
72
|
|
|
61
|
-
if ( !
|
|
73
|
+
if ( !this.isEnabled ) {
|
|
62
74
|
this.value = false;
|
|
63
75
|
} else if ( element.hasAttribute( 'imageStyle' ) ) {
|
|
64
|
-
|
|
65
|
-
this.value = this.styles[ attributeValue ] ? attributeValue : false;
|
|
76
|
+
this.value = element.getAttribute( 'imageStyle' );
|
|
66
77
|
} else {
|
|
67
|
-
this.value = this.
|
|
78
|
+
this.value = this._defaultStyles[ element.name ];
|
|
68
79
|
}
|
|
69
80
|
}
|
|
70
81
|
|
|
71
82
|
/**
|
|
72
|
-
* Executes the command
|
|
83
|
+
* Executes the command and applies the style to the currently selected image:
|
|
73
84
|
*
|
|
74
85
|
* editor.execute( 'imageStyle', { value: 'side' } );
|
|
75
86
|
*
|
|
87
|
+
* **Note**: Executing this command may change the image model element if the desired style requires an image
|
|
88
|
+
* of a different type. Learn more about {@link module:image/imagestyle~ImageStyleOptionDefinition#modelElements model element}
|
|
89
|
+
* configuration for the style option.
|
|
90
|
+
*
|
|
76
91
|
* @param {Object} options
|
|
77
|
-
* @param {
|
|
78
|
-
* {@link module:image/
|
|
92
|
+
* @param {module:image/imagestyle~ImageStyleOptionDefinition#name} options.value The name of the style (as configured in
|
|
93
|
+
* {@link module:image/imagestyle~ImageStyleConfig#options}).
|
|
79
94
|
* @fires execute
|
|
80
95
|
*/
|
|
81
|
-
execute( options ) {
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
const
|
|
85
|
-
const imageElement = model.document.selection.getSelectedElement();
|
|
96
|
+
execute( options = {} ) {
|
|
97
|
+
const editor = this.editor;
|
|
98
|
+
const model = editor.model;
|
|
99
|
+
const imageUtils = editor.plugins.get( 'ImageUtils' );
|
|
86
100
|
|
|
87
101
|
model.change( writer => {
|
|
102
|
+
const requestedStyle = options.value;
|
|
103
|
+
|
|
104
|
+
let imageElement = imageUtils.getClosestSelectedImageElement( model.document.selection );
|
|
105
|
+
|
|
106
|
+
// Change the image type if a style requires it.
|
|
107
|
+
if ( requestedStyle && this.shouldConvertImageType( requestedStyle, imageElement ) ) {
|
|
108
|
+
this.editor.execute( imageUtils.isBlockImage( imageElement ) ? 'imageTypeInline' : 'imageTypeBlock' );
|
|
109
|
+
|
|
110
|
+
// Update the imageElement to the newly created image.
|
|
111
|
+
imageElement = imageUtils.getClosestSelectedImageElement( model.document.selection );
|
|
112
|
+
}
|
|
113
|
+
|
|
88
114
|
// Default style means that there is no `imageStyle` attribute in the model.
|
|
89
115
|
// https://github.com/ckeditor/ckeditor5-image/issues/147
|
|
90
|
-
if ( this.
|
|
116
|
+
if ( !requestedStyle || this._styles.get( requestedStyle ).isDefault ) {
|
|
91
117
|
writer.removeAttribute( 'imageStyle', imageElement );
|
|
92
118
|
} else {
|
|
93
|
-
writer.setAttribute( 'imageStyle',
|
|
119
|
+
writer.setAttribute( 'imageStyle', requestedStyle, imageElement );
|
|
94
120
|
}
|
|
95
121
|
} );
|
|
96
122
|
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Returns `true` if requested style change would trigger the image type change.
|
|
126
|
+
*
|
|
127
|
+
* @param {module:image/imagestyle~ImageStyleOptionDefinition} requestedStyle The name of the style (as configured in
|
|
128
|
+
* {@link module:image/imagestyle~ImageStyleConfig#options}).
|
|
129
|
+
* @param {module:engine/model/element~Element} imageElement The image model element.
|
|
130
|
+
* @returns {Boolean}
|
|
131
|
+
*/
|
|
132
|
+
shouldConvertImageType( requestedStyle, imageElement ) {
|
|
133
|
+
const supportedTypes = this._styles.get( requestedStyle ).modelElements;
|
|
134
|
+
|
|
135
|
+
return !supportedTypes.includes( imageElement.name );
|
|
136
|
+
}
|
|
97
137
|
}
|
|
@@ -9,8 +9,9 @@
|
|
|
9
9
|
|
|
10
10
|
import { Plugin } from 'ckeditor5/src/core';
|
|
11
11
|
import ImageStyleCommand from './imagestylecommand';
|
|
12
|
+
import ImageUtils from '../imageutils';
|
|
13
|
+
import utils from './utils';
|
|
12
14
|
import { viewToModelStyleAttribute, modelToViewStyleAttribute } from './converters';
|
|
13
|
-
import { normalizeImageStyles } from './utils';
|
|
14
15
|
|
|
15
16
|
/**
|
|
16
17
|
* The image style engine plugin. It sets the default configuration, creates converters and registers
|
|
@@ -26,69 +27,129 @@ export default class ImageStyleEditing extends Plugin {
|
|
|
26
27
|
return 'ImageStyleEditing';
|
|
27
28
|
}
|
|
28
29
|
|
|
30
|
+
/**
|
|
31
|
+
* @inheritDoc
|
|
32
|
+
*/
|
|
33
|
+
static get requires() {
|
|
34
|
+
return [ ImageUtils ];
|
|
35
|
+
}
|
|
36
|
+
|
|
29
37
|
/**
|
|
30
38
|
* @inheritDoc
|
|
31
39
|
*/
|
|
32
40
|
init() {
|
|
41
|
+
const { normalizeStyles, getDefaultStylesConfiguration } = utils;
|
|
42
|
+
const editor = this.editor;
|
|
43
|
+
const isBlockPluginLoaded = editor.plugins.has( 'ImageBlockEditing' );
|
|
44
|
+
const isInlinePluginLoaded = editor.plugins.has( 'ImageInlineEditing' );
|
|
45
|
+
|
|
46
|
+
editor.config.define( 'image.styles', getDefaultStylesConfiguration( isBlockPluginLoaded, isInlinePluginLoaded ) );
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* It contains a list of the normalized and validated style options.
|
|
50
|
+
*
|
|
51
|
+
* * Each option contains a complete icon markup.
|
|
52
|
+
* * The style options not supported by any of the loaded image editing plugins (
|
|
53
|
+
* {@link module:image/image/imageinlineediting~ImageInlineEditing `ImageInlineEditing`} or
|
|
54
|
+
* {@link module:image/image/imageblockediting~ImageBlockEditing `ImageBlockEditing`}) are filtered out.
|
|
55
|
+
*
|
|
56
|
+
* @protected
|
|
57
|
+
* @readonly
|
|
58
|
+
* @type {module:image/imagestyle~ImageStyleConfig}
|
|
59
|
+
*/
|
|
60
|
+
this.normalizedStyles = normalizeStyles( {
|
|
61
|
+
configuredStyles: editor.config.get( 'image.styles' ),
|
|
62
|
+
isBlockPluginLoaded,
|
|
63
|
+
isInlinePluginLoaded
|
|
64
|
+
} );
|
|
65
|
+
|
|
66
|
+
this._setupConversion( isBlockPluginLoaded, isInlinePluginLoaded );
|
|
67
|
+
this._setupPostFixer();
|
|
68
|
+
|
|
69
|
+
// Register imageStyle command.
|
|
70
|
+
editor.commands.add( 'imageStyle', new ImageStyleCommand( editor, this.normalizedStyles ) );
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Sets the editor conversion taking the presence of
|
|
75
|
+
* {@link module:image/image/imageinlineediting~ImageInlineEditing `ImageInlineEditing`}
|
|
76
|
+
* and {@link module:image/image/imageblockediting~ImageBlockEditing `ImageBlockEditing`} plugins into consideration.
|
|
77
|
+
*
|
|
78
|
+
* @private
|
|
79
|
+
* @param {Boolean} isBlockPluginLoaded
|
|
80
|
+
* @param {Boolean} isInlinePluginLoaded
|
|
81
|
+
*/
|
|
82
|
+
_setupConversion( isBlockPluginLoaded, isInlinePluginLoaded ) {
|
|
33
83
|
const editor = this.editor;
|
|
34
84
|
const schema = editor.model.schema;
|
|
35
|
-
const data = editor.data;
|
|
36
|
-
const editing = editor.editing;
|
|
37
85
|
|
|
38
|
-
|
|
39
|
-
|
|
86
|
+
const modelToViewConverter = modelToViewStyleAttribute( this.normalizedStyles );
|
|
87
|
+
const viewToModelConverter = viewToModelStyleAttribute( this.normalizedStyles );
|
|
40
88
|
|
|
41
|
-
|
|
42
|
-
|
|
89
|
+
editor.editing.downcastDispatcher.on( 'attribute:imageStyle', modelToViewConverter );
|
|
90
|
+
editor.data.downcastDispatcher.on( 'attribute:imageStyle', modelToViewConverter );
|
|
43
91
|
|
|
44
|
-
// Allow imageStyle attribute in image.
|
|
92
|
+
// Allow imageStyle attribute in image and imageInline.
|
|
45
93
|
// We could call it 'style' but https://github.com/ckeditor/ckeditor5-engine/issues/559.
|
|
46
|
-
|
|
94
|
+
if ( isBlockPluginLoaded ) {
|
|
95
|
+
schema.extend( 'imageBlock', { allowAttributes: 'imageStyle' } );
|
|
47
96
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
data.downcastDispatcher.on( 'attribute:imageStyle:image', modelToViewConverter );
|
|
97
|
+
// Converter for figure element from view to model.
|
|
98
|
+
editor.data.upcastDispatcher.on( 'element:figure', viewToModelConverter, { priority: 'low' } );
|
|
99
|
+
}
|
|
52
100
|
|
|
53
|
-
|
|
54
|
-
|
|
101
|
+
if ( isInlinePluginLoaded ) {
|
|
102
|
+
schema.extend( 'imageInline', { allowAttributes: 'imageStyle' } );
|
|
55
103
|
|
|
56
|
-
|
|
57
|
-
|
|
104
|
+
// Converter for the img element from view to model.
|
|
105
|
+
editor.data.upcastDispatcher.on( 'element:img', viewToModelConverter, { priority: 'low' } );
|
|
106
|
+
}
|
|
58
107
|
}
|
|
59
|
-
}
|
|
60
108
|
|
|
61
|
-
/**
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
109
|
+
/**
|
|
110
|
+
* Registers a post-fixer that will make sure that the style attribute value is correct for a specific image type (block vs inline).
|
|
111
|
+
*
|
|
112
|
+
* @private
|
|
113
|
+
*/
|
|
114
|
+
_setupPostFixer() {
|
|
115
|
+
const editor = this.editor;
|
|
116
|
+
const document = editor.model.document;
|
|
117
|
+
|
|
118
|
+
const imageUtils = editor.plugins.get( ImageUtils );
|
|
119
|
+
const stylesMap = new Map( this.normalizedStyles.map( style => [ style.name, style ] ) );
|
|
120
|
+
|
|
121
|
+
// Make sure that style attribute is valid for the image type.
|
|
122
|
+
document.registerPostFixer( writer => {
|
|
123
|
+
let changed = false;
|
|
124
|
+
|
|
125
|
+
for ( const change of document.differ.getChanges() ) {
|
|
126
|
+
if ( change.type == 'insert' || change.type == 'attribute' && change.attributeKey == 'imageStyle' ) {
|
|
127
|
+
let element = change.type == 'insert' ? change.position.nodeAfter : change.range.start.nodeAfter;
|
|
128
|
+
|
|
129
|
+
if ( element && element.is( 'element', 'paragraph' ) && element.childCount > 0 ) {
|
|
130
|
+
element = element.getChild( 0 );
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if ( !imageUtils.isImage( element ) ) {
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const imageStyle = element.getAttribute( 'imageStyle' );
|
|
138
|
+
|
|
139
|
+
if ( !imageStyle ) {
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const imageStyleDefinition = stylesMap.get( imageStyle );
|
|
144
|
+
|
|
145
|
+
if ( !imageStyleDefinition || !imageStyleDefinition.modelElements.includes( element.name ) ) {
|
|
146
|
+
writer.removeAttribute( 'imageStyle', element );
|
|
147
|
+
changed = true;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return changed;
|
|
153
|
+
} );
|
|
154
|
+
}
|
|
155
|
+
}
|