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 | */
|
5 | /**
|
6 | * @module link/linkimageui
|
7 | */
|
8 | import { ButtonView } from 'ckeditor5/src/ui';
|
9 | import { Plugin } from 'ckeditor5/src/core';
|
10 | import LinkUI from './linkui';
|
11 | import LinkEditing from './linkediting';
|
12 | import { LINK_KEYSTROKE } from './utils';
|
13 | import linkIcon from '../theme/icons/link.svg';
|
14 | /**
|
15 | * The link image UI plugin.
|
16 | *
|
17 | * This plugin provides the `'linkImage'` button that can be displayed in the {@link module:image/imagetoolbar~ImageToolbar}.
|
18 | * It can be used to wrap images in links.
|
19 | */
|
20 | export default class LinkImageUI extends Plugin {
|
21 | /**
|
22 | * @inheritDoc
|
23 | */
|
24 | static get requires() {
|
25 | return [LinkEditing, LinkUI, 'ImageBlockEditing'];
|
26 | }
|
27 | /**
|
28 | * @inheritDoc
|
29 | */
|
30 | static get pluginName() {
|
31 | return 'LinkImageUI';
|
32 | }
|
33 | /**
|
34 | * @inheritDoc
|
35 | */
|
36 | init() {
|
37 | const editor = this.editor;
|
38 | const viewDocument = editor.editing.view.document;
|
39 | this.listenTo(viewDocument, 'click', (evt, data) => {
|
40 | if (this._isSelectedLinkedImage(editor.model.document.selection)) {
|
41 | // Prevent browser navigation when clicking a linked image.
|
42 | data.preventDefault();
|
43 | // Block the `LinkUI` plugin when an image was clicked.
|
44 | // In such a case, we'd like to display the image toolbar.
|
45 | evt.stop();
|
46 | }
|
47 | }, { priority: 'high' });
|
48 | this._createToolbarLinkImageButton();
|
49 | }
|
50 | /**
|
51 | * Creates a `LinkImageUI` button view.
|
52 | *
|
53 | * Clicking this button shows a {@link module:link/linkui~LinkUI#_balloon} attached to the selection.
|
54 | * When an image is already linked, the view shows {@link module:link/linkui~LinkUI#actionsView} or
|
55 | * {@link module:link/linkui~LinkUI#formView} if it is not.
|
56 | */
|
57 | _createToolbarLinkImageButton() {
|
58 | const editor = this.editor;
|
59 | const t = editor.t;
|
60 | editor.ui.componentFactory.add('linkImage', locale => {
|
61 | const button = new ButtonView(locale);
|
62 | const plugin = editor.plugins.get('LinkUI');
|
63 | const linkCommand = editor.commands.get('link');
|
64 | button.set({
|
65 | isEnabled: true,
|
66 | label: t('Link image'),
|
67 | icon: linkIcon,
|
68 | keystroke: LINK_KEYSTROKE,
|
69 | tooltip: true,
|
70 | isToggleable: true
|
71 | });
|
72 | // Bind button to the command.
|
73 | button.bind('isEnabled').to(linkCommand, 'isEnabled');
|
74 | button.bind('isOn').to(linkCommand, 'value', value => !!value);
|
75 | // Show the actionsView or formView (both from LinkUI) on button click depending on whether the image is linked already.
|
76 | this.listenTo(button, 'execute', () => {
|
77 | if (this._isSelectedLinkedImage(editor.model.document.selection)) {
|
78 | plugin._addActionsView();
|
79 | }
|
80 | else {
|
81 | plugin._showUI(true);
|
82 | }
|
83 | });
|
84 | return button;
|
85 | });
|
86 | }
|
87 | /**
|
88 | * Returns true if a linked image (either block or inline) is the only selected element
|
89 | * in the model document.
|
90 | */
|
91 | _isSelectedLinkedImage(selection) {
|
92 | const selectedModelElement = selection.getSelectedElement();
|
93 | const imageUtils = this.editor.plugins.get('ImageUtils');
|
94 | return imageUtils.isImage(selectedModelElement) && selectedModelElement.hasAttribute('linkHref');
|
95 | }
|
96 | }
|