@ckeditor/ckeditor5-widget 39.0.1 → 40.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. package/CHANGELOG.md +1 -1
  2. package/LICENSE.md +1 -1
  3. package/README.md +3 -3
  4. package/lang/translations/ar.po +1 -0
  5. package/lang/translations/az.po +1 -0
  6. package/lang/translations/bg.po +1 -0
  7. package/lang/translations/bn.po +1 -0
  8. package/lang/translations/ca.po +1 -0
  9. package/lang/translations/cs.po +1 -0
  10. package/lang/translations/da.po +1 -0
  11. package/lang/translations/de-ch.po +1 -0
  12. package/lang/translations/de.po +1 -0
  13. package/lang/translations/el.po +1 -0
  14. package/lang/translations/en-au.po +1 -0
  15. package/lang/translations/en.po +1 -0
  16. package/lang/translations/es.po +1 -0
  17. package/lang/translations/et.po +1 -0
  18. package/lang/translations/fa.po +1 -0
  19. package/lang/translations/fi.po +1 -0
  20. package/lang/translations/fr.po +1 -0
  21. package/lang/translations/gl.po +1 -0
  22. package/lang/translations/he.po +1 -0
  23. package/lang/translations/hi.po +1 -0
  24. package/lang/translations/hr.po +1 -0
  25. package/lang/translations/hu.po +1 -0
  26. package/lang/translations/id.po +1 -0
  27. package/lang/translations/it.po +1 -0
  28. package/lang/translations/ja.po +1 -0
  29. package/lang/translations/ko.po +1 -0
  30. package/lang/translations/ku.po +1 -0
  31. package/lang/translations/lt.po +1 -0
  32. package/lang/translations/lv.po +1 -0
  33. package/lang/translations/ms.po +1 -0
  34. package/lang/translations/nl.po +1 -0
  35. package/lang/translations/no.po +1 -0
  36. package/lang/translations/pl.po +1 -0
  37. package/lang/translations/pt-br.po +1 -0
  38. package/lang/translations/pt.po +1 -0
  39. package/lang/translations/ro.po +1 -0
  40. package/lang/translations/ru.po +1 -0
  41. package/lang/translations/sk.po +1 -0
  42. package/lang/translations/sq.po +1 -0
  43. package/lang/translations/sr-latn.po +1 -0
  44. package/lang/translations/sr.po +1 -0
  45. package/lang/translations/sv.po +1 -0
  46. package/lang/translations/th.po +1 -0
  47. package/lang/translations/tk.po +1 -0
  48. package/lang/translations/tr.po +1 -0
  49. package/lang/translations/uk.po +1 -0
  50. package/lang/translations/ur.po +1 -0
  51. package/lang/translations/uz.po +1 -0
  52. package/lang/translations/vi.po +1 -0
  53. package/lang/translations/zh-cn.po +1 -0
  54. package/lang/translations/zh.po +1 -0
  55. package/package.json +7 -11
  56. package/src/augmentation.d.ts +13 -13
  57. package/src/augmentation.js +5 -5
  58. package/src/highlightstack.d.ts +74 -74
  59. package/src/highlightstack.js +129 -129
  60. package/src/index.d.ts +13 -13
  61. package/src/index.js +13 -13
  62. package/src/utils.d.ts +198 -198
  63. package/src/utils.js +348 -348
  64. package/src/verticalnavigation.d.ts +15 -15
  65. package/src/verticalnavigation.js +196 -196
  66. package/src/widget.d.ts +91 -91
  67. package/src/widget.js +380 -380
  68. package/src/widgetresize/resizer.d.ts +177 -177
  69. package/src/widgetresize/resizer.js +372 -372
  70. package/src/widgetresize/resizerstate.d.ts +125 -125
  71. package/src/widgetresize/resizerstate.js +150 -150
  72. package/src/widgetresize/sizeview.d.ts +55 -55
  73. package/src/widgetresize/sizeview.js +63 -63
  74. package/src/widgetresize.d.ts +125 -125
  75. package/src/widgetresize.js +188 -188
  76. package/src/widgettoolbarrepository.d.ts +94 -94
  77. package/src/widgettoolbarrepository.js +268 -268
  78. package/src/widgettypearound/utils.d.ts +38 -38
  79. package/src/widgettypearound/utils.js +52 -52
  80. package/src/widgettypearound/widgettypearound.d.ts +229 -229
  81. package/src/widgettypearound/widgettypearound.js +773 -773
@@ -1,268 +1,268 @@
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/widgettoolbarrepository
7
- */
8
- import { Plugin } from '@ckeditor/ckeditor5-core';
9
- import { BalloonPanelView, ContextualBalloon, ToolbarView } from '@ckeditor/ckeditor5-ui';
10
- import { CKEditorError, logWarning } from '@ckeditor/ckeditor5-utils';
11
- import { isWidget } from './utils';
12
- /**
13
- * Widget toolbar repository plugin. A central point for registering widget toolbars. This plugin handles the whole
14
- * toolbar rendering process and exposes a concise API.
15
- *
16
- * To add a toolbar for your widget use the {@link ~WidgetToolbarRepository#register `WidgetToolbarRepository#register()`} method.
17
- *
18
- * The following example comes from the {@link module:image/imagetoolbar~ImageToolbar} plugin:
19
- *
20
- * ```ts
21
- * class ImageToolbar extends Plugin {
22
- * static get requires() {
23
- * return [ WidgetToolbarRepository ];
24
- * }
25
- *
26
- * afterInit() {
27
- * const editor = this.editor;
28
- * const widgetToolbarRepository = editor.plugins.get( WidgetToolbarRepository );
29
- *
30
- * widgetToolbarRepository.register( 'image', {
31
- * items: editor.config.get( 'image.toolbar' ),
32
- * getRelatedElement: getClosestSelectedImageWidget
33
- * } );
34
- * }
35
- * }
36
- * ```
37
- */
38
- export default class WidgetToolbarRepository extends Plugin {
39
- constructor() {
40
- super(...arguments);
41
- /**
42
- * A map of toolbar definitions.
43
- */
44
- this._toolbarDefinitions = new Map();
45
- }
46
- /**
47
- * @inheritDoc
48
- */
49
- static get requires() {
50
- return [ContextualBalloon];
51
- }
52
- /**
53
- * @inheritDoc
54
- */
55
- static get pluginName() {
56
- return 'WidgetToolbarRepository';
57
- }
58
- /**
59
- * @inheritDoc
60
- */
61
- init() {
62
- const editor = this.editor;
63
- // Disables the default balloon toolbar for all widgets.
64
- if (editor.plugins.has('BalloonToolbar')) {
65
- const balloonToolbar = editor.plugins.get('BalloonToolbar');
66
- this.listenTo(balloonToolbar, 'show', evt => {
67
- if (isWidgetSelected(editor.editing.view.document.selection)) {
68
- evt.stop();
69
- }
70
- }, { priority: 'high' });
71
- }
72
- this._balloon = this.editor.plugins.get('ContextualBalloon');
73
- this.on('change:isEnabled', () => {
74
- this._updateToolbarsVisibility();
75
- });
76
- this.listenTo(editor.ui, 'update', () => {
77
- this._updateToolbarsVisibility();
78
- });
79
- // UI#update is not fired after focus is back in editor, we need to check if balloon panel should be visible.
80
- this.listenTo(editor.ui.focusTracker, 'change:isFocused', () => {
81
- this._updateToolbarsVisibility();
82
- }, { priority: 'low' });
83
- }
84
- destroy() {
85
- super.destroy();
86
- for (const toolbarConfig of this._toolbarDefinitions.values()) {
87
- toolbarConfig.view.destroy();
88
- }
89
- }
90
- /**
91
- * Registers toolbar in the WidgetToolbarRepository. It renders it in the `ContextualBalloon` based on the value of the invoked
92
- * `getRelatedElement` function. Toolbar items are gathered from `items` array.
93
- * The balloon's CSS class is by default `ck-toolbar-container` and may be override with the `balloonClassName` option.
94
- *
95
- * Note: This method should be called in the {@link module:core/plugin~PluginInterface#afterInit `Plugin#afterInit()`}
96
- * callback (or later) to make sure that the given toolbar items were already registered by other plugins.
97
- *
98
- * @param toolbarId An id for the toolbar. Used to
99
- * @param options.ariaLabel Label used by assistive technologies to describe this toolbar element.
100
- * @param options.items Array of toolbar items.
101
- * @param options.getRelatedElement Callback which returns an element the toolbar should be attached to.
102
- * @param options.balloonClassName CSS class for the widget balloon.
103
- */
104
- register(toolbarId, { ariaLabel, items, getRelatedElement, balloonClassName = 'ck-toolbar-container' }) {
105
- // Trying to register a toolbar without any item.
106
- if (!items.length) {
107
- /**
108
- * When {@link module:widget/widgettoolbarrepository~WidgetToolbarRepository#register registering} a new widget toolbar, you
109
- * need to provide a non-empty array with the items that will be inserted into the toolbar.
110
- *
111
- * If you see this error when integrating the editor, you likely forgot to configure one of the widget toolbars.
112
- *
113
- * See for instance:
114
- *
115
- * * {@link module:table/tableconfig~TableConfig#contentToolbar `config.table.contentToolbar`}
116
- * * {@link module:image/imageconfig~ImageConfig#toolbar `config.image.toolbar`}
117
- *
118
- * @error widget-toolbar-no-items
119
- * @param toolbarId The id of the toolbar that has not been configured correctly.
120
- */
121
- logWarning('widget-toolbar-no-items', { toolbarId });
122
- return;
123
- }
124
- const editor = this.editor;
125
- const t = editor.t;
126
- const toolbarView = new ToolbarView(editor.locale);
127
- toolbarView.ariaLabel = ariaLabel || t('Widget toolbar');
128
- if (this._toolbarDefinitions.has(toolbarId)) {
129
- /**
130
- * Toolbar with the given id was already added.
131
- *
132
- * @error widget-toolbar-duplicated
133
- * @param toolbarId Toolbar id.
134
- */
135
- throw new CKEditorError('widget-toolbar-duplicated', this, { toolbarId });
136
- }
137
- const toolbarDefinition = {
138
- view: toolbarView,
139
- getRelatedElement,
140
- balloonClassName,
141
- itemsConfig: items,
142
- initialized: false
143
- };
144
- // Register the toolbar so it becomes available for Alt+F10 and Esc navigation.
145
- editor.ui.addToolbar(toolbarView, {
146
- isContextual: true,
147
- beforeFocus: () => {
148
- const relatedElement = getRelatedElement(editor.editing.view.document.selection);
149
- if (relatedElement) {
150
- this._showToolbar(toolbarDefinition, relatedElement);
151
- }
152
- },
153
- afterBlur: () => {
154
- this._hideToolbar(toolbarDefinition);
155
- }
156
- });
157
- this._toolbarDefinitions.set(toolbarId, toolbarDefinition);
158
- }
159
- /**
160
- * Iterates over stored toolbars and makes them visible or hidden.
161
- */
162
- _updateToolbarsVisibility() {
163
- let maxRelatedElementDepth = 0;
164
- let deepestRelatedElement = null;
165
- let deepestToolbarDefinition = null;
166
- for (const definition of this._toolbarDefinitions.values()) {
167
- const relatedElement = definition.getRelatedElement(this.editor.editing.view.document.selection);
168
- if (!this.isEnabled || !relatedElement) {
169
- if (this._isToolbarInBalloon(definition)) {
170
- this._hideToolbar(definition);
171
- }
172
- }
173
- else if (!this.editor.ui.focusTracker.isFocused) {
174
- if (this._isToolbarVisible(definition)) {
175
- this._hideToolbar(definition);
176
- }
177
- }
178
- else {
179
- const relatedElementDepth = relatedElement.getAncestors().length;
180
- // Many toolbars can express willingness to be displayed but they do not know about
181
- // each other. Figure out which toolbar is deepest in the view tree to decide which
182
- // should be displayed. For instance, if a selected image is inside a table cell, display
183
- // the ImageToolbar rather than the TableToolbar (#60).
184
- if (relatedElementDepth > maxRelatedElementDepth) {
185
- maxRelatedElementDepth = relatedElementDepth;
186
- deepestRelatedElement = relatedElement;
187
- deepestToolbarDefinition = definition;
188
- }
189
- }
190
- }
191
- if (deepestToolbarDefinition) {
192
- this._showToolbar(deepestToolbarDefinition, deepestRelatedElement);
193
- }
194
- }
195
- /**
196
- * Hides the given toolbar.
197
- */
198
- _hideToolbar(toolbarDefinition) {
199
- this._balloon.remove(toolbarDefinition.view);
200
- this.stopListening(this._balloon, 'change:visibleView');
201
- }
202
- /**
203
- * Shows up the toolbar if the toolbar is not visible.
204
- * Otherwise, repositions the toolbar's balloon when toolbar's view is the most top view in balloon stack.
205
- *
206
- * It might happen here that the toolbar's view is under another view. Then do nothing as the other toolbar view
207
- * should be still visible after the {@link module:ui/editorui/editorui~EditorUI#event:update}.
208
- */
209
- _showToolbar(toolbarDefinition, relatedElement) {
210
- if (this._isToolbarVisible(toolbarDefinition)) {
211
- repositionContextualBalloon(this.editor, relatedElement);
212
- }
213
- else if (!this._isToolbarInBalloon(toolbarDefinition)) {
214
- if (!toolbarDefinition.initialized) {
215
- toolbarDefinition.initialized = true;
216
- toolbarDefinition.view.fillFromConfig(toolbarDefinition.itemsConfig, this.editor.ui.componentFactory);
217
- }
218
- this._balloon.add({
219
- view: toolbarDefinition.view,
220
- position: getBalloonPositionData(this.editor, relatedElement),
221
- balloonClassName: toolbarDefinition.balloonClassName
222
- });
223
- // Update toolbar position each time stack with toolbar view is switched to visible.
224
- // This is in a case target element has changed when toolbar was in invisible stack
225
- // e.g. target image was wrapped by a block quote.
226
- // See https://github.com/ckeditor/ckeditor5-widget/issues/92.
227
- this.listenTo(this._balloon, 'change:visibleView', () => {
228
- for (const definition of this._toolbarDefinitions.values()) {
229
- if (this._isToolbarVisible(definition)) {
230
- const relatedElement = definition.getRelatedElement(this.editor.editing.view.document.selection);
231
- repositionContextualBalloon(this.editor, relatedElement);
232
- }
233
- }
234
- });
235
- }
236
- }
237
- _isToolbarVisible(toolbar) {
238
- return this._balloon.visibleView === toolbar.view;
239
- }
240
- _isToolbarInBalloon(toolbar) {
241
- return this._balloon.hasView(toolbar.view);
242
- }
243
- }
244
- function repositionContextualBalloon(editor, relatedElement) {
245
- const balloon = editor.plugins.get('ContextualBalloon');
246
- const position = getBalloonPositionData(editor, relatedElement);
247
- balloon.updatePosition(position);
248
- }
249
- function getBalloonPositionData(editor, relatedElement) {
250
- const editingView = editor.editing.view;
251
- const defaultPositions = BalloonPanelView.defaultPositions;
252
- return {
253
- target: editingView.domConverter.mapViewToDom(relatedElement),
254
- positions: [
255
- defaultPositions.northArrowSouth,
256
- defaultPositions.northArrowSouthWest,
257
- defaultPositions.northArrowSouthEast,
258
- defaultPositions.southArrowNorth,
259
- defaultPositions.southArrowNorthWest,
260
- defaultPositions.southArrowNorthEast,
261
- defaultPositions.viewportStickyNorth
262
- ]
263
- };
264
- }
265
- function isWidgetSelected(selection) {
266
- const viewElement = selection.getSelectedElement();
267
- return !!(viewElement && isWidget(viewElement));
268
- }
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/widgettoolbarrepository
7
+ */
8
+ import { Plugin } from '@ckeditor/ckeditor5-core';
9
+ import { BalloonPanelView, ContextualBalloon, ToolbarView } from '@ckeditor/ckeditor5-ui';
10
+ import { CKEditorError, logWarning } from '@ckeditor/ckeditor5-utils';
11
+ import { isWidget } from './utils';
12
+ /**
13
+ * Widget toolbar repository plugin. A central point for registering widget toolbars. This plugin handles the whole
14
+ * toolbar rendering process and exposes a concise API.
15
+ *
16
+ * To add a toolbar for your widget use the {@link ~WidgetToolbarRepository#register `WidgetToolbarRepository#register()`} method.
17
+ *
18
+ * The following example comes from the {@link module:image/imagetoolbar~ImageToolbar} plugin:
19
+ *
20
+ * ```ts
21
+ * class ImageToolbar extends Plugin {
22
+ * static get requires() {
23
+ * return [ WidgetToolbarRepository ];
24
+ * }
25
+ *
26
+ * afterInit() {
27
+ * const editor = this.editor;
28
+ * const widgetToolbarRepository = editor.plugins.get( WidgetToolbarRepository );
29
+ *
30
+ * widgetToolbarRepository.register( 'image', {
31
+ * items: editor.config.get( 'image.toolbar' ),
32
+ * getRelatedElement: getClosestSelectedImageWidget
33
+ * } );
34
+ * }
35
+ * }
36
+ * ```
37
+ */
38
+ export default class WidgetToolbarRepository extends Plugin {
39
+ constructor() {
40
+ super(...arguments);
41
+ /**
42
+ * A map of toolbar definitions.
43
+ */
44
+ this._toolbarDefinitions = new Map();
45
+ }
46
+ /**
47
+ * @inheritDoc
48
+ */
49
+ static get requires() {
50
+ return [ContextualBalloon];
51
+ }
52
+ /**
53
+ * @inheritDoc
54
+ */
55
+ static get pluginName() {
56
+ return 'WidgetToolbarRepository';
57
+ }
58
+ /**
59
+ * @inheritDoc
60
+ */
61
+ init() {
62
+ const editor = this.editor;
63
+ // Disables the default balloon toolbar for all widgets.
64
+ if (editor.plugins.has('BalloonToolbar')) {
65
+ const balloonToolbar = editor.plugins.get('BalloonToolbar');
66
+ this.listenTo(balloonToolbar, 'show', evt => {
67
+ if (isWidgetSelected(editor.editing.view.document.selection)) {
68
+ evt.stop();
69
+ }
70
+ }, { priority: 'high' });
71
+ }
72
+ this._balloon = this.editor.plugins.get('ContextualBalloon');
73
+ this.on('change:isEnabled', () => {
74
+ this._updateToolbarsVisibility();
75
+ });
76
+ this.listenTo(editor.ui, 'update', () => {
77
+ this._updateToolbarsVisibility();
78
+ });
79
+ // UI#update is not fired after focus is back in editor, we need to check if balloon panel should be visible.
80
+ this.listenTo(editor.ui.focusTracker, 'change:isFocused', () => {
81
+ this._updateToolbarsVisibility();
82
+ }, { priority: 'low' });
83
+ }
84
+ destroy() {
85
+ super.destroy();
86
+ for (const toolbarConfig of this._toolbarDefinitions.values()) {
87
+ toolbarConfig.view.destroy();
88
+ }
89
+ }
90
+ /**
91
+ * Registers toolbar in the WidgetToolbarRepository. It renders it in the `ContextualBalloon` based on the value of the invoked
92
+ * `getRelatedElement` function. Toolbar items are gathered from `items` array.
93
+ * The balloon's CSS class is by default `ck-toolbar-container` and may be override with the `balloonClassName` option.
94
+ *
95
+ * Note: This method should be called in the {@link module:core/plugin~PluginInterface#afterInit `Plugin#afterInit()`}
96
+ * callback (or later) to make sure that the given toolbar items were already registered by other plugins.
97
+ *
98
+ * @param toolbarId An id for the toolbar. Used to
99
+ * @param options.ariaLabel Label used by assistive technologies to describe this toolbar element.
100
+ * @param options.items Array of toolbar items.
101
+ * @param options.getRelatedElement Callback which returns an element the toolbar should be attached to.
102
+ * @param options.balloonClassName CSS class for the widget balloon.
103
+ */
104
+ register(toolbarId, { ariaLabel, items, getRelatedElement, balloonClassName = 'ck-toolbar-container' }) {
105
+ // Trying to register a toolbar without any item.
106
+ if (!items.length) {
107
+ /**
108
+ * When {@link module:widget/widgettoolbarrepository~WidgetToolbarRepository#register registering} a new widget toolbar, you
109
+ * need to provide a non-empty array with the items that will be inserted into the toolbar.
110
+ *
111
+ * If you see this error when integrating the editor, you likely forgot to configure one of the widget toolbars.
112
+ *
113
+ * See for instance:
114
+ *
115
+ * * {@link module:table/tableconfig~TableConfig#contentToolbar `config.table.contentToolbar`}
116
+ * * {@link module:image/imageconfig~ImageConfig#toolbar `config.image.toolbar`}
117
+ *
118
+ * @error widget-toolbar-no-items
119
+ * @param toolbarId The id of the toolbar that has not been configured correctly.
120
+ */
121
+ logWarning('widget-toolbar-no-items', { toolbarId });
122
+ return;
123
+ }
124
+ const editor = this.editor;
125
+ const t = editor.t;
126
+ const toolbarView = new ToolbarView(editor.locale);
127
+ toolbarView.ariaLabel = ariaLabel || t('Widget toolbar');
128
+ if (this._toolbarDefinitions.has(toolbarId)) {
129
+ /**
130
+ * Toolbar with the given id was already added.
131
+ *
132
+ * @error widget-toolbar-duplicated
133
+ * @param toolbarId Toolbar id.
134
+ */
135
+ throw new CKEditorError('widget-toolbar-duplicated', this, { toolbarId });
136
+ }
137
+ const toolbarDefinition = {
138
+ view: toolbarView,
139
+ getRelatedElement,
140
+ balloonClassName,
141
+ itemsConfig: items,
142
+ initialized: false
143
+ };
144
+ // Register the toolbar so it becomes available for Alt+F10 and Esc navigation.
145
+ editor.ui.addToolbar(toolbarView, {
146
+ isContextual: true,
147
+ beforeFocus: () => {
148
+ const relatedElement = getRelatedElement(editor.editing.view.document.selection);
149
+ if (relatedElement) {
150
+ this._showToolbar(toolbarDefinition, relatedElement);
151
+ }
152
+ },
153
+ afterBlur: () => {
154
+ this._hideToolbar(toolbarDefinition);
155
+ }
156
+ });
157
+ this._toolbarDefinitions.set(toolbarId, toolbarDefinition);
158
+ }
159
+ /**
160
+ * Iterates over stored toolbars and makes them visible or hidden.
161
+ */
162
+ _updateToolbarsVisibility() {
163
+ let maxRelatedElementDepth = 0;
164
+ let deepestRelatedElement = null;
165
+ let deepestToolbarDefinition = null;
166
+ for (const definition of this._toolbarDefinitions.values()) {
167
+ const relatedElement = definition.getRelatedElement(this.editor.editing.view.document.selection);
168
+ if (!this.isEnabled || !relatedElement) {
169
+ if (this._isToolbarInBalloon(definition)) {
170
+ this._hideToolbar(definition);
171
+ }
172
+ }
173
+ else if (!this.editor.ui.focusTracker.isFocused) {
174
+ if (this._isToolbarVisible(definition)) {
175
+ this._hideToolbar(definition);
176
+ }
177
+ }
178
+ else {
179
+ const relatedElementDepth = relatedElement.getAncestors().length;
180
+ // Many toolbars can express willingness to be displayed but they do not know about
181
+ // each other. Figure out which toolbar is deepest in the view tree to decide which
182
+ // should be displayed. For instance, if a selected image is inside a table cell, display
183
+ // the ImageToolbar rather than the TableToolbar (#60).
184
+ if (relatedElementDepth > maxRelatedElementDepth) {
185
+ maxRelatedElementDepth = relatedElementDepth;
186
+ deepestRelatedElement = relatedElement;
187
+ deepestToolbarDefinition = definition;
188
+ }
189
+ }
190
+ }
191
+ if (deepestToolbarDefinition) {
192
+ this._showToolbar(deepestToolbarDefinition, deepestRelatedElement);
193
+ }
194
+ }
195
+ /**
196
+ * Hides the given toolbar.
197
+ */
198
+ _hideToolbar(toolbarDefinition) {
199
+ this._balloon.remove(toolbarDefinition.view);
200
+ this.stopListening(this._balloon, 'change:visibleView');
201
+ }
202
+ /**
203
+ * Shows up the toolbar if the toolbar is not visible.
204
+ * Otherwise, repositions the toolbar's balloon when toolbar's view is the most top view in balloon stack.
205
+ *
206
+ * It might happen here that the toolbar's view is under another view. Then do nothing as the other toolbar view
207
+ * should be still visible after the {@link module:ui/editorui/editorui~EditorUI#event:update}.
208
+ */
209
+ _showToolbar(toolbarDefinition, relatedElement) {
210
+ if (this._isToolbarVisible(toolbarDefinition)) {
211
+ repositionContextualBalloon(this.editor, relatedElement);
212
+ }
213
+ else if (!this._isToolbarInBalloon(toolbarDefinition)) {
214
+ if (!toolbarDefinition.initialized) {
215
+ toolbarDefinition.initialized = true;
216
+ toolbarDefinition.view.fillFromConfig(toolbarDefinition.itemsConfig, this.editor.ui.componentFactory);
217
+ }
218
+ this._balloon.add({
219
+ view: toolbarDefinition.view,
220
+ position: getBalloonPositionData(this.editor, relatedElement),
221
+ balloonClassName: toolbarDefinition.balloonClassName
222
+ });
223
+ // Update toolbar position each time stack with toolbar view is switched to visible.
224
+ // This is in a case target element has changed when toolbar was in invisible stack
225
+ // e.g. target image was wrapped by a block quote.
226
+ // See https://github.com/ckeditor/ckeditor5-widget/issues/92.
227
+ this.listenTo(this._balloon, 'change:visibleView', () => {
228
+ for (const definition of this._toolbarDefinitions.values()) {
229
+ if (this._isToolbarVisible(definition)) {
230
+ const relatedElement = definition.getRelatedElement(this.editor.editing.view.document.selection);
231
+ repositionContextualBalloon(this.editor, relatedElement);
232
+ }
233
+ }
234
+ });
235
+ }
236
+ }
237
+ _isToolbarVisible(toolbar) {
238
+ return this._balloon.visibleView === toolbar.view;
239
+ }
240
+ _isToolbarInBalloon(toolbar) {
241
+ return this._balloon.hasView(toolbar.view);
242
+ }
243
+ }
244
+ function repositionContextualBalloon(editor, relatedElement) {
245
+ const balloon = editor.plugins.get('ContextualBalloon');
246
+ const position = getBalloonPositionData(editor, relatedElement);
247
+ balloon.updatePosition(position);
248
+ }
249
+ function getBalloonPositionData(editor, relatedElement) {
250
+ const editingView = editor.editing.view;
251
+ const defaultPositions = BalloonPanelView.defaultPositions;
252
+ return {
253
+ target: editingView.domConverter.mapViewToDom(relatedElement),
254
+ positions: [
255
+ defaultPositions.northArrowSouth,
256
+ defaultPositions.northArrowSouthWest,
257
+ defaultPositions.northArrowSouthEast,
258
+ defaultPositions.southArrowNorth,
259
+ defaultPositions.southArrowNorthWest,
260
+ defaultPositions.southArrowNorthEast,
261
+ defaultPositions.viewportStickyNorth
262
+ ]
263
+ };
264
+ }
265
+ function isWidgetSelected(selection) {
266
+ const viewElement = selection.getSelectedElement();
267
+ return !!(viewElement && isWidget(viewElement));
268
+ }
@@ -1,38 +1,38 @@
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
- import type { DocumentSelection, DomConverter, Element, Schema, Selection, ViewElement } from '@ckeditor/ckeditor5-engine';
6
- /**
7
- * The name of the type around model selection attribute responsible for
8
- * displaying a fake caret next to a selected widget.
9
- */
10
- export declare const TYPE_AROUND_SELECTION_ATTRIBUTE = "widget-type-around";
11
- /**
12
- * Checks if an element is a widget that qualifies to get the widget type around UI.
13
- */
14
- export declare function isTypeAroundWidget(viewElement: ViewElement | undefined, modelElement: Element, schema: Schema): boolean;
15
- /**
16
- * For the passed HTML element, this helper finds the closest widget type around button ancestor.
17
- */
18
- export declare function getClosestTypeAroundDomButton(domElement: HTMLElement): HTMLElement | null;
19
- /**
20
- * For the passed widget type around button element, this helper determines at which position
21
- * the paragraph would be inserted into the content if, for instance, the button was
22
- * clicked by the user.
23
- *
24
- * @returns The position of the button.
25
- */
26
- export declare function getTypeAroundButtonPosition(domElement: HTMLElement): 'before' | 'after';
27
- /**
28
- * For the passed HTML element, this helper returns the closest view widget ancestor.
29
- */
30
- export declare function getClosestWidgetViewElement(domElement: HTMLElement, domConverter: DomConverter): ViewElement;
31
- /**
32
- * For the passed selection instance, it returns the position of the fake caret displayed next to a widget.
33
- *
34
- * **Note**: If the fake caret is not currently displayed, `null` is returned.
35
- *
36
- * @returns The position of the fake caret or `null` when none is present.
37
- */
38
- export declare function getTypeAroundFakeCaretPosition(selection: Selection | DocumentSelection): 'before' | 'after' | null;
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
+ import type { DocumentSelection, DomConverter, Element, Schema, Selection, ViewElement } from '@ckeditor/ckeditor5-engine';
6
+ /**
7
+ * The name of the type around model selection attribute responsible for
8
+ * displaying a fake caret next to a selected widget.
9
+ */
10
+ export declare const TYPE_AROUND_SELECTION_ATTRIBUTE = "widget-type-around";
11
+ /**
12
+ * Checks if an element is a widget that qualifies to get the widget type around UI.
13
+ */
14
+ export declare function isTypeAroundWidget(viewElement: ViewElement | undefined, modelElement: Element, schema: Schema): boolean;
15
+ /**
16
+ * For the passed HTML element, this helper finds the closest widget type around button ancestor.
17
+ */
18
+ export declare function getClosestTypeAroundDomButton(domElement: HTMLElement): HTMLElement | null;
19
+ /**
20
+ * For the passed widget type around button element, this helper determines at which position
21
+ * the paragraph would be inserted into the content if, for instance, the button was
22
+ * clicked by the user.
23
+ *
24
+ * @returns The position of the button.
25
+ */
26
+ export declare function getTypeAroundButtonPosition(domElement: HTMLElement): 'before' | 'after';
27
+ /**
28
+ * For the passed HTML element, this helper returns the closest view widget ancestor.
29
+ */
30
+ export declare function getClosestWidgetViewElement(domElement: HTMLElement, domConverter: DomConverter): ViewElement;
31
+ /**
32
+ * For the passed selection instance, it returns the position of the fake caret displayed next to a widget.
33
+ *
34
+ * **Note**: If the fake caret is not currently displayed, `null` is returned.
35
+ *
36
+ * @returns The position of the fake caret or `null` when none is present.
37
+ */
38
+ export declare function getTypeAroundFakeCaretPosition(selection: Selection | DocumentSelection): 'before' | 'after' | null;