@ckeditor/ckeditor5-widget 0.0.0-nightly-20240410.0 → 0.0.0-nightly-20240412.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.
Potentially problematic release.
This version of @ckeditor/ckeditor5-widget might be problematic. Click here for more details.
- package/package.json +7 -7
- package/src/widget.d.ts +8 -0
- package/src/widget.js +85 -1
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@ckeditor/ckeditor5-widget",
|
3
|
-
"version": "0.0.0-nightly-
|
3
|
+
"version": "0.0.0-nightly-20240412.0",
|
4
4
|
"description": "Widget API for CKEditor 5.",
|
5
5
|
"keywords": [
|
6
6
|
"ckeditor",
|
@@ -12,12 +12,12 @@
|
|
12
12
|
"type": "module",
|
13
13
|
"main": "src/index.js",
|
14
14
|
"dependencies": {
|
15
|
-
"@ckeditor/ckeditor5-core": "0.0.0-nightly-
|
16
|
-
"@ckeditor/ckeditor5-engine": "0.0.0-nightly-
|
17
|
-
"@ckeditor/ckeditor5-enter": "0.0.0-nightly-
|
18
|
-
"@ckeditor/ckeditor5-ui": "0.0.0-nightly-
|
19
|
-
"@ckeditor/ckeditor5-utils": "0.0.0-nightly-
|
20
|
-
"@ckeditor/ckeditor5-typing": "0.0.0-nightly-
|
15
|
+
"@ckeditor/ckeditor5-core": "0.0.0-nightly-20240412.0",
|
16
|
+
"@ckeditor/ckeditor5-engine": "0.0.0-nightly-20240412.0",
|
17
|
+
"@ckeditor/ckeditor5-enter": "0.0.0-nightly-20240412.0",
|
18
|
+
"@ckeditor/ckeditor5-ui": "0.0.0-nightly-20240412.0",
|
19
|
+
"@ckeditor/ckeditor5-utils": "0.0.0-nightly-20240412.0",
|
20
|
+
"@ckeditor/ckeditor5-typing": "0.0.0-nightly-20240412.0",
|
21
21
|
"lodash-es": "4.17.21"
|
22
22
|
},
|
23
23
|
"author": "CKSource (http://cksource.com/)",
|
package/src/widget.d.ts
CHANGED
@@ -92,4 +92,12 @@ export default class Widget extends Plugin {
|
|
92
92
|
* Removes CSS class from previously selected widgets.
|
93
93
|
*/
|
94
94
|
private _clearPreviouslySelectedWidgets;
|
95
|
+
/**
|
96
|
+
* Moves the document selection into the first nested editable.
|
97
|
+
*/
|
98
|
+
private _selectFirstNestedEditable;
|
99
|
+
/**
|
100
|
+
* Updates the document selection so that it selects first ancestor widget.
|
101
|
+
*/
|
102
|
+
private _selectAncestorWidget;
|
95
103
|
}
|
package/src/widget.js
CHANGED
@@ -8,7 +8,7 @@
|
|
8
8
|
import { Plugin } from '@ckeditor/ckeditor5-core';
|
9
9
|
import { MouseObserver, TreeWalker } from '@ckeditor/ckeditor5-engine';
|
10
10
|
import { Delete } from '@ckeditor/ckeditor5-typing';
|
11
|
-
import { env, getLocalizedArrowKeyCodeDirection } from '@ckeditor/ckeditor5-utils';
|
11
|
+
import { env, keyCodes, getLocalizedArrowKeyCodeDirection } from '@ckeditor/ckeditor5-utils';
|
12
12
|
import WidgetTypeAround from './widgettypearound/widgettypearound.js';
|
13
13
|
import verticalNavigationHandler from './verticalnavigation.js';
|
14
14
|
import { getLabel, isWidget, WIDGET_SELECTED_CLASS_NAME } from './utils.js';
|
@@ -146,6 +146,41 @@ export default class Widget extends Plugin {
|
|
146
146
|
evt.stop();
|
147
147
|
}
|
148
148
|
}, { context: '$root' });
|
149
|
+
// Handle Tab key while a widget is selected.
|
150
|
+
this.listenTo(viewDocument, 'tab', (evt, data) => {
|
151
|
+
// This event could be triggered from inside the widget, but we are interested
|
152
|
+
// only when the widget is selected itself.
|
153
|
+
if (evt.eventPhase != 'atTarget') {
|
154
|
+
return;
|
155
|
+
}
|
156
|
+
if (data.shiftKey) {
|
157
|
+
return;
|
158
|
+
}
|
159
|
+
if (this._selectFirstNestedEditable()) {
|
160
|
+
data.preventDefault();
|
161
|
+
evt.stop();
|
162
|
+
}
|
163
|
+
}, { context: isWidget, priority: 'low' });
|
164
|
+
// Handle Shift+Tab key while caret inside a widget editable.
|
165
|
+
this.listenTo(viewDocument, 'tab', (evt, data) => {
|
166
|
+
if (!data.shiftKey) {
|
167
|
+
return;
|
168
|
+
}
|
169
|
+
if (this._selectAncestorWidget()) {
|
170
|
+
data.preventDefault();
|
171
|
+
evt.stop();
|
172
|
+
}
|
173
|
+
}, { priority: 'low' });
|
174
|
+
// Handle Esc key while inside a nested editable.
|
175
|
+
this.listenTo(viewDocument, 'keydown', (evt, data) => {
|
176
|
+
if (data.keystroke != keyCodes.esc) {
|
177
|
+
return;
|
178
|
+
}
|
179
|
+
if (this._selectAncestorWidget()) {
|
180
|
+
data.preventDefault();
|
181
|
+
evt.stop();
|
182
|
+
}
|
183
|
+
}, { priority: 'low' });
|
149
184
|
// Add the information about the keystrokes to the accessibility database.
|
150
185
|
editor.accessibility.addKeystrokeInfoGroup({
|
151
186
|
id: 'widget',
|
@@ -391,6 +426,55 @@ export default class Widget extends Plugin {
|
|
391
426
|
}
|
392
427
|
this._previouslySelected.clear();
|
393
428
|
}
|
429
|
+
/**
|
430
|
+
* Moves the document selection into the first nested editable.
|
431
|
+
*/
|
432
|
+
_selectFirstNestedEditable() {
|
433
|
+
const editor = this.editor;
|
434
|
+
const view = this.editor.editing.view;
|
435
|
+
const viewDocument = view.document;
|
436
|
+
for (const item of viewDocument.selection.getFirstRange().getItems()) {
|
437
|
+
if (item.is('editableElement')) {
|
438
|
+
const modelElement = editor.editing.mapper.toModelElement(item);
|
439
|
+
/* istanbul ignore next -- @preserve */
|
440
|
+
if (!modelElement) {
|
441
|
+
continue;
|
442
|
+
}
|
443
|
+
const position = editor.model.createPositionAt(modelElement, 0);
|
444
|
+
const newRange = editor.model.schema.getNearestSelectionRange(position, 'forward');
|
445
|
+
editor.model.change(writer => {
|
446
|
+
writer.setSelection(newRange);
|
447
|
+
});
|
448
|
+
return true;
|
449
|
+
}
|
450
|
+
}
|
451
|
+
return false;
|
452
|
+
}
|
453
|
+
/**
|
454
|
+
* Updates the document selection so that it selects first ancestor widget.
|
455
|
+
*/
|
456
|
+
_selectAncestorWidget() {
|
457
|
+
const editor = this.editor;
|
458
|
+
const mapper = editor.editing.mapper;
|
459
|
+
const selection = editor.editing.view.document.selection;
|
460
|
+
const positionParent = selection.getFirstPosition().parent;
|
461
|
+
const positionParentElement = positionParent.is('$text') ?
|
462
|
+
positionParent.parent :
|
463
|
+
positionParent;
|
464
|
+
const viewElement = positionParentElement.findAncestor(isWidget);
|
465
|
+
if (!viewElement) {
|
466
|
+
return false;
|
467
|
+
}
|
468
|
+
const modelElement = mapper.toModelElement(viewElement);
|
469
|
+
/* istanbul ignore next -- @preserve */
|
470
|
+
if (!modelElement) {
|
471
|
+
return false;
|
472
|
+
}
|
473
|
+
editor.model.change(writer => {
|
474
|
+
writer.setSelection(modelElement, 'on');
|
475
|
+
});
|
476
|
+
return true;
|
477
|
+
}
|
394
478
|
}
|
395
479
|
/**
|
396
480
|
* Returns `true` when element is a nested editable or is placed inside one.
|