UNPKG

4.81 kBJavaScriptView Raw
1/**
2 * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
3 * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4 */
5import { Command } from 'ckeditor5/src/core';
6/**
7 * The image style command. It is used to apply {@link module:image/imageconfig~ImageStyleConfig#options image style option}
8 * to a selected image.
9 *
10 * **Note**: Executing this command may change the image model element if the desired style requires an image of a different
11 * type. See {@link module:image/imagestyle/imagestylecommand~ImageStyleCommand#execute} to learn more.
12 */
13export default class ImageStyleCommand extends Command {
14 /**
15 * Creates an instance of the image style command. When executed, the command applies one of
16 * {@link module:image/imageconfig~ImageStyleConfig#options style options} to the currently selected image.
17 *
18 * @param editor The editor instance.
19 * @param styles The style options that this command supports.
20 */
21 constructor(editor, styles) {
22 super(editor);
23 this._defaultStyles = {
24 imageBlock: false,
25 imageInline: false
26 };
27 this._styles = new Map(styles.map(style => {
28 if (style.isDefault) {
29 for (const modelElementName of style.modelElements) {
30 this._defaultStyles[modelElementName] = style.name;
31 }
32 }
33 return [style.name, style];
34 }));
35 }
36 /**
37 * @inheritDoc
38 */
39 refresh() {
40 const editor = this.editor;
41 const imageUtils = editor.plugins.get('ImageUtils');
42 const element = imageUtils.getClosestSelectedImageElement(this.editor.model.document.selection);
43 this.isEnabled = !!element;
44 if (!this.isEnabled) {
45 this.value = false;
46 }
47 else if (element.hasAttribute('imageStyle')) {
48 this.value = element.getAttribute('imageStyle');
49 }
50 else {
51 this.value = this._defaultStyles[element.name];
52 }
53 }
54 /**
55 * Executes the command and applies the style to the currently selected image:
56 *
57 * ```ts
58 * editor.execute( 'imageStyle', { value: 'side' } );
59 * ```
60 *
61 * **Note**: Executing this command may change the image model element if the desired style requires an image
62 * of a different type. Learn more about {@link module:image/imageconfig~ImageStyleOptionDefinition#modelElements model element}
63 * configuration for the style option.
64 *
65 * @param options.value The name of the style (as configured in {@link module:image/imageconfig~ImageStyleConfig#options}).
66 * @param options.setImageSizes Specifies whether the image `width` and `height` attributes should be set automatically.
67 * The default is `true`.
68 * @fires execute
69 */
70 execute(options = {}) {
71 const editor = this.editor;
72 const model = editor.model;
73 const imageUtils = editor.plugins.get('ImageUtils');
74 model.change(writer => {
75 const requestedStyle = options.value;
76 const { setImageSizes = true } = options;
77 let imageElement = imageUtils.getClosestSelectedImageElement(model.document.selection);
78 // Change the image type if a style requires it.
79 if (requestedStyle && this.shouldConvertImageType(requestedStyle, imageElement)) {
80 this.editor.execute(imageUtils.isBlockImage(imageElement) ? 'imageTypeInline' : 'imageTypeBlock', { setImageSizes });
81 // Update the imageElement to the newly created image.
82 imageElement = imageUtils.getClosestSelectedImageElement(model.document.selection);
83 }
84 // Default style means that there is no `imageStyle` attribute in the model.
85 // https://github.com/ckeditor/ckeditor5-image/issues/147
86 if (!requestedStyle || this._styles.get(requestedStyle).isDefault) {
87 writer.removeAttribute('imageStyle', imageElement);
88 }
89 else {
90 writer.setAttribute('imageStyle', requestedStyle, imageElement);
91 }
92 if (setImageSizes) {
93 imageUtils.setImageNaturalSizeAttributes(imageElement);
94 }
95 });
96 }
97 /**
98 * Returns `true` if requested style change would trigger the image type change.
99 *
100 * @param requestedStyle The name of the style (as configured in {@link module:image/imageconfig~ImageStyleConfig#options}).
101 * @param imageElement The image model element.
102 */
103 shouldConvertImageType(requestedStyle, imageElement) {
104 const supportedTypes = this._styles.get(requestedStyle).modelElements;
105 return !supportedTypes.includes(imageElement.name);
106 }
107}