@ckeditor/ckeditor5-image 47.6.1-alpha.1 → 48.0.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +1 -1
- package/ckeditor5-metadata.json +25 -25
- package/{src → dist}/autoimage.d.ts +4 -4
- package/{src → dist}/image/converters.d.ts +1 -1
- package/{src → dist}/image/imageblockediting.d.ts +2 -2
- package/{src → dist}/image/imageediting.d.ts +1 -1
- package/{src → dist}/image/imageinlineediting.d.ts +2 -2
- package/{src → dist}/image/imageloadobserver.d.ts +1 -1
- package/{src → dist}/image/imageplaceholder.d.ts +1 -1
- package/{src → dist}/image/imagetypecommand.d.ts +2 -2
- package/{src → dist}/image/insertimagecommand.d.ts +2 -2
- package/{src → dist}/image/replaceimagesourcecommand.d.ts +2 -2
- package/{src → dist}/image/ui/utils.d.ts +2 -2
- package/{src → dist}/image/utils.d.ts +2 -2
- package/{src → dist}/image.d.ts +1 -1
- package/{src → dist}/imageblock.d.ts +2 -2
- package/{src → dist}/imagecaption/imagecaptionediting.d.ts +2 -2
- package/{src → dist}/imagecaption/imagecaptionui.d.ts +1 -1
- package/{src → dist}/imagecaption/imagecaptionutils.d.ts +2 -2
- package/{src → dist}/imagecaption/toggleimagecaptioncommand.d.ts +1 -1
- package/{src → dist}/imagecaption.d.ts +1 -1
- package/{src → dist}/imageconfig.d.ts +25 -16
- package/{src → dist}/imageinline.d.ts +2 -2
- package/{src → dist}/imageinsert/imageinsertui.d.ts +3 -3
- package/{src → dist}/imageinsert/imageinsertviaurlui.d.ts +2 -2
- package/{src → dist}/imageinsert/ui/imageinsertformview.d.ts +2 -2
- package/{src → dist}/imageinsert/ui/imageinserturlview.d.ts +2 -2
- package/{src → dist}/imageinsert.d.ts +1 -1
- package/{src → dist}/imageinsertviaurl.d.ts +1 -1
- package/{src → dist}/imageresize/imagecustomresizeui.d.ts +2 -2
- package/{src → dist}/imageresize/imageresizebuttons.d.ts +1 -1
- package/{src → dist}/imageresize/imageresizeediting.d.ts +1 -1
- package/{src → dist}/imageresize/imageresizehandles.d.ts +2 -2
- package/{src → dist}/imageresize/resizeimagecommand.d.ts +1 -1
- package/{src → dist}/imageresize/ui/imagecustomresizeformview.d.ts +2 -4
- package/{src → dist}/imageresize/utils/getselectedimageeditornodes.d.ts +2 -2
- package/{src → dist}/imageresize/utils/getselectedimagepossibleresizerange.d.ts +1 -1
- package/{src → dist}/imageresize/utils/getselectedimagewidthinunits.d.ts +1 -1
- package/{src → dist}/imageresize.d.ts +1 -1
- package/{src → dist}/imagesizeattributes.d.ts +1 -1
- package/{src → dist}/imagestyle/converters.d.ts +2 -2
- package/{src → dist}/imagestyle/imagestylecommand.d.ts +2 -2
- package/{src → dist}/imagestyle/imagestyleediting.d.ts +1 -1
- package/{src → dist}/imagestyle/imagestyleui.d.ts +1 -1
- package/{src → dist}/imagestyle/utils.d.ts +1 -1
- package/{src → dist}/imagestyle.d.ts +1 -1
- package/{src → dist}/imagetextalternative/imagetextalternativecommand.d.ts +1 -1
- package/{src → dist}/imagetextalternative/imagetextalternativeediting.d.ts +1 -1
- package/{src → dist}/imagetextalternative/imagetextalternativeui.d.ts +2 -2
- package/{src → dist}/imagetextalternative/ui/textalternativeformview.d.ts +2 -4
- package/{src → dist}/imagetextalternative.d.ts +1 -1
- package/{src → dist}/imagetoolbar.d.ts +2 -2
- package/{src → dist}/imageupload/imageuploadediting.d.ts +5 -5
- package/{src → dist}/imageupload/imageuploadprogress.d.ts +1 -1
- package/{src → dist}/imageupload/imageuploadui.d.ts +1 -1
- package/{src → dist}/imageupload/uploadimagecommand.d.ts +2 -2
- package/{src → dist}/imageupload/utils.d.ts +1 -1
- package/{src → dist}/imageupload.d.ts +1 -1
- package/{src → dist}/imageutils.d.ts +2 -2
- package/dist/index-content.css +97 -100
- package/dist/index-editor.css +313 -190
- package/dist/index.css +388 -458
- package/dist/index.css.map +1 -1
- package/dist/index.js +1 -2
- package/dist/index.js.map +1 -1
- package/{src → dist}/pictureediting.d.ts +1 -1
- package/package.json +29 -53
- package/build/image.js +0 -5
- package/build/translations/af.js +0 -1
- package/build/translations/ar.js +0 -1
- package/build/translations/ast.js +0 -1
- package/build/translations/az.js +0 -1
- package/build/translations/be.js +0 -1
- package/build/translations/bg.js +0 -1
- package/build/translations/bn.js +0 -1
- package/build/translations/bs.js +0 -1
- package/build/translations/ca.js +0 -1
- package/build/translations/cs.js +0 -1
- package/build/translations/da.js +0 -1
- package/build/translations/de-ch.js +0 -1
- package/build/translations/de.js +0 -1
- package/build/translations/el.js +0 -1
- package/build/translations/en-au.js +0 -1
- package/build/translations/en-gb.js +0 -1
- package/build/translations/eo.js +0 -1
- package/build/translations/es-co.js +0 -1
- package/build/translations/es.js +0 -1
- package/build/translations/et.js +0 -1
- package/build/translations/eu.js +0 -1
- package/build/translations/fa.js +0 -1
- package/build/translations/fi.js +0 -1
- package/build/translations/fr.js +0 -1
- package/build/translations/gl.js +0 -1
- package/build/translations/gu.js +0 -1
- package/build/translations/he.js +0 -1
- package/build/translations/hi.js +0 -1
- package/build/translations/hr.js +0 -1
- package/build/translations/hu.js +0 -1
- package/build/translations/hy.js +0 -1
- package/build/translations/id.js +0 -1
- package/build/translations/it.js +0 -1
- package/build/translations/ja.js +0 -1
- package/build/translations/jv.js +0 -1
- package/build/translations/kk.js +0 -1
- package/build/translations/km.js +0 -1
- package/build/translations/kn.js +0 -1
- package/build/translations/ko.js +0 -1
- package/build/translations/ku.js +0 -1
- package/build/translations/lt.js +0 -1
- package/build/translations/lv.js +0 -1
- package/build/translations/ms.js +0 -1
- package/build/translations/nb.js +0 -1
- package/build/translations/ne.js +0 -1
- package/build/translations/nl.js +0 -1
- package/build/translations/no.js +0 -1
- package/build/translations/oc.js +0 -1
- package/build/translations/pl.js +0 -1
- package/build/translations/pt-br.js +0 -1
- package/build/translations/pt.js +0 -1
- package/build/translations/ro.js +0 -1
- package/build/translations/ru.js +0 -1
- package/build/translations/si.js +0 -1
- package/build/translations/sk.js +0 -1
- package/build/translations/sl.js +0 -1
- package/build/translations/sq.js +0 -1
- package/build/translations/sr-latn.js +0 -1
- package/build/translations/sr.js +0 -1
- package/build/translations/sv.js +0 -1
- package/build/translations/th.js +0 -1
- package/build/translations/ti.js +0 -1
- package/build/translations/tk.js +0 -1
- package/build/translations/tr.js +0 -1
- package/build/translations/tt.js +0 -1
- package/build/translations/ug.js +0 -1
- package/build/translations/uk.js +0 -1
- package/build/translations/ur.js +0 -1
- package/build/translations/uz.js +0 -1
- package/build/translations/vi.js +0 -1
- package/build/translations/zh-cn.js +0 -1
- package/build/translations/zh.js +0 -1
- package/lang/contexts.json +0 -48
- package/lang/translations/af.po +0 -196
- package/lang/translations/ar.po +0 -196
- package/lang/translations/ast.po +0 -196
- package/lang/translations/az.po +0 -196
- package/lang/translations/be.po +0 -196
- package/lang/translations/bg.po +0 -196
- package/lang/translations/bn.po +0 -196
- package/lang/translations/bs.po +0 -196
- package/lang/translations/ca.po +0 -196
- package/lang/translations/cs.po +0 -196
- package/lang/translations/da.po +0 -196
- package/lang/translations/de-ch.po +0 -196
- package/lang/translations/de.po +0 -196
- package/lang/translations/el.po +0 -196
- package/lang/translations/en-au.po +0 -196
- package/lang/translations/en-gb.po +0 -196
- package/lang/translations/en.po +0 -196
- package/lang/translations/eo.po +0 -196
- package/lang/translations/es-co.po +0 -196
- package/lang/translations/es.po +0 -196
- package/lang/translations/et.po +0 -196
- package/lang/translations/eu.po +0 -196
- package/lang/translations/fa.po +0 -196
- package/lang/translations/fi.po +0 -196
- package/lang/translations/fr.po +0 -196
- package/lang/translations/gl.po +0 -196
- package/lang/translations/gu.po +0 -196
- package/lang/translations/he.po +0 -196
- package/lang/translations/hi.po +0 -196
- package/lang/translations/hr.po +0 -196
- package/lang/translations/hu.po +0 -196
- package/lang/translations/hy.po +0 -196
- package/lang/translations/id.po +0 -196
- package/lang/translations/it.po +0 -196
- package/lang/translations/ja.po +0 -196
- package/lang/translations/jv.po +0 -196
- package/lang/translations/kk.po +0 -196
- package/lang/translations/km.po +0 -196
- package/lang/translations/kn.po +0 -196
- package/lang/translations/ko.po +0 -196
- package/lang/translations/ku.po +0 -196
- package/lang/translations/lt.po +0 -196
- package/lang/translations/lv.po +0 -196
- package/lang/translations/ms.po +0 -196
- package/lang/translations/nb.po +0 -196
- package/lang/translations/ne.po +0 -196
- package/lang/translations/nl.po +0 -196
- package/lang/translations/no.po +0 -196
- package/lang/translations/oc.po +0 -196
- package/lang/translations/pl.po +0 -196
- package/lang/translations/pt-br.po +0 -196
- package/lang/translations/pt.po +0 -196
- package/lang/translations/ro.po +0 -196
- package/lang/translations/ru.po +0 -196
- package/lang/translations/si.po +0 -196
- package/lang/translations/sk.po +0 -196
- package/lang/translations/sl.po +0 -196
- package/lang/translations/sq.po +0 -196
- package/lang/translations/sr-latn.po +0 -196
- package/lang/translations/sr.po +0 -196
- package/lang/translations/sv.po +0 -196
- package/lang/translations/th.po +0 -196
- package/lang/translations/ti.po +0 -196
- package/lang/translations/tk.po +0 -196
- package/lang/translations/tr.po +0 -196
- package/lang/translations/tt.po +0 -196
- package/lang/translations/ug.po +0 -196
- package/lang/translations/uk.po +0 -196
- package/lang/translations/ur.po +0 -196
- package/lang/translations/uz.po +0 -196
- package/lang/translations/vi.po +0 -196
- package/lang/translations/zh-cn.po +0 -196
- package/lang/translations/zh.po +0 -196
- package/src/augmentation.js +0 -5
- package/src/autoimage.js +0 -148
- package/src/image/converters.js +0 -236
- package/src/image/imageblockediting.js +0 -159
- package/src/image/imageediting.js +0 -69
- package/src/image/imageinlineediting.js +0 -178
- package/src/image/imageloadobserver.js +0 -52
- package/src/image/imageplaceholder.js +0 -119
- package/src/image/imagetypecommand.js +0 -84
- package/src/image/insertimagecommand.js +0 -125
- package/src/image/replaceimagesourcecommand.js +0 -75
- package/src/image/ui/utils.js +0 -46
- package/src/image/utils.js +0 -125
- package/src/image.js +0 -44
- package/src/imageblock.js +0 -44
- package/src/imagecaption/imagecaptionediting.js +0 -238
- package/src/imagecaption/imagecaptionui.js +0 -68
- package/src/imagecaption/imagecaptionutils.js +0 -68
- package/src/imagecaption/toggleimagecaptioncommand.js +0 -138
- package/src/imagecaption.js +0 -36
- package/src/imageconfig.js +0 -5
- package/src/imageinline.js +0 -44
- package/src/imageinsert/imageinsertui.js +0 -216
- package/src/imageinsert/imageinsertviaurlui.js +0 -175
- package/src/imageinsert/ui/imageinsertformview.js +0 -117
- package/src/imageinsert/ui/imageinserturlview.js +0 -102
- package/src/imageinsert.js +0 -43
- package/src/imageinsertviaurl.js +0 -41
- package/src/imageresize/imagecustomresizeui.js +0 -177
- package/src/imageresize/imageresizebuttons.js +0 -303
- package/src/imageresize/imageresizeediting.js +0 -206
- package/src/imageresize/imageresizehandles.js +0 -118
- package/src/imageresize/resizeimagecommand.js +0 -63
- package/src/imageresize/ui/imagecustomresizeformview.js +0 -264
- package/src/imageresize/utils/getselectedimageeditornodes.js +0 -25
- package/src/imageresize/utils/getselectedimagepossibleresizerange.js +0 -33
- package/src/imageresize/utils/getselectedimagewidthinunits.js +0 -42
- package/src/imageresize/utils/tryparsedimensionwithunit.js +0 -58
- package/src/imageresize.js +0 -38
- package/src/imagesizeattributes.js +0 -163
- package/src/imagestyle/converters.js +0 -118
- package/src/imagestyle/imagestylecommand.js +0 -117
- package/src/imagestyle/imagestyleediting.js +0 -127
- package/src/imagestyle/imagestyleui.js +0 -198
- package/src/imagestyle/utils.js +0 -333
- package/src/imagestyle.js +0 -42
- package/src/imagetextalternative/imagetextalternativecommand.js +0 -44
- package/src/imagetextalternative/imagetextalternativeediting.js +0 -41
- package/src/imagetextalternative/imagetextalternativeui.js +0 -183
- package/src/imagetextalternative/ui/textalternativeformview.js +0 -193
- package/src/imagetextalternative.js +0 -39
- package/src/imagetoolbar.js +0 -63
- package/src/imageupload/imageuploadediting.js +0 -482
- package/src/imageupload/imageuploadprogress.js +0 -222
- package/src/imageupload/imageuploadui.js +0 -135
- package/src/imageupload/uploadimagecommand.js +0 -110
- package/src/imageupload/utils.js +0 -114
- package/src/imageupload.js +0 -42
- package/src/imageutils.js +0 -309
- package/src/index.js +0 -67
- package/src/pictureediting.js +0 -136
- package/theme/image.css +0 -143
- package/theme/imagecaption.css +0 -53
- package/theme/imagecustomresizeform.css +0 -4
- package/theme/imageinsert.css +0 -14
- package/theme/imageplaceholder.css +0 -10
- package/theme/imageresize.css +0 -53
- package/theme/imagestyle.css +0 -120
- package/theme/imageuploadicon.css +0 -23
- package/theme/imageuploadloader.css +0 -18
- package/theme/imageuploadprogress.css +0 -19
- package/theme/textalternativeform.css +0 -4
- /package/{src → dist}/augmentation.d.ts +0 -0
- /package/{src → dist}/imageresize/utils/tryparsedimensionwithunit.d.ts +0 -0
- /package/{src → dist}/index.d.ts +0 -0
|
@@ -1,159 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
-
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* @module image/image/imageblockediting
|
|
7
|
-
*/
|
|
8
|
-
import { Plugin } from 'ckeditor5/src/core.js';
|
|
9
|
-
import { ClipboardPipeline } from 'ckeditor5/src/clipboard.js';
|
|
10
|
-
import { ViewUpcastWriter } from 'ckeditor5/src/engine.js';
|
|
11
|
-
import { downcastImageAttribute, downcastSrcsetAttribute, upcastImageFigure } from './converters.js';
|
|
12
|
-
import { ImageEditing } from './imageediting.js';
|
|
13
|
-
import { ImageSizeAttributes } from '../imagesizeattributes.js';
|
|
14
|
-
import { ImageTypeCommand } from './imagetypecommand.js';
|
|
15
|
-
import { ImageUtils } from '../imageutils.js';
|
|
16
|
-
import { getImgViewElementMatcher, createBlockImageViewElement, determineImageTypeForInsertionAtSelection } from './utils.js';
|
|
17
|
-
import { ImagePlaceholder } from './imageplaceholder.js';
|
|
18
|
-
/**
|
|
19
|
-
* The image block plugin.
|
|
20
|
-
*
|
|
21
|
-
* It registers:
|
|
22
|
-
*
|
|
23
|
-
* * `<imageBlock>` as a block element in the document schema, and allows `alt`, `src` and `srcset` attributes.
|
|
24
|
-
* * converters for editing and data pipelines.,
|
|
25
|
-
* * {@link module:image/image/imagetypecommand~ImageTypeCommand `'imageTypeBlock'`} command that converts inline images into
|
|
26
|
-
* block images.
|
|
27
|
-
*/
|
|
28
|
-
export class ImageBlockEditing extends Plugin {
|
|
29
|
-
/**
|
|
30
|
-
* @inheritDoc
|
|
31
|
-
*/
|
|
32
|
-
static get requires() {
|
|
33
|
-
return [ImageEditing, ImageSizeAttributes, ImageUtils, ImagePlaceholder, ClipboardPipeline];
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* @inheritDoc
|
|
37
|
-
*/
|
|
38
|
-
static get pluginName() {
|
|
39
|
-
return 'ImageBlockEditing';
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* @inheritDoc
|
|
43
|
-
*/
|
|
44
|
-
static get isOfficialPlugin() {
|
|
45
|
-
return true;
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* @inheritDoc
|
|
49
|
-
*/
|
|
50
|
-
init() {
|
|
51
|
-
const editor = this.editor;
|
|
52
|
-
const schema = editor.model.schema;
|
|
53
|
-
// Converters 'alt' and 'srcset' are added in 'ImageEditing' plugin.
|
|
54
|
-
schema.register('imageBlock', {
|
|
55
|
-
inheritAllFrom: '$blockObject',
|
|
56
|
-
allowAttributes: ['alt', 'src', 'srcset']
|
|
57
|
-
});
|
|
58
|
-
this._setupConversion();
|
|
59
|
-
if (editor.plugins.has('ImageInlineEditing')) {
|
|
60
|
-
editor.commands.add('imageTypeBlock', new ImageTypeCommand(this.editor, 'imageBlock'));
|
|
61
|
-
this._setupClipboardIntegration();
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* Configures conversion pipelines to support upcasting and downcasting
|
|
66
|
-
* block images (block image widgets) and their attributes.
|
|
67
|
-
*/
|
|
68
|
-
_setupConversion() {
|
|
69
|
-
const editor = this.editor;
|
|
70
|
-
const t = editor.t;
|
|
71
|
-
const conversion = editor.conversion;
|
|
72
|
-
const imageUtils = editor.plugins.get('ImageUtils');
|
|
73
|
-
conversion.for('dataDowncast')
|
|
74
|
-
.elementToStructure({
|
|
75
|
-
model: 'imageBlock',
|
|
76
|
-
view: (modelElement, { writer }) => createBlockImageViewElement(writer)
|
|
77
|
-
});
|
|
78
|
-
conversion.for('editingDowncast')
|
|
79
|
-
.elementToStructure({
|
|
80
|
-
model: 'imageBlock',
|
|
81
|
-
view: (modelElement, { writer }) => imageUtils.toImageWidget(createBlockImageViewElement(writer), writer, t('image widget'))
|
|
82
|
-
});
|
|
83
|
-
conversion.for('downcast')
|
|
84
|
-
.add(downcastImageAttribute(imageUtils, 'imageBlock', 'src'))
|
|
85
|
-
.add(downcastImageAttribute(imageUtils, 'imageBlock', 'alt'))
|
|
86
|
-
.add(downcastSrcsetAttribute(imageUtils, 'imageBlock'));
|
|
87
|
-
// More image related upcasts are in 'ImageEditing' plugin.
|
|
88
|
-
conversion.for('upcast')
|
|
89
|
-
.elementToElement({
|
|
90
|
-
view: getImgViewElementMatcher(editor, 'imageBlock'),
|
|
91
|
-
model: (viewImage, { writer }) => writer.createElement('imageBlock', viewImage.hasAttribute('src') ? { src: viewImage.getAttribute('src') } : undefined)
|
|
92
|
-
})
|
|
93
|
-
.add(upcastImageFigure(imageUtils));
|
|
94
|
-
}
|
|
95
|
-
/**
|
|
96
|
-
* Integrates the plugin with the clipboard pipeline.
|
|
97
|
-
*
|
|
98
|
-
* Idea is that the feature should recognize the user's intent when an **inline** image is
|
|
99
|
-
* pasted or dropped. If such an image is pasted/dropped:
|
|
100
|
-
*
|
|
101
|
-
* * into an empty block (e.g. an empty paragraph),
|
|
102
|
-
* * on another object (e.g. some block widget).
|
|
103
|
-
*
|
|
104
|
-
* it gets converted into a block image on the fly. We assume this is the user's intent
|
|
105
|
-
* if they decided to put their image there.
|
|
106
|
-
*
|
|
107
|
-
* See the `ImageInlineEditing` for the similar integration that works in the opposite direction.
|
|
108
|
-
*
|
|
109
|
-
* The feature also sets image `width` and `height` attributes on paste.
|
|
110
|
-
*/
|
|
111
|
-
_setupClipboardIntegration() {
|
|
112
|
-
const editor = this.editor;
|
|
113
|
-
const model = editor.model;
|
|
114
|
-
const editingView = editor.editing.view;
|
|
115
|
-
const imageUtils = editor.plugins.get('ImageUtils');
|
|
116
|
-
const clipboardPipeline = editor.plugins.get('ClipboardPipeline');
|
|
117
|
-
this.listenTo(clipboardPipeline, 'inputTransformation', (evt, data) => {
|
|
118
|
-
const docFragmentChildren = Array.from(data.content.getChildren());
|
|
119
|
-
let modelRange;
|
|
120
|
-
// Make sure only <img> elements are dropped or pasted. Otherwise, if there some other HTML
|
|
121
|
-
// mixed up, this should be handled as a regular paste.
|
|
122
|
-
if (!docFragmentChildren.every(imageUtils.isInlineImageView)) {
|
|
123
|
-
return;
|
|
124
|
-
}
|
|
125
|
-
// When drag and dropping, data.targetRanges specifies where to drop because
|
|
126
|
-
// this is usually a different place than the current model selection (the user
|
|
127
|
-
// uses a drop marker to specify the drop location).
|
|
128
|
-
if (data.targetRanges) {
|
|
129
|
-
modelRange = editor.editing.mapper.toModelRange(data.targetRanges[0]);
|
|
130
|
-
}
|
|
131
|
-
// Pasting, however, always occurs at the current model selection.
|
|
132
|
-
else {
|
|
133
|
-
modelRange = model.document.selection.getFirstRange();
|
|
134
|
-
}
|
|
135
|
-
const selection = model.createSelection(modelRange);
|
|
136
|
-
// Convert inline images into block images only when the currently selected block is empty
|
|
137
|
-
// (e.g. an empty paragraph) or some object is selected (to replace it).
|
|
138
|
-
if (determineImageTypeForInsertionAtSelection(model.schema, selection) === 'imageBlock') {
|
|
139
|
-
const writer = new ViewUpcastWriter(editingView.document);
|
|
140
|
-
// Wrap <img ... /> -> <figure class="image"><img .../></figure>
|
|
141
|
-
const blockViewImages = docFragmentChildren.map(inlineViewImage => writer.createElement('figure', { class: 'image' }, inlineViewImage));
|
|
142
|
-
data.content = writer.createDocumentFragment(blockViewImages);
|
|
143
|
-
}
|
|
144
|
-
});
|
|
145
|
-
this.listenTo(clipboardPipeline, 'contentInsertion', (evt, data) => {
|
|
146
|
-
if (data.method !== 'paste') {
|
|
147
|
-
return;
|
|
148
|
-
}
|
|
149
|
-
model.change(writer => {
|
|
150
|
-
const range = writer.createRangeIn(data.content);
|
|
151
|
-
for (const item of range.getItems()) {
|
|
152
|
-
if (item.is('element', 'imageBlock')) {
|
|
153
|
-
imageUtils.setImageNaturalSizeAttributes(item);
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
});
|
|
157
|
-
});
|
|
158
|
-
}
|
|
159
|
-
}
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
-
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* @module image/image/imageediting
|
|
7
|
-
*/
|
|
8
|
-
import { Plugin } from 'ckeditor5/src/core.js';
|
|
9
|
-
import { ImageLoadObserver } from './imageloadobserver.js';
|
|
10
|
-
import { InsertImageCommand } from './insertimagecommand.js';
|
|
11
|
-
import { ReplaceImageSourceCommand } from './replaceimagesourcecommand.js';
|
|
12
|
-
import { ImageUtils } from '../imageutils.js';
|
|
13
|
-
/**
|
|
14
|
-
* The image engine plugin. This module loads common code shared between
|
|
15
|
-
* {@link module:image/image/imageinlineediting~ImageInlineEditing} and
|
|
16
|
-
* {@link module:image/image/imageblockediting~ImageBlockEditing} plugins.
|
|
17
|
-
*
|
|
18
|
-
* This plugin registers the {@link module:image/image/insertimagecommand~InsertImageCommand 'insertImage'} command.
|
|
19
|
-
*/
|
|
20
|
-
export class ImageEditing extends Plugin {
|
|
21
|
-
/**
|
|
22
|
-
* @inheritDoc
|
|
23
|
-
*/
|
|
24
|
-
static get requires() {
|
|
25
|
-
return [ImageUtils];
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* @inheritDoc
|
|
29
|
-
*/
|
|
30
|
-
static get pluginName() {
|
|
31
|
-
return 'ImageEditing';
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* @inheritDoc
|
|
35
|
-
*/
|
|
36
|
-
static get isOfficialPlugin() {
|
|
37
|
-
return true;
|
|
38
|
-
}
|
|
39
|
-
/**
|
|
40
|
-
* @inheritDoc
|
|
41
|
-
*/
|
|
42
|
-
init() {
|
|
43
|
-
const editor = this.editor;
|
|
44
|
-
const conversion = editor.conversion;
|
|
45
|
-
// See https://github.com/ckeditor/ckeditor5-image/issues/142.
|
|
46
|
-
editor.editing.view.addObserver(ImageLoadObserver);
|
|
47
|
-
conversion.for('upcast')
|
|
48
|
-
.attributeToAttribute({
|
|
49
|
-
view: {
|
|
50
|
-
name: 'img',
|
|
51
|
-
key: 'alt'
|
|
52
|
-
},
|
|
53
|
-
model: 'alt'
|
|
54
|
-
})
|
|
55
|
-
.attributeToAttribute({
|
|
56
|
-
view: {
|
|
57
|
-
name: 'img',
|
|
58
|
-
key: 'srcset'
|
|
59
|
-
},
|
|
60
|
-
model: 'srcset'
|
|
61
|
-
});
|
|
62
|
-
const insertImageCommand = new InsertImageCommand(editor);
|
|
63
|
-
const replaceImageSourceCommand = new ReplaceImageSourceCommand(editor);
|
|
64
|
-
editor.commands.add('insertImage', insertImageCommand);
|
|
65
|
-
editor.commands.add('replaceImageSource', replaceImageSourceCommand);
|
|
66
|
-
// `imageInsert` is an alias for backward compatibility.
|
|
67
|
-
editor.commands.add('imageInsert', insertImageCommand);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
-
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* @module image/image/imageinlineediting
|
|
7
|
-
*/
|
|
8
|
-
import { Plugin } from 'ckeditor5/src/core.js';
|
|
9
|
-
import { ClipboardPipeline } from 'ckeditor5/src/clipboard.js';
|
|
10
|
-
import { ViewUpcastWriter } from 'ckeditor5/src/engine.js';
|
|
11
|
-
import { downcastImageAttribute, downcastSrcsetAttribute } from './converters.js';
|
|
12
|
-
import { ImageEditing } from './imageediting.js';
|
|
13
|
-
import { ImageSizeAttributes } from '../imagesizeattributes.js';
|
|
14
|
-
import { ImageTypeCommand } from './imagetypecommand.js';
|
|
15
|
-
import { ImageUtils } from '../imageutils.js';
|
|
16
|
-
import { getImgViewElementMatcher, createInlineImageViewElement, determineImageTypeForInsertionAtSelection } from './utils.js';
|
|
17
|
-
import { ImagePlaceholder } from './imageplaceholder.js';
|
|
18
|
-
/**
|
|
19
|
-
* The image inline plugin.
|
|
20
|
-
*
|
|
21
|
-
* It registers:
|
|
22
|
-
*
|
|
23
|
-
* * `<imageInline>` as an inline element in the document schema, and allows `alt`, `src` and `srcset` attributes.
|
|
24
|
-
* * converters for editing and data pipelines.
|
|
25
|
-
* * {@link module:image/image/imagetypecommand~ImageTypeCommand `'imageTypeInline'`} command that converts block images into
|
|
26
|
-
* inline images.
|
|
27
|
-
*/
|
|
28
|
-
export class ImageInlineEditing extends Plugin {
|
|
29
|
-
/**
|
|
30
|
-
* @inheritDoc
|
|
31
|
-
*/
|
|
32
|
-
static get requires() {
|
|
33
|
-
return [ImageEditing, ImageSizeAttributes, ImageUtils, ImagePlaceholder, ClipboardPipeline];
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* @inheritDoc
|
|
37
|
-
*/
|
|
38
|
-
static get pluginName() {
|
|
39
|
-
return 'ImageInlineEditing';
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* @inheritDoc
|
|
43
|
-
*/
|
|
44
|
-
static get isOfficialPlugin() {
|
|
45
|
-
return true;
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* @inheritDoc
|
|
49
|
-
*/
|
|
50
|
-
init() {
|
|
51
|
-
const editor = this.editor;
|
|
52
|
-
const schema = editor.model.schema;
|
|
53
|
-
// Converters 'alt' and 'srcset' are added in 'ImageEditing' plugin.
|
|
54
|
-
schema.register('imageInline', {
|
|
55
|
-
inheritAllFrom: '$inlineObject',
|
|
56
|
-
allowAttributes: ['alt', 'src', 'srcset'],
|
|
57
|
-
// Disallow inline images in captions (at least for now).
|
|
58
|
-
// This is the best spot to do that because independent packages can introduce captions (ImageCaption, TableCaption, etc.).
|
|
59
|
-
disallowIn: ['caption']
|
|
60
|
-
});
|
|
61
|
-
this._setupConversion();
|
|
62
|
-
if (editor.plugins.has('ImageBlockEditing')) {
|
|
63
|
-
editor.commands.add('imageTypeInline', new ImageTypeCommand(this.editor, 'imageInline'));
|
|
64
|
-
this._setupClipboardIntegration();
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* Configures conversion pipelines to support upcasting and downcasting
|
|
69
|
-
* inline images (inline image widgets) and their attributes.
|
|
70
|
-
*/
|
|
71
|
-
_setupConversion() {
|
|
72
|
-
const editor = this.editor;
|
|
73
|
-
const t = editor.t;
|
|
74
|
-
const conversion = editor.conversion;
|
|
75
|
-
const imageUtils = editor.plugins.get('ImageUtils');
|
|
76
|
-
conversion.for('dataDowncast')
|
|
77
|
-
.elementToElement({
|
|
78
|
-
model: 'imageInline',
|
|
79
|
-
view: (modelElement, { writer }) => writer.createEmptyElement('img')
|
|
80
|
-
});
|
|
81
|
-
conversion.for('editingDowncast')
|
|
82
|
-
.elementToStructure({
|
|
83
|
-
model: 'imageInline',
|
|
84
|
-
view: (modelElement, { writer }) => imageUtils.toImageWidget(createInlineImageViewElement(writer), writer, t('image widget'))
|
|
85
|
-
});
|
|
86
|
-
conversion.for('downcast')
|
|
87
|
-
.add(downcastImageAttribute(imageUtils, 'imageInline', 'src'))
|
|
88
|
-
.add(downcastImageAttribute(imageUtils, 'imageInline', 'alt'))
|
|
89
|
-
.add(downcastSrcsetAttribute(imageUtils, 'imageInline'));
|
|
90
|
-
// More image related upcasts are in 'ImageEditing' plugin.
|
|
91
|
-
conversion.for('upcast')
|
|
92
|
-
.elementToElement({
|
|
93
|
-
view: getImgViewElementMatcher(editor, 'imageInline'),
|
|
94
|
-
model: (viewImage, { writer }) => writer.createElement('imageInline', viewImage.hasAttribute('src') ? { src: viewImage.getAttribute('src') } : undefined)
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
/**
|
|
98
|
-
* Integrates the plugin with the clipboard pipeline.
|
|
99
|
-
*
|
|
100
|
-
* Idea is that the feature should recognize the user's intent when an **block** image is
|
|
101
|
-
* pasted or dropped. If such an image is pasted/dropped into a non-empty block
|
|
102
|
-
* (e.g. a paragraph with some text) it gets converted into an inline image on the fly.
|
|
103
|
-
*
|
|
104
|
-
* We assume this is the user's intent if they decided to put their image there.
|
|
105
|
-
*
|
|
106
|
-
* **Note**: If a block image has a caption, it will not be converted to an inline image
|
|
107
|
-
* to avoid the confusion. Captions are added on purpose and they should never be lost
|
|
108
|
-
* in the clipboard pipeline.
|
|
109
|
-
*
|
|
110
|
-
* See the `ImageBlockEditing` for the similar integration that works in the opposite direction.
|
|
111
|
-
*
|
|
112
|
-
* The feature also sets image `width` and `height` attributes when pasting.
|
|
113
|
-
*/
|
|
114
|
-
_setupClipboardIntegration() {
|
|
115
|
-
const editor = this.editor;
|
|
116
|
-
const model = editor.model;
|
|
117
|
-
const editingView = editor.editing.view;
|
|
118
|
-
const imageUtils = editor.plugins.get('ImageUtils');
|
|
119
|
-
const clipboardPipeline = editor.plugins.get('ClipboardPipeline');
|
|
120
|
-
this.listenTo(clipboardPipeline, 'inputTransformation', (evt, data) => {
|
|
121
|
-
const docFragmentChildren = Array.from(data.content.getChildren());
|
|
122
|
-
let modelRange;
|
|
123
|
-
// Make sure only <figure class="image"></figure> elements are dropped or pasted. Otherwise, if there some other HTML
|
|
124
|
-
// mixed up, this should be handled as a regular paste.
|
|
125
|
-
if (!docFragmentChildren.every(imageUtils.isBlockImageView)) {
|
|
126
|
-
return;
|
|
127
|
-
}
|
|
128
|
-
// When drag and dropping, data.targetRanges specifies where to drop because
|
|
129
|
-
// this is usually a different place than the current model selection (the user
|
|
130
|
-
// uses a drop marker to specify the drop location).
|
|
131
|
-
if (data.targetRanges) {
|
|
132
|
-
modelRange = editor.editing.mapper.toModelRange(data.targetRanges[0]);
|
|
133
|
-
}
|
|
134
|
-
// Pasting, however, always occurs at the current model selection.
|
|
135
|
-
else {
|
|
136
|
-
modelRange = model.document.selection.getFirstRange();
|
|
137
|
-
}
|
|
138
|
-
const selection = model.createSelection(modelRange);
|
|
139
|
-
// Convert block images into inline images only when pasting or dropping into non-empty blocks
|
|
140
|
-
// and when the block is not an object (e.g. pasting to replace another widget).
|
|
141
|
-
if (determineImageTypeForInsertionAtSelection(model.schema, selection) === 'imageInline') {
|
|
142
|
-
const writer = new ViewUpcastWriter(editingView.document);
|
|
143
|
-
// Unwrap <figure class="image"><img .../></figure> -> <img ... />
|
|
144
|
-
// but <figure class="image"><img .../><figcaption>...</figcaption></figure> -> stays the same
|
|
145
|
-
const inlineViewImages = docFragmentChildren.map(blockViewImage => {
|
|
146
|
-
// If there's just one child, it can be either <img /> or <a><img></a>.
|
|
147
|
-
// If there are other children than <img>, this means that the block image
|
|
148
|
-
// has a caption or some other features and this kind of image should be
|
|
149
|
-
// pasted/dropped without modifications.
|
|
150
|
-
if (blockViewImage.childCount === 1) {
|
|
151
|
-
// Pass the attributes which are present only in the <figure> to the <img>
|
|
152
|
-
// (e.g. the style="width:10%" attribute applied by the ImageResize plugin).
|
|
153
|
-
Array.from(blockViewImage.getAttributes())
|
|
154
|
-
.forEach(attribute => writer.setAttribute(...attribute, imageUtils.findViewImgElement(blockViewImage)));
|
|
155
|
-
return blockViewImage.getChild(0);
|
|
156
|
-
}
|
|
157
|
-
else {
|
|
158
|
-
return blockViewImage;
|
|
159
|
-
}
|
|
160
|
-
});
|
|
161
|
-
data.content = writer.createDocumentFragment(inlineViewImages);
|
|
162
|
-
}
|
|
163
|
-
});
|
|
164
|
-
this.listenTo(clipboardPipeline, 'contentInsertion', (evt, data) => {
|
|
165
|
-
if (data.method !== 'paste') {
|
|
166
|
-
return;
|
|
167
|
-
}
|
|
168
|
-
model.change(writer => {
|
|
169
|
-
const range = writer.createRangeIn(data.content);
|
|
170
|
-
for (const item of range.getItems()) {
|
|
171
|
-
if (item.is('element', 'imageInline')) {
|
|
172
|
-
imageUtils.setImageNaturalSizeAttributes(item);
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
});
|
|
176
|
-
});
|
|
177
|
-
}
|
|
178
|
-
}
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
-
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* @module image/image/imageloadobserver
|
|
7
|
-
*/
|
|
8
|
-
import { Observer } from 'ckeditor5/src/engine.js';
|
|
9
|
-
/**
|
|
10
|
-
* Observes all new images added to the {@link module:engine/view/document~ViewDocument},
|
|
11
|
-
* fires {@link module:engine/view/document~ViewDocument#event:imageLoaded} and
|
|
12
|
-
* {@link module:engine/view/document~ViewDocument#event:layoutChanged} event every time when the new image
|
|
13
|
-
* has been loaded.
|
|
14
|
-
*
|
|
15
|
-
* **Note:** This event is not fired for images that has been added to the document and rendered as `complete` (already loaded).
|
|
16
|
-
*/
|
|
17
|
-
export class ImageLoadObserver extends Observer {
|
|
18
|
-
/**
|
|
19
|
-
* @inheritDoc
|
|
20
|
-
*/
|
|
21
|
-
observe(domRoot) {
|
|
22
|
-
this.listenTo(domRoot, 'load', (event, domEvent) => {
|
|
23
|
-
const domElement = domEvent.target;
|
|
24
|
-
if (this.checkShouldIgnoreEventFromTarget(domElement)) {
|
|
25
|
-
return;
|
|
26
|
-
}
|
|
27
|
-
if (domElement.tagName == 'IMG') {
|
|
28
|
-
this._fireEvents(domEvent);
|
|
29
|
-
}
|
|
30
|
-
// Use capture phase for better performance (#4504).
|
|
31
|
-
}, { useCapture: true });
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* @inheritDoc
|
|
35
|
-
*/
|
|
36
|
-
stopObserving(domRoot) {
|
|
37
|
-
this.stopListening(domRoot);
|
|
38
|
-
}
|
|
39
|
-
/**
|
|
40
|
-
* Fires {@link module:engine/view/document~ViewDocument#event:layoutChanged} and
|
|
41
|
-
* {@link module:engine/view/document~ViewDocument#event:imageLoaded}
|
|
42
|
-
* if observer {@link #isEnabled is enabled}.
|
|
43
|
-
*
|
|
44
|
-
* @param domEvent The DOM event.
|
|
45
|
-
*/
|
|
46
|
-
_fireEvents(domEvent) {
|
|
47
|
-
if (this.isEnabled) {
|
|
48
|
-
this.document.fire('layoutChanged');
|
|
49
|
-
this.document.fire('imageLoaded', domEvent);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
}
|
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
-
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* @module image/image/imageplaceholder
|
|
7
|
-
*/
|
|
8
|
-
import { Plugin } from 'ckeditor5/src/core.js';
|
|
9
|
-
import { ImageUtils } from '../imageutils.js';
|
|
10
|
-
import { ImageLoadObserver } from './imageloadobserver.js';
|
|
11
|
-
import '../../theme/imageplaceholder.css';
|
|
12
|
-
/**
|
|
13
|
-
* Adds support for image placeholder that is automatically removed when the image is loaded.
|
|
14
|
-
*/
|
|
15
|
-
export class ImagePlaceholder extends Plugin {
|
|
16
|
-
/**
|
|
17
|
-
* @inheritDoc
|
|
18
|
-
*/
|
|
19
|
-
static get requires() {
|
|
20
|
-
return [ImageUtils];
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* @inheritDoc
|
|
24
|
-
*/
|
|
25
|
-
static get pluginName() {
|
|
26
|
-
return 'ImagePlaceholder';
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* @inheritDoc
|
|
30
|
-
*/
|
|
31
|
-
static get isOfficialPlugin() {
|
|
32
|
-
return true;
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* @inheritDoc
|
|
36
|
-
*/
|
|
37
|
-
afterInit() {
|
|
38
|
-
this._setupSchema();
|
|
39
|
-
this._setupConversion();
|
|
40
|
-
this._setupLoadListener();
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* Extends model schema.
|
|
44
|
-
*/
|
|
45
|
-
_setupSchema() {
|
|
46
|
-
const schema = this.editor.model.schema;
|
|
47
|
-
// Wait for ImageBlockEditing or ImageInlineEditing to register their elements first,
|
|
48
|
-
// that's why doing this in afterInit() instead of init().
|
|
49
|
-
if (schema.isRegistered('imageBlock')) {
|
|
50
|
-
schema.extend('imageBlock', {
|
|
51
|
-
allowAttributes: ['placeholder']
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
if (schema.isRegistered('imageInline')) {
|
|
55
|
-
schema.extend('imageInline', {
|
|
56
|
-
allowAttributes: ['placeholder']
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* Registers converters.
|
|
62
|
-
*/
|
|
63
|
-
_setupConversion() {
|
|
64
|
-
const editor = this.editor;
|
|
65
|
-
const conversion = editor.conversion;
|
|
66
|
-
const imageUtils = editor.plugins.get('ImageUtils');
|
|
67
|
-
conversion.for('editingDowncast').add(dispatcher => {
|
|
68
|
-
dispatcher.on('attribute:placeholder', (evt, data, conversionApi) => {
|
|
69
|
-
if (!conversionApi.consumable.test(data.item, evt.name)) {
|
|
70
|
-
return;
|
|
71
|
-
}
|
|
72
|
-
if (!data.item.is('element', 'imageBlock') && !data.item.is('element', 'imageInline')) {
|
|
73
|
-
return;
|
|
74
|
-
}
|
|
75
|
-
conversionApi.consumable.consume(data.item, evt.name);
|
|
76
|
-
const viewWriter = conversionApi.writer;
|
|
77
|
-
const element = conversionApi.mapper.toViewElement(data.item);
|
|
78
|
-
const img = imageUtils.findViewImgElement(element);
|
|
79
|
-
if (data.attributeNewValue) {
|
|
80
|
-
viewWriter.addClass('image_placeholder', img);
|
|
81
|
-
viewWriter.setStyle('background-image', `url(${data.attributeNewValue})`, img);
|
|
82
|
-
viewWriter.setCustomProperty('editingPipeline:doNotReuseOnce', true, img);
|
|
83
|
-
}
|
|
84
|
-
else {
|
|
85
|
-
viewWriter.removeClass('image_placeholder', img);
|
|
86
|
-
viewWriter.removeStyle('background-image', img);
|
|
87
|
-
}
|
|
88
|
-
});
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* Prepares listener for image load.
|
|
93
|
-
*/
|
|
94
|
-
_setupLoadListener() {
|
|
95
|
-
const editor = this.editor;
|
|
96
|
-
const model = editor.model;
|
|
97
|
-
const editing = editor.editing;
|
|
98
|
-
const editingView = editing.view;
|
|
99
|
-
const imageUtils = editor.plugins.get('ImageUtils');
|
|
100
|
-
editingView.addObserver(ImageLoadObserver);
|
|
101
|
-
this.listenTo(editingView.document, 'imageLoaded', (evt, domEvent) => {
|
|
102
|
-
const imgViewElement = editingView.domConverter.mapDomToView(domEvent.target);
|
|
103
|
-
if (!imgViewElement) {
|
|
104
|
-
return;
|
|
105
|
-
}
|
|
106
|
-
const viewElement = imageUtils.getImageWidgetFromImageView(imgViewElement);
|
|
107
|
-
if (!viewElement) {
|
|
108
|
-
return;
|
|
109
|
-
}
|
|
110
|
-
const modelElement = editing.mapper.toModelElement(viewElement);
|
|
111
|
-
if (!modelElement || !modelElement.hasAttribute('placeholder')) {
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
|
-
model.enqueueChange({ isUndoable: false }, writer => {
|
|
115
|
-
writer.removeAttribute('placeholder', modelElement);
|
|
116
|
-
});
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
}
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
-
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
4
|
-
*/
|
|
5
|
-
import { Command } from 'ckeditor5/src/core.js';
|
|
6
|
-
/**
|
|
7
|
-
* The image type command. It changes the type of a selected image, depending on the configuration.
|
|
8
|
-
*/
|
|
9
|
-
export class ImageTypeCommand extends Command {
|
|
10
|
-
/**
|
|
11
|
-
* Model element name the command converts to.
|
|
12
|
-
*/
|
|
13
|
-
_modelElementName;
|
|
14
|
-
/**
|
|
15
|
-
* @inheritDoc
|
|
16
|
-
*
|
|
17
|
-
* @param modelElementName Model element name the command converts to.
|
|
18
|
-
*/
|
|
19
|
-
constructor(editor, modelElementName) {
|
|
20
|
-
super(editor);
|
|
21
|
-
this._modelElementName = modelElementName;
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* @inheritDoc
|
|
25
|
-
*/
|
|
26
|
-
refresh() {
|
|
27
|
-
const editor = this.editor;
|
|
28
|
-
const imageUtils = editor.plugins.get('ImageUtils');
|
|
29
|
-
const element = imageUtils.getClosestSelectedImageElement(this.editor.model.document.selection);
|
|
30
|
-
if (this._modelElementName === 'imageBlock') {
|
|
31
|
-
this.isEnabled = imageUtils.isInlineImage(element);
|
|
32
|
-
}
|
|
33
|
-
else {
|
|
34
|
-
this.isEnabled = imageUtils.isBlockImage(element);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* Executes the command and changes the type of a selected image.
|
|
39
|
-
*
|
|
40
|
-
* @fires execute
|
|
41
|
-
* @param options.setImageSizes Specifies whether the image `width` and `height` attributes should be set automatically.
|
|
42
|
-
* The default is `true`.
|
|
43
|
-
* @returns An object containing references to old and new model image elements
|
|
44
|
-
* (for before and after the change) so external integrations can hook into the decorated
|
|
45
|
-
* `execute` event and handle this change. `null` if the type change failed.
|
|
46
|
-
*/
|
|
47
|
-
execute(options = {}) {
|
|
48
|
-
const editor = this.editor;
|
|
49
|
-
const model = this.editor.model;
|
|
50
|
-
const imageUtils = editor.plugins.get('ImageUtils');
|
|
51
|
-
const oldElement = imageUtils.getClosestSelectedImageElement(model.document.selection);
|
|
52
|
-
const attributes = Object.fromEntries(oldElement.getAttributes());
|
|
53
|
-
// Don't change image type if "src" is missing (a broken image), unless there's "uploadId" set.
|
|
54
|
-
// This state may happen during image upload (before it finishes) and it should be possible to change type
|
|
55
|
-
// of the image in the meantime.
|
|
56
|
-
if (!attributes.src && !attributes.uploadId) {
|
|
57
|
-
return null;
|
|
58
|
-
}
|
|
59
|
-
return model.change(writer => {
|
|
60
|
-
const { setImageSizes = true } = options;
|
|
61
|
-
// Get all markers that contain the old image element.
|
|
62
|
-
const markers = Array.from(model.markers)
|
|
63
|
-
.filter(marker => marker.getRange().containsItem(oldElement));
|
|
64
|
-
const newElement = imageUtils.insertImage(attributes, model.createSelection(oldElement, 'on'), this._modelElementName, { setImageSizes });
|
|
65
|
-
if (!newElement) {
|
|
66
|
-
return null;
|
|
67
|
-
}
|
|
68
|
-
const newElementRange = writer.createRangeOn(newElement);
|
|
69
|
-
// Expand the previously intersecting markers' ranges to include the new image element.
|
|
70
|
-
for (const marker of markers) {
|
|
71
|
-
const markerRange = marker.getRange();
|
|
72
|
-
// Join the survived part of the old marker range with the new element range
|
|
73
|
-
// (loosely because there could be some new paragraph or the existing one might got split).
|
|
74
|
-
const range = markerRange.root.rootName != '$graveyard' ?
|
|
75
|
-
markerRange.getJoined(newElementRange, true) : newElementRange;
|
|
76
|
-
writer.updateMarker(marker, { range });
|
|
77
|
-
}
|
|
78
|
-
return {
|
|
79
|
-
oldElement,
|
|
80
|
-
newElement
|
|
81
|
-
};
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
}
|