@ckeditor/ckeditor5-link 36.0.1 → 37.0.0-alpha.1

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.
@@ -2,121 +2,95 @@
2
2
  * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
4
  */
5
-
6
5
  /**
7
6
  * @module link/linkimageui
8
7
  */
9
-
10
8
  import { ButtonView } from 'ckeditor5/src/ui';
11
9
  import { Plugin } from 'ckeditor5/src/core';
12
-
13
10
  import LinkUI from './linkui';
14
11
  import LinkEditing from './linkediting';
15
-
16
12
  import { LINK_KEYSTROKE } from './utils';
17
-
18
13
  import linkIcon from '../theme/icons/link.svg';
19
-
20
14
  /**
21
15
  * The link image UI plugin.
22
16
  *
23
17
  * This plugin provides the `'linkImage'` button that can be displayed in the {@link module:image/imagetoolbar~ImageToolbar}.
24
18
  * It can be used to wrap images in links.
25
- *
26
- * @extends module:core/plugin~Plugin
27
19
  */
28
20
  export default class LinkImageUI extends Plugin {
29
- /**
30
- * @inheritDoc
31
- */
32
- static get requires() {
33
- return [ LinkEditing, LinkUI, 'ImageBlockEditing' ];
34
- }
35
-
36
- /**
37
- * @inheritDoc
38
- */
39
- static get pluginName() {
40
- return 'LinkImageUI';
41
- }
42
-
43
- /**
44
- * @inheritDoc
45
- */
46
- init() {
47
- const editor = this.editor;
48
- const viewDocument = editor.editing.view.document;
49
-
50
- this.listenTo( viewDocument, 'click', ( evt, data ) => {
51
- if ( this._isSelectedLinkedImage( editor.model.document.selection ) ) {
52
- // Prevent browser navigation when clicking a linked image.
53
- data.preventDefault();
54
-
55
- // Block the `LinkUI` plugin when an image was clicked.
56
- // In such a case, we'd like to display the image toolbar.
57
- evt.stop();
58
- }
59
- }, { priority: 'high' } );
60
-
61
- this._createToolbarLinkImageButton();
62
- }
63
-
64
- /**
65
- * Creates a `LinkImageUI` button view.
66
- *
67
- * Clicking this button shows a {@link module:link/linkui~LinkUI#_balloon} attached to the selection.
68
- * When an image is already linked, the view shows {@link module:link/linkui~LinkUI#actionsView} or
69
- * {@link module:link/linkui~LinkUI#formView} if it is not.
70
- *
71
- * @private
72
- */
73
- _createToolbarLinkImageButton() {
74
- const editor = this.editor;
75
- const t = editor.t;
76
-
77
- editor.ui.componentFactory.add( 'linkImage', locale => {
78
- const button = new ButtonView( locale );
79
- const plugin = editor.plugins.get( 'LinkUI' );
80
- const linkCommand = editor.commands.get( 'link' );
81
-
82
- button.set( {
83
- isEnabled: true,
84
- label: t( 'Link image' ),
85
- icon: linkIcon,
86
- keystroke: LINK_KEYSTROKE,
87
- tooltip: true,
88
- isToggleable: true
89
- } );
90
-
91
- // Bind button to the command.
92
- button.bind( 'isEnabled' ).to( linkCommand, 'isEnabled' );
93
- button.bind( 'isOn' ).to( linkCommand, 'value', value => !!value );
94
-
95
- // Show the actionsView or formView (both from LinkUI) on button click depending on whether the image is linked already.
96
- this.listenTo( button, 'execute', () => {
97
- if ( this._isSelectedLinkedImage( editor.model.document.selection ) ) {
98
- plugin._addActionsView();
99
- } else {
100
- plugin._showUI( true );
101
- }
102
- } );
103
-
104
- return button;
105
- } );
106
- }
107
-
108
- /**
109
- * Returns true if a linked image (either block or inline) is the only selected element
110
- * in the model document.
111
- *
112
- * @private
113
- * @param {module:engine/model/selection~Selection} selection
114
- * @returns {Boolean}
115
- */
116
- _isSelectedLinkedImage( selection ) {
117
- const selectedModelElement = selection.getSelectedElement();
118
- const imageUtils = this.editor.plugins.get( 'ImageUtils' );
119
-
120
- return imageUtils.isImage( selectedModelElement ) && selectedModelElement.hasAttribute( 'linkHref' );
121
- }
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
+ }
122
96
  }
@@ -0,0 +1,165 @@
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/linkui
7
+ */
8
+ import { Plugin, type PluginDependencies } from 'ckeditor5/src/core';
9
+ import { type ViewWithCssTransitionDisabler } from 'ckeditor5/src/ui';
10
+ import LinkFormView from './ui/linkformview';
11
+ import LinkActionsView from './ui/linkactionsview';
12
+ /**
13
+ * The link UI plugin. It introduces the `'link'` and `'unlink'` buttons and support for the <kbd>Ctrl+K</kbd> keystroke.
14
+ *
15
+ * It uses the
16
+ * {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon contextual balloon plugin}.
17
+ */
18
+ export default class LinkUI extends Plugin {
19
+ /**
20
+ * The actions view displayed inside of the balloon.
21
+ */
22
+ actionsView: LinkActionsView | null;
23
+ /**
24
+ * The form view displayed inside the balloon.
25
+ */
26
+ formView: LinkFormView & ViewWithCssTransitionDisabler | null;
27
+ /**
28
+ * The contextual balloon plugin instance.
29
+ */
30
+ private _balloon;
31
+ /**
32
+ * @inheritDoc
33
+ */
34
+ static get requires(): PluginDependencies;
35
+ /**
36
+ * @inheritDoc
37
+ */
38
+ static get pluginName(): 'LinkUI';
39
+ /**
40
+ * @inheritDoc
41
+ */
42
+ init(): void;
43
+ /**
44
+ * @inheritDoc
45
+ */
46
+ destroy(): void;
47
+ /**
48
+ * Creates views.
49
+ */
50
+ private _createViews;
51
+ /**
52
+ * Creates the {@link module:link/ui/linkactionsview~LinkActionsView} instance.
53
+ */
54
+ private _createActionsView;
55
+ /**
56
+ * Creates the {@link module:link/ui/linkformview~LinkFormView} instance.
57
+ */
58
+ private _createFormView;
59
+ /**
60
+ * Creates a toolbar Link button. Clicking this button will show
61
+ * a {@link #_balloon} attached to the selection.
62
+ */
63
+ private _createToolbarLinkButton;
64
+ /**
65
+ * Attaches actions that control whether the balloon panel containing the
66
+ * {@link #formView} should be displayed.
67
+ */
68
+ private _enableBalloonActivators;
69
+ /**
70
+ * Attaches actions that control whether the balloon panel containing the
71
+ * {@link #formView} is visible or not.
72
+ */
73
+ private _enableUserBalloonInteractions;
74
+ /**
75
+ * Adds the {@link #actionsView} to the {@link #_balloon}.
76
+ *
77
+ * @internal
78
+ */
79
+ _addActionsView(): void;
80
+ /**
81
+ * Adds the {@link #formView} to the {@link #_balloon}.
82
+ */
83
+ private _addFormView;
84
+ /**
85
+ * Closes the form view. Decides whether the balloon should be hidden completely or if the action view should be shown. This is
86
+ * decided upon the link command value (which has a value if the document selection is in the link).
87
+ *
88
+ * Additionally, if any {@link module:link/linkconfig~LinkConfig#decorators} are defined in the editor configuration, the state of
89
+ * switch buttons responsible for manual decorator handling is restored.
90
+ */
91
+ private _closeFormView;
92
+ /**
93
+ * Removes the {@link #formView} from the {@link #_balloon}.
94
+ */
95
+ private _removeFormView;
96
+ /**
97
+ * Shows the correct UI type. It is either {@link #formView} or {@link #actionsView}.
98
+ *
99
+ * @internal
100
+ */
101
+ _showUI(forceVisible?: boolean): void;
102
+ /**
103
+ * Removes the {@link #formView} from the {@link #_balloon}.
104
+ *
105
+ * See {@link #_addFormView}, {@link #_addActionsView}.
106
+ */
107
+ private _hideUI;
108
+ /**
109
+ * Makes the UI react to the {@link module:ui/editorui/editorui~EditorUI#event:update} event to
110
+ * reposition itself when the editor UI should be refreshed.
111
+ *
112
+ * See: {@link #_hideUI} to learn when the UI stops reacting to the `update` event.
113
+ */
114
+ private _startUpdatingUI;
115
+ /**
116
+ * Returns `true` when {@link #formView} is in the {@link #_balloon}.
117
+ */
118
+ private get _isFormInPanel();
119
+ /**
120
+ * Returns `true` when {@link #actionsView} is in the {@link #_balloon}.
121
+ */
122
+ private get _areActionsInPanel();
123
+ /**
124
+ * Returns `true` when {@link #actionsView} is in the {@link #_balloon} and it is
125
+ * currently visible.
126
+ */
127
+ private get _areActionsVisible();
128
+ /**
129
+ * Returns `true` when {@link #actionsView} or {@link #formView} is in the {@link #_balloon}.
130
+ */
131
+ private get _isUIInPanel();
132
+ /**
133
+ * Returns `true` when {@link #actionsView} or {@link #formView} is in the {@link #_balloon} and it is
134
+ * currently visible.
135
+ */
136
+ private get _isUIVisible();
137
+ /**
138
+ * Returns positioning options for the {@link #_balloon}. They control the way the balloon is attached
139
+ * to the target element or selection.
140
+ *
141
+ * If the selection is collapsed and inside a link element, the panel will be attached to the
142
+ * entire link element. Otherwise, it will be attached to the selection.
143
+ */
144
+ private _getBalloonPositionData;
145
+ /**
146
+ * Returns the link {@link module:engine/view/attributeelement~AttributeElement} under
147
+ * the {@link module:engine/view/document~Document editing view's} selection or `null`
148
+ * if there is none.
149
+ *
150
+ * **Note**: For a non–collapsed selection, the link element is returned when **fully**
151
+ * selected and the **only** element within the selection boundaries, or when
152
+ * a linked widget is selected.
153
+ */
154
+ private _getSelectedLinkElement;
155
+ /**
156
+ * Displays a fake visual selection when the contextual balloon is displayed.
157
+ *
158
+ * This adds a 'link-ui' marker into the document that is rendered as a highlight on selected text fragment.
159
+ */
160
+ private _showFakeVisualSelection;
161
+ /**
162
+ * Hides the fake visual selection created in {@link #_showFakeVisualSelection}.
163
+ */
164
+ private _hideFakeVisualSelection;
165
+ }