@ckeditor/ckeditor5-widget 36.0.0 → 37.0.0-alpha.0

Sign up to get free protection for your applications and to get access to all the features.
package/src/utils.js CHANGED
@@ -13,21 +13,14 @@ import { getTypeAroundFakeCaretPosition } from './widgettypearound/utils';
13
13
  import dragHandleIcon from '../theme/icons/drag-handle.svg';
14
14
  /**
15
15
  * CSS class added to each widget element.
16
- *
17
- * @const {String}
18
16
  */
19
17
  export const WIDGET_CLASS_NAME = 'ck-widget';
20
18
  /**
21
19
  * CSS class added to currently selected widget element.
22
- *
23
- * @const {String}
24
20
  */
25
21
  export const WIDGET_SELECTED_CLASS_NAME = 'ck-widget_selected';
26
22
  /**
27
23
  * Returns `true` if given {@link module:engine/view/node~Node} is an {@link module:engine/view/element~Element} and a widget.
28
- *
29
- * @param {module:engine/view/node~Node} node
30
- * @returns {Boolean}
31
24
  */
32
25
  export function isWidget(node) {
33
26
  if (!node.is('element')) {
@@ -52,34 +45,34 @@ export function isWidget(node) {
52
45
  * For example, in order to convert a `<widget>` model element to `<div class="widget">` in the view, you can define
53
46
  * such converters:
54
47
  *
55
- * editor.conversion.for( 'editingDowncast' )
56
- * .elementToElement( {
57
- * model: 'widget',
58
- * view: ( modelItem, { writer } ) => {
59
- * const div = writer.createContainerElement( 'div', { class: 'widget' } );
60
- *
61
- * return toWidget( div, writer, { label: 'some widget' } );
62
- * }
63
- * } );
64
- *
65
- * editor.conversion.for( 'dataDowncast' )
66
- * .elementToElement( {
67
- * model: 'widget',
68
- * view: ( modelItem, { writer } ) => {
69
- * return writer.createContainerElement( 'div', { class: 'widget' } );
70
- * }
71
- * } );
48
+ * ```ts
49
+ * editor.conversion.for( 'editingDowncast' )
50
+ * .elementToElement( {
51
+ * model: 'widget',
52
+ * view: ( modelItem, { writer } ) => {
53
+ * const div = writer.createContainerElement( 'div', { class: 'widget' } );
54
+ *
55
+ * return toWidget( div, writer, { label: 'some widget' } );
56
+ * }
57
+ * } );
58
+ *
59
+ * editor.conversion.for( 'dataDowncast' )
60
+ * .elementToElement( {
61
+ * model: 'widget',
62
+ * view: ( modelItem, { writer } ) => {
63
+ * return writer.createContainerElement( 'div', { class: 'widget' } );
64
+ * }
65
+ * } );
66
+ * ```
72
67
  *
73
68
  * See the full source code of the widget (with a nested editable) schema definition and converters in
74
69
  * [this sample](https://github.com/ckeditor/ckeditor5-widget/blob/master/tests/manual/widget-with-nestededitable.js).
75
70
  *
76
- * @param {module:engine/view/element~Element} element
77
- * @param {module:engine/view/downcastwriter~DowncastWriter} writer
78
- * @param {Object} [options={}]
79
- * @param {String|Function} [options.label] Element's label provided to the {@link ~setLabel} function. It can be passed as
71
+ * @param options Additional options.
72
+ * @param options.label Element's label provided to the {@link ~setLabel} function. It can be passed as
80
73
  * a plain string or a function returning a string. It represents the widget for assistive technologies (like screen readers).
81
- * @param {Boolean} [options.hasSelectionHandle=false] If `true`, the widget will have a selection handle added.
82
- * @returns {module:engine/view/element~Element} Returns the same element.
74
+ * @param options.hasSelectionHandle If `true`, the widget will have a selection handle added.
75
+ * @returns Returns the same element.
83
76
  */
84
77
  export function toWidget(element, writer, options = {}) {
85
78
  if (!element.is('containerElement')) {
@@ -88,7 +81,7 @@ export function toWidget(element, writer, options = {}) {
88
81
  * instance.
89
82
  *
90
83
  * @error widget-to-widget-wrong-element-type
91
- * @param {String} element The view element passed to `toWidget()`.
84
+ * @param element The view element passed to `toWidget()`.
92
85
  */
93
86
  throw new CKEditorError('widget-to-widget-wrong-element-type', null, { element });
94
87
  }
@@ -106,12 +99,10 @@ export function toWidget(element, writer, options = {}) {
106
99
  setHighlightHandling(element, writer);
107
100
  return element;
108
101
  }
109
- // Default handler for adding a highlight on a widget.
110
- // It adds CSS class and attributes basing on the given highlight descriptor.
111
- //
112
- // @param {module:engine/view/element~Element} element
113
- // @param {module:engine/conversion/downcasthelpers~HighlightDescriptor} descriptor
114
- // @param {module:engine/view/downcastwriter~DowncastWriter} writer
102
+ /**
103
+ * Default handler for adding a highlight on a widget.
104
+ * It adds CSS class and attributes basing on the given highlight descriptor.
105
+ */
115
106
  function addHighlight(element, descriptor, writer) {
116
107
  if (descriptor.classes) {
117
108
  writer.addClass(toArray(descriptor.classes), element);
@@ -122,12 +113,10 @@ function addHighlight(element, descriptor, writer) {
122
113
  }
123
114
  }
124
115
  }
125
- // Default handler for removing a highlight from a widget.
126
- // It removes CSS class and attributes basing on the given highlight descriptor.
127
- //
128
- // @param {module:engine/view/element~Element} element
129
- // @param {module:engine/conversion/downcasthelpers~HighlightDescriptor} descriptor
130
- // @param {module:engine/view/downcastwriter~DowncastWriter} writer
116
+ /**
117
+ * Default handler for removing a highlight from a widget.
118
+ * It removes CSS class and attributes basing on the given highlight descriptor.
119
+ */
131
120
  function removeHighlight(element, descriptor, writer) {
132
121
  if (descriptor.classes) {
133
122
  writer.removeClass(toArray(descriptor.classes), element);
@@ -141,11 +130,6 @@ function removeHighlight(element, descriptor, writer) {
141
130
  /**
142
131
  * Sets highlight handling methods. Uses {@link module:widget/highlightstack~HighlightStack} to
143
132
  * properly determine which highlight descriptor should be used at given time.
144
- *
145
- * @param {module:engine/view/element~Element} element
146
- * @param {module:engine/view/downcastwriter~DowncastWriter} writer
147
- * @param {Function} [add]
148
- * @param {Function} [remove]
149
133
  */
150
134
  export function setHighlightHandling(element, writer, add = addHighlight, remove = removeHighlight) {
151
135
  const stack = new HighlightStack();
@@ -166,9 +150,6 @@ export function setHighlightHandling(element, writer, add = addHighlight, remove
166
150
  * Sets label for given element.
167
151
  * It can be passed as a plain string or a function returning a string. Function will be called each time label is retrieved by
168
152
  * {@link ~getLabel `getLabel()`}.
169
- *
170
- * @param {module:engine/view/element~Element} element
171
- * @param {string|Function} labelOrCreator
172
153
  */
173
154
  export function setLabel(element, labelOrCreator) {
174
155
  const widgetLabel = element.getCustomProperty('widgetLabel');
@@ -176,9 +157,6 @@ export function setLabel(element, labelOrCreator) {
176
157
  }
177
158
  /**
178
159
  * Returns the label of the provided element.
179
- *
180
- * @param {module:engine/view/element~Element} element
181
- * @returns {String}
182
160
  */
183
161
  export function getLabel(element) {
184
162
  const widgetLabel = element.getCustomProperty('widgetLabel');
@@ -206,32 +184,32 @@ export function getLabel(element) {
206
184
  * For example, in order to convert a `<nested>` model element to `<div class="nested">` in the view, you can define
207
185
  * such converters:
208
186
  *
209
- * editor.conversion.for( 'editingDowncast' )
210
- * .elementToElement( {
211
- * model: 'nested',
212
- * view: ( modelItem, { writer } ) => {
213
- * const div = writer.createEditableElement( 'div', { class: 'nested' } );
214
- *
215
- * return toWidgetEditable( nested, writer, { label: 'label for editable' } );
216
- * }
217
- * } );
218
- *
219
- * editor.conversion.for( 'dataDowncast' )
220
- * .elementToElement( {
221
- * model: 'nested',
222
- * view: ( modelItem, { writer } ) => {
223
- * return writer.createContainerElement( 'div', { class: 'nested' } );
224
- * }
225
- * } );
187
+ * ```ts
188
+ * editor.conversion.for( 'editingDowncast' )
189
+ * .elementToElement( {
190
+ * model: 'nested',
191
+ * view: ( modelItem, { writer } ) => {
192
+ * const div = writer.createEditableElement( 'div', { class: 'nested' } );
193
+ *
194
+ * return toWidgetEditable( nested, writer, { label: 'label for editable' } );
195
+ * }
196
+ * } );
197
+ *
198
+ * editor.conversion.for( 'dataDowncast' )
199
+ * .elementToElement( {
200
+ * model: 'nested',
201
+ * view: ( modelItem, { writer } ) => {
202
+ * return writer.createContainerElement( 'div', { class: 'nested' } );
203
+ * }
204
+ * } );
205
+ * ```
226
206
  *
227
207
  * See the full source code of the widget (with nested editable) schema definition and converters in
228
208
  * [this sample](https://github.com/ckeditor/ckeditor5-widget/blob/master/tests/manual/widget-with-nestededitable.js).
229
209
  *
230
- * @param {module:engine/view/editableelement~EditableElement} editable
231
- * @param {module:engine/view/downcastwriter~DowncastWriter} writer
232
- * @param {Object} [options] Additional options.
233
- * @param {String} [options.label] Editable's label used by assistive technologies (e.g. screen readers).
234
- * @returns {module:engine/view/editableelement~EditableElement} Returns the same element that was provided in the `editable` parameter
210
+ * @param options Additional options.
211
+ * @param options.label Editable's label used by assistive technologies (e.g. screen readers).
212
+ * @returns Returns the same element that was provided in the `editable` parameter
235
213
  */
236
214
  export function toWidgetEditable(editable, writer, options = {}) {
237
215
  writer.addClass(['ck-editor__editable', 'ck-editor__nested-editable'], editable);
@@ -267,10 +245,9 @@ export function toWidgetEditable(editable, writer, options = {}) {
267
245
  * is then passed to {@link module:engine/model/model~Model#insertContent}, the block will be fully replaced
268
246
  * by the inserted widget block.
269
247
  *
270
- * @param {module:engine/model/selection~Selection|module:engine/model/documentselection~DocumentSelection} selection
271
- * The selection based on which the insertion position should be calculated.
272
- * @param {module:engine/model/model~Model} model Model instance.
273
- * @returns {module:engine/model/range~Range} The optimal range.
248
+ * @param selection The selection based on which the insertion position should be calculated.
249
+ * @param model Model instance.
250
+ * @returns The optimal range.
274
251
  */
275
252
  export function findOptimalInsertionRange(selection, model) {
276
253
  const selectedElement = selection.getSelectedElement();
@@ -290,42 +267,49 @@ export function findOptimalInsertionRange(selection, model) {
290
267
  *
291
268
  * For example:
292
269
  *
293
- * // Model:
294
- * <placeholder type="name"></placeholder>
270
+ * ```
271
+ * // Model:
272
+ * <placeholder type="name"></placeholder>
295
273
  *
296
- * // View:
297
- * <span class="placeholder">name</span>
274
+ * // View:
275
+ * <span class="placeholder">name</span>
276
+ * ```
298
277
  *
299
- * In such case, view positions inside `<span>` cannot be correct mapped to the model (because the model element is empty).
278
+ * In such case, view positions inside `<span>` cannot be correctly mapped to the model (because the model element is empty).
300
279
  * To handle mapping positions inside `<span class="placeholder">` to the model use this util as follows:
301
280
  *
302
- * editor.editing.mapper.on(
303
- * 'viewToModelPosition',
304
- * viewToModelPositionOutsideModelElement( model, viewElement => viewElement.hasClass( 'placeholder' ) )
305
- * );
281
+ * ```ts
282
+ * editor.editing.mapper.on(
283
+ * 'viewToModelPosition',
284
+ * viewToModelPositionOutsideModelElement( model, viewElement => viewElement.hasClass( 'placeholder' ) )
285
+ * );
286
+ * ```
306
287
  *
307
288
  * The callback will try to map the view offset of selection to an expected model position.
308
289
  *
309
290
  * 1. When the position is at the end (or in the middle) of the inline widget:
310
291
  *
311
- * // View:
312
- * <p>foo <span class="placeholder">name|</span> bar</p>
292
+ * ```
293
+ * // View:
294
+ * <p>foo <span class="placeholder">name|</span> bar</p>
313
295
  *
314
- * // Model:
315
- * <paragraph>foo <placeholder type="name"></placeholder>| bar</paragraph>
296
+ * // Model:
297
+ * <paragraph>foo <placeholder type="name"></placeholder>| bar</paragraph>
298
+ * ```
316
299
  *
317
300
  * 2. When the position is at the beginning of the inline widget:
318
301
  *
319
- * // View:
320
- * <p>foo <span class="placeholder">|name</span> bar</p>
302
+ * ```
303
+ * // View:
304
+ * <p>foo <span class="placeholder">|name</span> bar</p>
321
305
  *
322
- * // Model:
323
- * <paragraph>foo |<placeholder type="name"></placeholder> bar</paragraph>
306
+ * // Model:
307
+ * <paragraph>foo |<placeholder type="name"></placeholder> bar</paragraph>
308
+ * ```
324
309
  *
325
- * @param {module:engine/model/model~Model} model Model instance on which the callback operates.
326
- * @param {Function} viewElementMatcher Function that is passed a view element and should return `true` if the custom mapping
310
+ * @param model Model instance on which the callback operates.
311
+ * @param viewElementMatcher Function that is passed a view element and should return `true` if the custom mapping
327
312
  * should be applied to the given view element.
328
- * @return {Function}
329
313
  */
330
314
  export function viewToModelPositionOutsideModelElement(model, viewElementMatcher) {
331
315
  return (evt, data) => {
@@ -338,16 +322,15 @@ export function viewToModelPositionOutsideModelElement(model, viewElementMatcher
338
322
  data.modelPosition = model.createPositionAt(modelParent, viewPosition.isAtStart ? 'before' : 'after');
339
323
  };
340
324
  }
341
- // Default filler offset function applied to all widget elements.
342
- //
343
- // @returns {null}
325
+ /**
326
+ * Default filler offset function applied to all widget elements.
327
+ */
344
328
  function getFillerOffset() {
345
329
  return null;
346
330
  }
347
- // Adds a drag handle to the widget.
348
- //
349
- // @param {module:engine/view/containerelement~ContainerElement}
350
- // @param {module:engine/view/downcastwriter~DowncastWriter} writer
331
+ /**
332
+ * Adds a drag handle to the widget.
333
+ */
351
334
  function addSelectionHandle(widgetElement, writer) {
352
335
  const selectionHandle = writer.createUIElement('div', { class: 'ck ck-widget__selection-handle' }, function (domDocument) {
353
336
  const domElement = this.toDomElement(domDocument);
@@ -0,0 +1,15 @@
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 widget/verticalnavigationhandler
7
+ */
8
+ import { type GetCallback } from '@ckeditor/ckeditor5-utils';
9
+ import type { EditingController, ViewDocumentArrowKeyEvent } from '@ckeditor/ckeditor5-engine';
10
+ /**
11
+ * Returns 'keydown' handler for up/down arrow keys that modifies the caret movement if it's in a text line next to an object.
12
+ *
13
+ * @param editing The editing controller.
14
+ */
15
+ export default function verticalNavigationHandler(editing: EditingController): GetCallback<ViewDocumentArrowKeyEvent>;
@@ -2,15 +2,14 @@
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
- import { keyCodes, Rect } from '@ckeditor/ckeditor5-utils';
6
5
  /**
7
6
  * @module widget/verticalnavigationhandler
8
7
  */
8
+ import { keyCodes, Rect } from '@ckeditor/ckeditor5-utils';
9
9
  /**
10
10
  * Returns 'keydown' handler for up/down arrow keys that modifies the caret movement if it's in a text line next to an object.
11
11
  *
12
- * @param {module:engine/controller/editingcontroller~EditingController} editing The editing controller.
13
- * @returns {Function}
12
+ * @param editing The editing controller.
14
13
  */
15
14
  export default function verticalNavigationHandler(editing) {
16
15
  const model = editing.model;
@@ -67,16 +66,16 @@ export default function verticalNavigationHandler(editing) {
67
66
  }
68
67
  };
69
68
  }
70
- // Finds the range between selection and closest limit element (in the direction of navigation).
71
- // The position next to limit element is adjusted to the closest allowed `$text` position.
72
- //
73
- // Returns `null` if, according to the schema, the resulting range cannot contain a `$text` element.
74
- //
75
- // @param {module:engine/controller/editingcontroller~EditingController} editing The editing controller.
76
- // @param {module:engine/model/selection~Selection} selection The current selection.
77
- // @param {Boolean} isForward The expected navigation direction.
78
- // @returns {module:engine/model/range~Range|null}
79
- //
69
+ /**
70
+ * Finds the range between selection and closest limit element (in the direction of navigation).
71
+ * The position next to limit element is adjusted to the closest allowed `$text` position.
72
+ *
73
+ * Returns `null` if, according to the schema, the resulting range cannot contain a `$text` element.
74
+ *
75
+ * @param editing The editing controller.
76
+ * @param selection The current selection.
77
+ * @param isForward The expected navigation direction.
78
+ */
80
79
  function findTextRangeFromSelection(editing, selection, isForward) {
81
80
  const model = editing.model;
82
81
  if (isForward) {
@@ -108,13 +107,11 @@ function findTextRangeFromSelection(editing, selection, isForward) {
108
107
  return null;
109
108
  }
110
109
  }
111
- // Finds the limit element position that is closest to startPosition.
112
- //
113
- // @param {module:engine/model/model~Model} model
114
- // @param {<module:engine/model/position~Position>} startPosition
115
- // @param {'forward'|'backward'} direction Search direction.
116
- // @returns {<module:engine/model/position~Position>|null}
117
- //
110
+ /**
111
+ * Finds the limit element position that is closest to startPosition.
112
+ *
113
+ * @param direction Search direction.
114
+ */
118
115
  function getNearestNonInlineLimit(model, startPosition, direction) {
119
116
  const schema = model.schema;
120
117
  const range = model.createRangeIn(startPosition.root);
@@ -130,14 +127,16 @@ function getNearestNonInlineLimit(model, startPosition, direction) {
130
127
  }
131
128
  return null;
132
129
  }
133
- // Basing on the provided range, finds the first or last (depending on `direction`) position inside the range
134
- // that can contain `$text` (according to schema).
135
- //
136
- // @param {module:engine/model/schema~Schema} schema The schema.
137
- // @param {module:engine/model/range~Range} range The range to find the position in.
138
- // @param {'forward'|'backward'} direction Search direction.
139
- // @returns {module:engine/model/position~Position|null} The nearest selection position.
140
- //
130
+ /**
131
+ * Basing on the provided range, finds the first or last (depending on `direction`) position inside the range
132
+ * that can contain `$text` (according to schema).
133
+ *
134
+ * @param schema The schema.
135
+ * @param range The range to find the position in.
136
+ * @param direction Search direction.
137
+ * @returns The nearest selection position.
138
+ *
139
+ */
141
140
  function getNearestTextPosition(schema, range, direction) {
142
141
  const position = direction == 'backward' ? range.end : range.start;
143
142
  if (schema.checkChild(position, '$text')) {
@@ -150,14 +149,14 @@ function getNearestTextPosition(schema, range, direction) {
150
149
  }
151
150
  return null;
152
151
  }
153
- // Checks if the DOM range corresponding to the provided model range renders as a single line by analyzing DOMRects
154
- // (verifying if they visually wrap content to the next line).
155
- //
156
- // @param {module:engine/controller/editingcontroller~EditingController} editing The editing controller.
157
- // @param {module:engine/model/range~Range} modelRange The current table cell content range.
158
- // @param {Boolean} isForward The expected navigation direction.
159
- // @returns {Boolean}
160
- //
152
+ /**
153
+ * Checks if the DOM range corresponding to the provided model range renders as a single line by analyzing DOMRects
154
+ * (verifying if they visually wrap content to the next line).
155
+ *
156
+ * @param editing The editing controller.
157
+ * @param modelRange The current table cell content range.
158
+ * @param isForward The expected navigation direction.
159
+ */
161
160
  function isSingleLineRange(editing, modelRange, isForward) {
162
161
  const model = editing.model;
163
162
  const domConverter = editing.view.domConverter;
@@ -0,0 +1,94 @@
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 widget/widget
7
+ */
8
+ import { Plugin, type PluginDependencies } from '@ckeditor/ckeditor5-core';
9
+ import { type Element, type Node } from '@ckeditor/ckeditor5-engine';
10
+ import '../theme/widget.css';
11
+ /**
12
+ * The widget plugin. It enables base support for widgets.
13
+ *
14
+ * See {@glink api/widget package page} for more details and documentation.
15
+ *
16
+ * This plugin enables multiple behaviors required by widgets:
17
+ *
18
+ * * The model to view selection converter for the editing pipeline (it handles widget custom selection rendering).
19
+ * If a converted selection wraps around a widget element, that selection is marked as
20
+ * {@link module:engine/view/selection~Selection#isFake fake}. Additionally, the `ck-widget_selected` CSS class
21
+ * is added to indicate that widget has been selected.
22
+ * * The mouse and keyboard events handling on and around widget elements.
23
+ */
24
+ export default class Widget extends Plugin {
25
+ /**
26
+ * Holds previously selected widgets.
27
+ */
28
+ private _previouslySelected;
29
+ /**
30
+ * @inheritDoc
31
+ */
32
+ static get pluginName(): 'Widget';
33
+ /**
34
+ * @inheritDoc
35
+ */
36
+ static get requires(): PluginDependencies;
37
+ /**
38
+ * @inheritDoc
39
+ */
40
+ init(): void;
41
+ /**
42
+ * Handles {@link module:engine/view/document~Document#event:mousedown mousedown} events on widget elements.
43
+ */
44
+ private _onMousedown;
45
+ /**
46
+ * Handles {@link module:engine/view/document~Document#event:keydown keydown} events and changes
47
+ * the model selection when:
48
+ *
49
+ * * arrow key is pressed when the widget is selected,
50
+ * * the selection is next to a widget and the widget should become selected upon the arrow key press.
51
+ *
52
+ * See {@link #_preventDefaultOnArrowKeyPress}.
53
+ */
54
+ private _handleSelectionChangeOnArrowKeyPress;
55
+ /**
56
+ * Handles {@link module:engine/view/document~Document#event:keydown keydown} events and prevents
57
+ * the default browser behavior to make sure the fake selection is not being moved from a fake selection
58
+ * container.
59
+ *
60
+ * See {@link #_handleSelectionChangeOnArrowKeyPress}.
61
+ */
62
+ private _preventDefaultOnArrowKeyPress;
63
+ /**
64
+ * Handles delete keys: backspace and delete.
65
+ *
66
+ * @param isForward Set to true if delete was performed in forward direction.
67
+ * @returns Returns `true` if keys were handled correctly.
68
+ */
69
+ private _handleDelete;
70
+ /**
71
+ * Sets {@link module:engine/model/selection~Selection document's selection} over given element.
72
+ *
73
+ * @internal
74
+ */
75
+ _setSelectionOverElement(element: Node): void;
76
+ /**
77
+ * Checks if {@link module:engine/model/element~Element element} placed next to the current
78
+ * {@link module:engine/model/selection~Selection model selection} exists and is marked in
79
+ * {@link module:engine/model/schema~Schema schema} as `object`.
80
+ *
81
+ * @internal
82
+ * @param forward Direction of checking.
83
+ */
84
+ _getObjectElementNextToSelection(forward: boolean): Element | null;
85
+ /**
86
+ * Removes CSS class from previously selected widgets.
87
+ */
88
+ private _clearPreviouslySelectedWidgets;
89
+ }
90
+ declare module '@ckeditor/ckeditor5-core' {
91
+ interface PluginsMap {
92
+ [Widget.pluginName]: Widget;
93
+ }
94
+ }