UNPKG

@ckeditor/ckeditor5-image

Version:

Image feature for CKEditor 5.

142 lines (141 loc) 6.08 kB
/** * @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; } }