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

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,361 +2,231 @@
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/ui/linkformview
8
7
  */
9
-
10
- import {
11
- ButtonView,
12
- FocusCycler,
13
- LabeledFieldView,
14
- SwitchButtonView,
15
- View,
16
- ViewCollection,
17
- createLabeledInputText,
18
- injectCssTransitionDisabler,
19
- submitHandler
20
- } from 'ckeditor5/src/ui';
8
+ import { ButtonView, FocusCycler, LabeledFieldView, SwitchButtonView, View, ViewCollection, createLabeledInputText, submitHandler } from 'ckeditor5/src/ui';
21
9
  import { FocusTracker, KeystrokeHandler } from 'ckeditor5/src/utils';
22
10
  import { icons } from 'ckeditor5/src/core';
23
-
24
11
  // See: #8833.
25
12
  // eslint-disable-next-line ckeditor5-rules/ckeditor-imports
26
13
  import '@ckeditor/ckeditor5-ui/theme/components/responsive-form/responsiveform.css';
27
14
  import '../../theme/linkform.css';
28
-
29
15
  /**
30
16
  * The link form view controller class.
31
17
  *
32
18
  * See {@link module:link/ui/linkformview~LinkFormView}.
33
- *
34
- * @extends module:ui/view~View
35
19
  */
36
20
  export default class LinkFormView extends View {
37
- /**
38
- * Creates an instance of the {@link module:link/ui/linkformview~LinkFormView} class.
39
- *
40
- * Also see {@link #render}.
41
- *
42
- * @param {module:utils/locale~Locale} [locale] The localization services instance.
43
- * @param {module:link/linkcommand~LinkCommand} linkCommand Reference to {@link module:link/linkcommand~LinkCommand}.
44
- * @param {String} [protocol] A value of a protocol to be displayed in the input's placeholder.
45
- */
46
- constructor( locale, linkCommand ) {
47
- super( locale );
48
-
49
- const t = locale.t;
50
-
51
- /**
52
- * Tracks information about DOM focus in the form.
53
- *
54
- * @readonly
55
- * @member {module:utils/focustracker~FocusTracker}
56
- */
57
- this.focusTracker = new FocusTracker();
58
-
59
- /**
60
- * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.
61
- *
62
- * @readonly
63
- * @member {module:utils/keystrokehandler~KeystrokeHandler}
64
- */
65
- this.keystrokes = new KeystrokeHandler();
66
-
67
- /**
68
- * The URL input view.
69
- *
70
- * @member {module:ui/labeledfield/labeledfieldview~LabeledFieldView}
71
- */
72
- this.urlInputView = this._createUrlInput();
73
-
74
- /**
75
- * The Save button view.
76
- *
77
- * @member {module:ui/button/buttonview~ButtonView}
78
- */
79
- this.saveButtonView = this._createButton( t( 'Save' ), icons.check, 'ck-button-save' );
80
- this.saveButtonView.type = 'submit';
81
-
82
- /**
83
- * The Cancel button view.
84
- *
85
- * @member {module:ui/button/buttonview~ButtonView}
86
- */
87
- this.cancelButtonView = this._createButton( t( 'Cancel' ), icons.cancel, 'ck-button-cancel', 'cancel' );
88
-
89
- /**
90
- * A collection of {@link module:ui/button/switchbuttonview~SwitchButtonView},
91
- * which corresponds to {@link module:link/linkcommand~LinkCommand#manualDecorators manual decorators}
92
- * configured in the editor.
93
- *
94
- * @private
95
- * @readonly
96
- * @type {module:ui/viewcollection~ViewCollection}
97
- */
98
- this._manualDecoratorSwitches = this._createManualDecoratorSwitches( linkCommand );
99
-
100
- /**
101
- * A collection of child views in the form.
102
- *
103
- * @readonly
104
- * @type {module:ui/viewcollection~ViewCollection}
105
- */
106
- this.children = this._createFormChildren( linkCommand.manualDecorators );
107
-
108
- /**
109
- * A collection of views that can be focused in the form.
110
- *
111
- * @readonly
112
- * @protected
113
- * @member {module:ui/viewcollection~ViewCollection}
114
- */
115
- this._focusables = new ViewCollection();
116
-
117
- /**
118
- * Helps cycling over {@link #_focusables} in the form.
119
- *
120
- * @readonly
121
- * @protected
122
- * @member {module:ui/focuscycler~FocusCycler}
123
- */
124
- this._focusCycler = new FocusCycler( {
125
- focusables: this._focusables,
126
- focusTracker: this.focusTracker,
127
- keystrokeHandler: this.keystrokes,
128
- actions: {
129
- // Navigate form fields backwards using the Shift + Tab keystroke.
130
- focusPrevious: 'shift + tab',
131
-
132
- // Navigate form fields forwards using the Tab key.
133
- focusNext: 'tab'
134
- }
135
- } );
136
-
137
- const classList = [ 'ck', 'ck-link-form', 'ck-responsive-form' ];
138
-
139
- if ( linkCommand.manualDecorators.length ) {
140
- classList.push( 'ck-link-form_layout-vertical', 'ck-vertical-form' );
141
- }
142
-
143
- this.setTemplate( {
144
- tag: 'form',
145
-
146
- attributes: {
147
- class: classList,
148
-
149
- // https://github.com/ckeditor/ckeditor5-link/issues/90
150
- tabindex: '-1'
151
- },
152
-
153
- children: this.children
154
- } );
155
-
156
- injectCssTransitionDisabler( this );
157
- }
158
-
159
- /**
160
- * Obtains the state of the {@link module:ui/button/switchbuttonview~SwitchButtonView switch buttons} representing
161
- * {@link module:link/linkcommand~LinkCommand#manualDecorators manual link decorators}
162
- * in the {@link module:link/ui/linkformview~LinkFormView}.
163
- *
164
- * @returns {Object.<String,Boolean>} Key-value pairs, where the key is the name of the decorator and the value is
165
- * its state.
166
- */
167
- getDecoratorSwitchesState() {
168
- return Array.from( this._manualDecoratorSwitches ).reduce( ( accumulator, switchButton ) => {
169
- accumulator[ switchButton.name ] = switchButton.isOn;
170
- return accumulator;
171
- }, {} );
172
- }
173
-
174
- /**
175
- * @inheritDoc
176
- */
177
- render() {
178
- super.render();
179
-
180
- submitHandler( {
181
- view: this
182
- } );
183
-
184
- const childViews = [
185
- this.urlInputView,
186
- ...this._manualDecoratorSwitches,
187
- this.saveButtonView,
188
- this.cancelButtonView
189
- ];
190
-
191
- childViews.forEach( v => {
192
- // Register the view as focusable.
193
- this._focusables.add( v );
194
-
195
- // Register the view in the focus tracker.
196
- this.focusTracker.add( v.element );
197
- } );
198
-
199
- // Start listening for the keystrokes coming from #element.
200
- this.keystrokes.listenTo( this.element );
201
- }
202
-
203
- /**
204
- * @inheritDoc
205
- */
206
- destroy() {
207
- super.destroy();
208
-
209
- this.focusTracker.destroy();
210
- this.keystrokes.destroy();
211
- }
212
-
213
- /**
214
- * Focuses the fist {@link #_focusables} in the form.
215
- */
216
- focus() {
217
- this._focusCycler.focusFirst();
218
- }
219
-
220
- /**
221
- * Creates a labeled input view.
222
- *
223
- * @private
224
- * @returns {module:ui/labeledfield/labeledfieldview~LabeledFieldView} Labeled field view instance.
225
- */
226
- _createUrlInput() {
227
- const t = this.locale.t;
228
- const labeledInput = new LabeledFieldView( this.locale, createLabeledInputText );
229
-
230
- labeledInput.label = t( 'Link URL' );
231
-
232
- return labeledInput;
233
- }
234
-
235
- /**
236
- * Creates a button view.
237
- *
238
- * @private
239
- * @param {String} label The button label.
240
- * @param {String} icon The button icon.
241
- * @param {String} className The additional button CSS class name.
242
- * @param {String} [eventName] An event name that the `ButtonView#execute` event will be delegated to.
243
- * @returns {module:ui/button/buttonview~ButtonView} The button view instance.
244
- */
245
- _createButton( label, icon, className, eventName ) {
246
- const button = new ButtonView( this.locale );
247
-
248
- button.set( {
249
- label,
250
- icon,
251
- tooltip: true
252
- } );
253
-
254
- button.extendTemplate( {
255
- attributes: {
256
- class: className
257
- }
258
- } );
259
-
260
- if ( eventName ) {
261
- button.delegate( 'execute' ).to( this, eventName );
262
- }
263
-
264
- return button;
265
- }
266
-
267
- /**
268
- * Populates {@link module:ui/viewcollection~ViewCollection} of {@link module:ui/button/switchbuttonview~SwitchButtonView}
269
- * made based on {@link module:link/linkcommand~LinkCommand#manualDecorators}.
270
- *
271
- * @private
272
- * @param {module:link/linkcommand~LinkCommand} linkCommand A reference to the link command.
273
- * @returns {module:ui/viewcollection~ViewCollection} of switch buttons.
274
- */
275
- _createManualDecoratorSwitches( linkCommand ) {
276
- const switches = this.createCollection();
277
-
278
- for ( const manualDecorator of linkCommand.manualDecorators ) {
279
- const switchButton = new SwitchButtonView( this.locale );
280
-
281
- switchButton.set( {
282
- name: manualDecorator.id,
283
- label: manualDecorator.label,
284
- withText: true
285
- } );
286
-
287
- switchButton.bind( 'isOn' ).toMany( [ manualDecorator, linkCommand ], 'value', ( decoratorValue, commandValue ) => {
288
- return commandValue === undefined && decoratorValue === undefined ? manualDecorator.defaultValue : decoratorValue;
289
- } );
290
-
291
- switchButton.on( 'execute', () => {
292
- manualDecorator.set( 'value', !switchButton.isOn );
293
- } );
294
-
295
- switches.add( switchButton );
296
- }
297
-
298
- return switches;
299
- }
300
-
301
- /**
302
- * Populates the {@link #children} collection of the form.
303
- *
304
- * If {@link module:link/linkcommand~LinkCommand#manualDecorators manual decorators} are configured in the editor, it creates an
305
- * additional `View` wrapping all {@link #_manualDecoratorSwitches} switch buttons corresponding
306
- * to these decorators.
307
- *
308
- * @private
309
- * @param {module:utils/collection~Collection} manualDecorators A reference to
310
- * the collection of manual decorators stored in the link command.
311
- * @returns {module:ui/viewcollection~ViewCollection} The children of link form view.
312
- */
313
- _createFormChildren( manualDecorators ) {
314
- const children = this.createCollection();
315
-
316
- children.add( this.urlInputView );
317
-
318
- if ( manualDecorators.length ) {
319
- const additionalButtonsView = new View();
320
-
321
- additionalButtonsView.setTemplate( {
322
- tag: 'ul',
323
- children: this._manualDecoratorSwitches.map( switchButton => ( {
324
- tag: 'li',
325
- children: [ switchButton ],
326
- attributes: {
327
- class: [
328
- 'ck',
329
- 'ck-list__item'
330
- ]
331
- }
332
- } ) ),
333
- attributes: {
334
- class: [
335
- 'ck',
336
- 'ck-reset',
337
- 'ck-list'
338
- ]
339
- }
340
- } );
341
- children.add( additionalButtonsView );
342
- }
343
-
344
- children.add( this.saveButtonView );
345
- children.add( this.cancelButtonView );
346
-
347
- return children;
348
- }
21
+ /**
22
+ * Creates an instance of the {@link module:link/ui/linkformview~LinkFormView} class.
23
+ *
24
+ * Also see {@link #render}.
25
+ *
26
+ * @param locale The localization services instance.
27
+ * @param linkCommand Reference to {@link module:link/linkcommand~LinkCommand}.
28
+ */
29
+ constructor(locale, linkCommand) {
30
+ super(locale);
31
+ /**
32
+ * Tracks information about DOM focus in the form.
33
+ */
34
+ this.focusTracker = new FocusTracker();
35
+ /**
36
+ * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.
37
+ */
38
+ this.keystrokes = new KeystrokeHandler();
39
+ /**
40
+ * A collection of views that can be focused in the form.
41
+ */
42
+ this._focusables = new ViewCollection();
43
+ const t = locale.t;
44
+ this.urlInputView = this._createUrlInput();
45
+ this.saveButtonView = this._createButton(t('Save'), icons.check, 'ck-button-save');
46
+ this.saveButtonView.type = 'submit';
47
+ this.cancelButtonView = this._createButton(t('Cancel'), icons.cancel, 'ck-button-cancel', 'cancel');
48
+ this._manualDecoratorSwitches = this._createManualDecoratorSwitches(linkCommand);
49
+ this.children = this._createFormChildren(linkCommand.manualDecorators);
50
+ this._focusCycler = new FocusCycler({
51
+ focusables: this._focusables,
52
+ focusTracker: this.focusTracker,
53
+ keystrokeHandler: this.keystrokes,
54
+ actions: {
55
+ // Navigate form fields backwards using the Shift + Tab keystroke.
56
+ focusPrevious: 'shift + tab',
57
+ // Navigate form fields forwards using the Tab key.
58
+ focusNext: 'tab'
59
+ }
60
+ });
61
+ const classList = ['ck', 'ck-link-form', 'ck-responsive-form'];
62
+ if (linkCommand.manualDecorators.length) {
63
+ classList.push('ck-link-form_layout-vertical', 'ck-vertical-form');
64
+ }
65
+ this.setTemplate({
66
+ tag: 'form',
67
+ attributes: {
68
+ class: classList,
69
+ // https://github.com/ckeditor/ckeditor5-link/issues/90
70
+ tabindex: '-1'
71
+ },
72
+ children: this.children
73
+ });
74
+ }
75
+ /**
76
+ * Obtains the state of the {@link module:ui/button/switchbuttonview~SwitchButtonView switch buttons} representing
77
+ * {@link module:link/linkcommand~LinkCommand#manualDecorators manual link decorators}
78
+ * in the {@link module:link/ui/linkformview~LinkFormView}.
79
+ *
80
+ * @returns Key-value pairs, where the key is the name of the decorator and the value is its state.
81
+ */
82
+ getDecoratorSwitchesState() {
83
+ return Array
84
+ .from(this._manualDecoratorSwitches)
85
+ .reduce((accumulator, switchButton) => {
86
+ accumulator[switchButton.name] = switchButton.isOn;
87
+ return accumulator;
88
+ }, {});
89
+ }
90
+ /**
91
+ * @inheritDoc
92
+ */
93
+ render() {
94
+ super.render();
95
+ submitHandler({
96
+ view: this
97
+ });
98
+ const childViews = [
99
+ this.urlInputView,
100
+ ...this._manualDecoratorSwitches,
101
+ this.saveButtonView,
102
+ this.cancelButtonView
103
+ ];
104
+ childViews.forEach(v => {
105
+ // Register the view as focusable.
106
+ this._focusables.add(v);
107
+ // Register the view in the focus tracker.
108
+ this.focusTracker.add(v.element);
109
+ });
110
+ // Start listening for the keystrokes coming from #element.
111
+ this.keystrokes.listenTo(this.element);
112
+ }
113
+ /**
114
+ * @inheritDoc
115
+ */
116
+ destroy() {
117
+ super.destroy();
118
+ this.focusTracker.destroy();
119
+ this.keystrokes.destroy();
120
+ }
121
+ /**
122
+ * Focuses the fist {@link #_focusables} in the form.
123
+ */
124
+ focus() {
125
+ this._focusCycler.focusFirst();
126
+ }
127
+ /**
128
+ * Creates a labeled input view.
129
+ *
130
+ * @returns Labeled field view instance.
131
+ */
132
+ _createUrlInput() {
133
+ const t = this.locale.t;
134
+ const labeledInput = new LabeledFieldView(this.locale, createLabeledInputText);
135
+ labeledInput.label = t('Link URL');
136
+ return labeledInput;
137
+ }
138
+ /**
139
+ * Creates a button view.
140
+ *
141
+ * @param label The button label.
142
+ * @param icon The button icon.
143
+ * @param className The additional button CSS class name.
144
+ * @param eventName An event name that the `ButtonView#execute` event will be delegated to.
145
+ * @returns The button view instance.
146
+ */
147
+ _createButton(label, icon, className, eventName) {
148
+ const button = new ButtonView(this.locale);
149
+ button.set({
150
+ label,
151
+ icon,
152
+ tooltip: true
153
+ });
154
+ button.extendTemplate({
155
+ attributes: {
156
+ class: className
157
+ }
158
+ });
159
+ if (eventName) {
160
+ button.delegate('execute').to(this, eventName);
161
+ }
162
+ return button;
163
+ }
164
+ /**
165
+ * Populates {@link module:ui/viewcollection~ViewCollection} of {@link module:ui/button/switchbuttonview~SwitchButtonView}
166
+ * made based on {@link module:link/linkcommand~LinkCommand#manualDecorators}.
167
+ *
168
+ * @param linkCommand A reference to the link command.
169
+ * @returns ViewCollection of switch buttons.
170
+ */
171
+ _createManualDecoratorSwitches(linkCommand) {
172
+ const switches = this.createCollection();
173
+ for (const manualDecorator of linkCommand.manualDecorators) {
174
+ const switchButton = new SwitchButtonView(this.locale);
175
+ switchButton.set({
176
+ name: manualDecorator.id,
177
+ label: manualDecorator.label,
178
+ withText: true
179
+ });
180
+ switchButton.bind('isOn').toMany([manualDecorator, linkCommand], 'value', (decoratorValue, commandValue) => {
181
+ return commandValue === undefined && decoratorValue === undefined ? !!manualDecorator.defaultValue : !!decoratorValue;
182
+ });
183
+ switchButton.on('execute', () => {
184
+ manualDecorator.set('value', !switchButton.isOn);
185
+ });
186
+ switches.add(switchButton);
187
+ }
188
+ return switches;
189
+ }
190
+ /**
191
+ * Populates the {@link #children} collection of the form.
192
+ *
193
+ * If {@link module:link/linkcommand~LinkCommand#manualDecorators manual decorators} are configured in the editor, it creates an
194
+ * additional `View` wrapping all {@link #_manualDecoratorSwitches} switch buttons corresponding
195
+ * to these decorators.
196
+ *
197
+ * @param manualDecorators A reference to
198
+ * the collection of manual decorators stored in the link command.
199
+ * @returns The children of link form view.
200
+ */
201
+ _createFormChildren(manualDecorators) {
202
+ const children = this.createCollection();
203
+ children.add(this.urlInputView);
204
+ if (manualDecorators.length) {
205
+ const additionalButtonsView = new View();
206
+ additionalButtonsView.setTemplate({
207
+ tag: 'ul',
208
+ children: this._manualDecoratorSwitches.map(switchButton => ({
209
+ tag: 'li',
210
+ children: [switchButton],
211
+ attributes: {
212
+ class: [
213
+ 'ck',
214
+ 'ck-list__item'
215
+ ]
216
+ }
217
+ })),
218
+ attributes: {
219
+ class: [
220
+ 'ck',
221
+ 'ck-reset',
222
+ 'ck-list'
223
+ ]
224
+ }
225
+ });
226
+ children.add(additionalButtonsView);
227
+ }
228
+ children.add(this.saveButtonView);
229
+ children.add(this.cancelButtonView);
230
+ return children;
231
+ }
349
232
  }
350
-
351
- /**
352
- * Fired when the form view is submitted (when one of the children triggered the submit event),
353
- * for example with a click on {@link #saveButtonView}.
354
- *
355
- * @event submit
356
- */
357
-
358
- /**
359
- * Fired when the form view is canceled, for example with a click on {@link #cancelButtonView}.
360
- *
361
- * @event cancel
362
- */
@@ -0,0 +1,36 @@
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/unlinkcommand
7
+ */
8
+ import { Command } from 'ckeditor5/src/core';
9
+ /**
10
+ * The unlink command. It is used by the {@link module:link/link~Link link plugin}.
11
+ */
12
+ export default class UnlinkCommand extends Command {
13
+ /**
14
+ * @inheritDoc
15
+ */
16
+ refresh(): void;
17
+ /**
18
+ * Executes the command.
19
+ *
20
+ * When the selection is collapsed, it removes the `linkHref` attribute from each node with the same `linkHref` attribute value.
21
+ * When the selection is non-collapsed, it removes the `linkHref` attribute from each node in selected ranges.
22
+ *
23
+ * # Decorators
24
+ *
25
+ * If {@link module:link/link~LinkConfig#decorators `config.link.decorators`} is specified,
26
+ * all configured decorators are removed together with the `linkHref` attribute.
27
+ *
28
+ * @fires execute
29
+ */
30
+ execute(): void;
31
+ }
32
+ declare module '@ckeditor/ckeditor5-core' {
33
+ interface CommandsMap {
34
+ unlink: UnlinkCommand;
35
+ }
36
+ }