@ckeditor/ckeditor5-image
Version:
Image feature for CKEditor 5.
142 lines (141 loc) • 6.08 kB
JavaScript
/**
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
*/
/**
* @module image/imageinsert/imageinsertui
*/
import { Plugin, icons } from 'ckeditor5/src/core';
import { SplitButtonView, createDropdown } from 'ckeditor5/src/ui';
import ImageInsertPanelView from './ui/imageinsertpanelview';
import { prepareIntegrations } from './utils';
/**
* The image insert dropdown plugin.
*
* For a detailed overview, check the {@glink features/images/image-upload/image-upload Image upload feature}
* and {@glink features/images/images-inserting Insert images via source URL} documentation.
*
* Adds the `'insertImage'` dropdown to the {@link module:ui/componentfactory~ComponentFactory UI component factory}
* and also the `imageInsert` dropdown as an alias for backward compatibility.
*/
export default class ImageInsertUI extends Plugin {
/**
* @inheritDoc
*/
static get pluginName() {
return 'ImageInsertUI';
}
/**
* @inheritDoc
*/
init() {
const editor = this.editor;
const componentCreator = (locale) => {
return this._createDropdownView(locale);
};
// Register `insertImage` dropdown and add `imageInsert` dropdown as an alias for backward compatibility.
editor.ui.componentFactory.add('insertImage', componentCreator);
editor.ui.componentFactory.add('imageInsert', componentCreator);
}
/**
* Creates the dropdown view.
*
* @param locale The localization services instance.
*/
_createDropdownView(locale) {
const editor = this.editor;
const t = locale.t;
const uploadImageCommand = editor.commands.get('uploadImage');
const insertImageCommand = editor.commands.get('insertImage');
this.dropdownView = createDropdown(locale, uploadImageCommand ? SplitButtonView : undefined);
const buttonView = this.dropdownView.buttonView;
const panelView = this.dropdownView.panelView;
buttonView.set({
label: t('Insert image'),
icon: icons.image,
tooltip: true
});
panelView.extendTemplate({
attributes: {
class: 'ck-image-insert__panel'
}
});
if (uploadImageCommand) {
const splitButtonView = this.dropdownView.buttonView;
// We are injecting custom button replacement to readonly field.
splitButtonView.actionView = editor.ui.componentFactory.create('uploadImage');
// After we replaced action button with `uploadImage` component,
// we have lost a proper styling and some minor visual quirks have appeared.
// Brining back original split button classes helps fix the button styling
// See https://github.com/ckeditor/ckeditor5/issues/7986.
splitButtonView.actionView.extendTemplate({
attributes: {
class: 'ck ck-button ck-splitbutton__action'
}
});
}
return this._setUpDropdown(uploadImageCommand || insertImageCommand);
}
/**
* Sets up the dropdown view.
*
* @param command An uploadImage or insertImage command.
*/
_setUpDropdown(command) {
const editor = this.editor;
const t = editor.t;
const dropdownView = this.dropdownView;
const panelView = dropdownView.panelView;
const imageUtils = this.editor.plugins.get('ImageUtils');
const replaceImageSourceCommand = editor.commands.get('replaceImageSource');
let imageInsertView;
dropdownView.bind('isEnabled').to(command);
dropdownView.once('change:isOpen', () => {
imageInsertView = new ImageInsertPanelView(editor.locale, prepareIntegrations(editor));
imageInsertView.delegate('submit', 'cancel').to(dropdownView);
panelView.children.add(imageInsertView);
});
dropdownView.on('change:isOpen', () => {
const selectedElement = editor.model.document.selection.getSelectedElement();
const insertButtonView = imageInsertView.insertButtonView;
const insertImageViaUrlForm = imageInsertView.getIntegration('insertImageViaUrl');
if (dropdownView.isOpen) {
if (imageUtils.isImage(selectedElement)) {
imageInsertView.imageURLInputValue = replaceImageSourceCommand.value;
insertButtonView.label = t('Update');
insertImageViaUrlForm.label = t('Update image URL');
}
else {
imageInsertView.imageURLInputValue = '';
insertButtonView.label = t('Insert');
insertImageViaUrlForm.label = t('Insert image via URL');
}
}
// Note: Use the low priority to make sure the following listener starts working after the
// default action of the drop-down is executed (i.e. the panel showed up). Otherwise, the
// invisible form/input cannot be focused/selected.
}, { priority: 'low' });
this.delegate('cancel').to(dropdownView);
dropdownView.on('submit', () => {
closePanel();
onSubmit();
});
dropdownView.on('cancel', () => {
closePanel();
});
function onSubmit() {
const selectedElement = editor.model.document.selection.getSelectedElement();
if (imageUtils.isImage(selectedElement)) {
editor.execute('replaceImageSource', { source: imageInsertView.imageURLInputValue });
}
else {
editor.execute('insertImage', { source: imageInsertView.imageURLInputValue });
}
}
function closePanel() {
editor.editing.view.focus();
dropdownView.isOpen = false;
}
return dropdownView;
}
}