@ckeditor/ckeditor5-widget 40.0.0 → 40.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,15 +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/verticalnavigation
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>;
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/verticalnavigation
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>;
@@ -1,196 +1,196 @@
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/verticalnavigation
7
- */
8
- import { keyCodes, Rect } from '@ckeditor/ckeditor5-utils';
9
- /**
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
- *
12
- * @param editing The editing controller.
13
- */
14
- export default function verticalNavigationHandler(editing) {
15
- const model = editing.model;
16
- return (evt, data) => {
17
- const arrowUpPressed = data.keyCode == keyCodes.arrowup;
18
- const arrowDownPressed = data.keyCode == keyCodes.arrowdown;
19
- const expandSelection = data.shiftKey;
20
- const selection = model.document.selection;
21
- if (!arrowUpPressed && !arrowDownPressed) {
22
- return;
23
- }
24
- const isForward = arrowDownPressed;
25
- // Navigation is in the opposite direction than the selection direction so this is shrinking of the selection.
26
- // Selection for sure will not approach any object.
27
- if (expandSelection && selectionWillShrink(selection, isForward)) {
28
- return;
29
- }
30
- // Find a range between selection and closest limit element.
31
- const range = findTextRangeFromSelection(editing, selection, isForward);
32
- // There is no selection position inside the limit element.
33
- if (!range) {
34
- return;
35
- }
36
- // If already at the edge of a limit element.
37
- if (range.isCollapsed) {
38
- // A collapsed selection at limit edge - nothing more to do.
39
- if (selection.isCollapsed) {
40
- return;
41
- }
42
- // A non collapsed selection is at the limit edge while expanding the selection - let others do their stuff.
43
- else if (expandSelection) {
44
- return;
45
- }
46
- }
47
- // If the range is a single line (there is no word wrapping) then move the selection to the position closest to the limit element.
48
- //
49
- // We can't move the selection directly to the isObject element (eg. table cell) because of dual position at the end/beginning
50
- // of wrapped line (it's at the same time at the end of one line and at the start of the next line).
51
- if (range.isCollapsed || isSingleLineRange(editing, range, isForward)) {
52
- model.change(writer => {
53
- const newPosition = isForward ? range.end : range.start;
54
- if (expandSelection) {
55
- const newSelection = model.createSelection(selection.anchor);
56
- newSelection.setFocus(newPosition);
57
- writer.setSelection(newSelection);
58
- }
59
- else {
60
- writer.setSelection(newPosition);
61
- }
62
- });
63
- evt.stop();
64
- data.preventDefault();
65
- data.stopPropagation();
66
- }
67
- };
68
- }
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
- */
79
- function findTextRangeFromSelection(editing, selection, isForward) {
80
- const model = editing.model;
81
- if (isForward) {
82
- const startPosition = selection.isCollapsed ? selection.focus : selection.getLastPosition();
83
- const endPosition = getNearestNonInlineLimit(model, startPosition, 'forward');
84
- // There is no limit element, browser should handle this.
85
- if (!endPosition) {
86
- return null;
87
- }
88
- const range = model.createRange(startPosition, endPosition);
89
- const lastRangePosition = getNearestTextPosition(model.schema, range, 'backward');
90
- if (lastRangePosition) {
91
- return model.createRange(startPosition, lastRangePosition);
92
- }
93
- return null;
94
- }
95
- else {
96
- const endPosition = selection.isCollapsed ? selection.focus : selection.getFirstPosition();
97
- const startPosition = getNearestNonInlineLimit(model, endPosition, 'backward');
98
- // There is no limit element, browser should handle this.
99
- if (!startPosition) {
100
- return null;
101
- }
102
- const range = model.createRange(startPosition, endPosition);
103
- const firstRangePosition = getNearestTextPosition(model.schema, range, 'forward');
104
- if (firstRangePosition) {
105
- return model.createRange(firstRangePosition, endPosition);
106
- }
107
- return null;
108
- }
109
- }
110
- /**
111
- * Finds the limit element position that is closest to startPosition.
112
- *
113
- * @param direction Search direction.
114
- */
115
- function getNearestNonInlineLimit(model, startPosition, direction) {
116
- const schema = model.schema;
117
- const range = model.createRangeIn(startPosition.root);
118
- const walkerValueType = direction == 'forward' ? 'elementStart' : 'elementEnd';
119
- for (const { previousPosition, item, type } of range.getWalker({ startPosition, direction })) {
120
- if (schema.isLimit(item) && !schema.isInline(item)) {
121
- return previousPosition;
122
- }
123
- // Stop looking for isLimit element if the next element is a block element (it is for sure not single line).
124
- if (type == walkerValueType && schema.isBlock(item)) {
125
- return null;
126
- }
127
- }
128
- return null;
129
- }
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
- */
140
- function getNearestTextPosition(schema, range, direction) {
141
- const position = direction == 'backward' ? range.end : range.start;
142
- if (schema.checkChild(position, '$text')) {
143
- return position;
144
- }
145
- for (const { nextPosition } of range.getWalker({ direction })) {
146
- if (schema.checkChild(nextPosition, '$text')) {
147
- return nextPosition;
148
- }
149
- }
150
- return null;
151
- }
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
- */
160
- function isSingleLineRange(editing, modelRange, isForward) {
161
- const model = editing.model;
162
- const domConverter = editing.view.domConverter;
163
- // Wrapped lines contain exactly the same position at the end of current line
164
- // and at the beginning of next line. That position's client rect is at the end
165
- // of current line. In case of caret at first position of the last line that 'dual'
166
- // position would be detected as it's not the last line.
167
- if (isForward) {
168
- const probe = model.createSelection(modelRange.start);
169
- model.modifySelection(probe);
170
- // If the new position is at the end of the container then we can't use this position
171
- // because it would provide incorrect result for eg caption of image and selection
172
- // just before end of it. Also in this case there is no "dual" position.
173
- if (!probe.focus.isAtEnd && !modelRange.start.isEqual(probe.focus)) {
174
- modelRange = model.createRange(probe.focus, modelRange.end);
175
- }
176
- }
177
- const viewRange = editing.mapper.toViewRange(modelRange);
178
- const domRange = domConverter.viewRangeToDom(viewRange);
179
- const rects = Rect.getDomRangeRects(domRange);
180
- let boundaryVerticalPosition;
181
- for (const rect of rects) {
182
- if (boundaryVerticalPosition === undefined) {
183
- boundaryVerticalPosition = Math.round(rect.bottom);
184
- continue;
185
- }
186
- // Let's check if this rect is in new line.
187
- if (Math.round(rect.top) >= boundaryVerticalPosition) {
188
- return false;
189
- }
190
- boundaryVerticalPosition = Math.max(boundaryVerticalPosition, Math.round(rect.bottom));
191
- }
192
- return true;
193
- }
194
- function selectionWillShrink(selection, isForward) {
195
- return !selection.isCollapsed && selection.isBackward == isForward;
196
- }
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/verticalnavigation
7
+ */
8
+ import { keyCodes, Rect } from '@ckeditor/ckeditor5-utils';
9
+ /**
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
+ *
12
+ * @param editing The editing controller.
13
+ */
14
+ export default function verticalNavigationHandler(editing) {
15
+ const model = editing.model;
16
+ return (evt, data) => {
17
+ const arrowUpPressed = data.keyCode == keyCodes.arrowup;
18
+ const arrowDownPressed = data.keyCode == keyCodes.arrowdown;
19
+ const expandSelection = data.shiftKey;
20
+ const selection = model.document.selection;
21
+ if (!arrowUpPressed && !arrowDownPressed) {
22
+ return;
23
+ }
24
+ const isForward = arrowDownPressed;
25
+ // Navigation is in the opposite direction than the selection direction so this is shrinking of the selection.
26
+ // Selection for sure will not approach any object.
27
+ if (expandSelection && selectionWillShrink(selection, isForward)) {
28
+ return;
29
+ }
30
+ // Find a range between selection and closest limit element.
31
+ const range = findTextRangeFromSelection(editing, selection, isForward);
32
+ // There is no selection position inside the limit element.
33
+ if (!range) {
34
+ return;
35
+ }
36
+ // If already at the edge of a limit element.
37
+ if (range.isCollapsed) {
38
+ // A collapsed selection at limit edge - nothing more to do.
39
+ if (selection.isCollapsed) {
40
+ return;
41
+ }
42
+ // A non collapsed selection is at the limit edge while expanding the selection - let others do their stuff.
43
+ else if (expandSelection) {
44
+ return;
45
+ }
46
+ }
47
+ // If the range is a single line (there is no word wrapping) then move the selection to the position closest to the limit element.
48
+ //
49
+ // We can't move the selection directly to the isObject element (eg. table cell) because of dual position at the end/beginning
50
+ // of wrapped line (it's at the same time at the end of one line and at the start of the next line).
51
+ if (range.isCollapsed || isSingleLineRange(editing, range, isForward)) {
52
+ model.change(writer => {
53
+ const newPosition = isForward ? range.end : range.start;
54
+ if (expandSelection) {
55
+ const newSelection = model.createSelection(selection.anchor);
56
+ newSelection.setFocus(newPosition);
57
+ writer.setSelection(newSelection);
58
+ }
59
+ else {
60
+ writer.setSelection(newPosition);
61
+ }
62
+ });
63
+ evt.stop();
64
+ data.preventDefault();
65
+ data.stopPropagation();
66
+ }
67
+ };
68
+ }
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
+ */
79
+ function findTextRangeFromSelection(editing, selection, isForward) {
80
+ const model = editing.model;
81
+ if (isForward) {
82
+ const startPosition = selection.isCollapsed ? selection.focus : selection.getLastPosition();
83
+ const endPosition = getNearestNonInlineLimit(model, startPosition, 'forward');
84
+ // There is no limit element, browser should handle this.
85
+ if (!endPosition) {
86
+ return null;
87
+ }
88
+ const range = model.createRange(startPosition, endPosition);
89
+ const lastRangePosition = getNearestTextPosition(model.schema, range, 'backward');
90
+ if (lastRangePosition) {
91
+ return model.createRange(startPosition, lastRangePosition);
92
+ }
93
+ return null;
94
+ }
95
+ else {
96
+ const endPosition = selection.isCollapsed ? selection.focus : selection.getFirstPosition();
97
+ const startPosition = getNearestNonInlineLimit(model, endPosition, 'backward');
98
+ // There is no limit element, browser should handle this.
99
+ if (!startPosition) {
100
+ return null;
101
+ }
102
+ const range = model.createRange(startPosition, endPosition);
103
+ const firstRangePosition = getNearestTextPosition(model.schema, range, 'forward');
104
+ if (firstRangePosition) {
105
+ return model.createRange(firstRangePosition, endPosition);
106
+ }
107
+ return null;
108
+ }
109
+ }
110
+ /**
111
+ * Finds the limit element position that is closest to startPosition.
112
+ *
113
+ * @param direction Search direction.
114
+ */
115
+ function getNearestNonInlineLimit(model, startPosition, direction) {
116
+ const schema = model.schema;
117
+ const range = model.createRangeIn(startPosition.root);
118
+ const walkerValueType = direction == 'forward' ? 'elementStart' : 'elementEnd';
119
+ for (const { previousPosition, item, type } of range.getWalker({ startPosition, direction })) {
120
+ if (schema.isLimit(item) && !schema.isInline(item)) {
121
+ return previousPosition;
122
+ }
123
+ // Stop looking for isLimit element if the next element is a block element (it is for sure not single line).
124
+ if (type == walkerValueType && schema.isBlock(item)) {
125
+ return null;
126
+ }
127
+ }
128
+ return null;
129
+ }
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
+ */
140
+ function getNearestTextPosition(schema, range, direction) {
141
+ const position = direction == 'backward' ? range.end : range.start;
142
+ if (schema.checkChild(position, '$text')) {
143
+ return position;
144
+ }
145
+ for (const { nextPosition } of range.getWalker({ direction })) {
146
+ if (schema.checkChild(nextPosition, '$text')) {
147
+ return nextPosition;
148
+ }
149
+ }
150
+ return null;
151
+ }
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
+ */
160
+ function isSingleLineRange(editing, modelRange, isForward) {
161
+ const model = editing.model;
162
+ const domConverter = editing.view.domConverter;
163
+ // Wrapped lines contain exactly the same position at the end of current line
164
+ // and at the beginning of next line. That position's client rect is at the end
165
+ // of current line. In case of caret at first position of the last line that 'dual'
166
+ // position would be detected as it's not the last line.
167
+ if (isForward) {
168
+ const probe = model.createSelection(modelRange.start);
169
+ model.modifySelection(probe);
170
+ // If the new position is at the end of the container then we can't use this position
171
+ // because it would provide incorrect result for eg caption of image and selection
172
+ // just before end of it. Also in this case there is no "dual" position.
173
+ if (!probe.focus.isAtEnd && !modelRange.start.isEqual(probe.focus)) {
174
+ modelRange = model.createRange(probe.focus, modelRange.end);
175
+ }
176
+ }
177
+ const viewRange = editing.mapper.toViewRange(modelRange);
178
+ const domRange = domConverter.viewRangeToDom(viewRange);
179
+ const rects = Rect.getDomRangeRects(domRange);
180
+ let boundaryVerticalPosition;
181
+ for (const rect of rects) {
182
+ if (boundaryVerticalPosition === undefined) {
183
+ boundaryVerticalPosition = Math.round(rect.bottom);
184
+ continue;
185
+ }
186
+ // Let's check if this rect is in new line.
187
+ if (Math.round(rect.top) >= boundaryVerticalPosition) {
188
+ return false;
189
+ }
190
+ boundaryVerticalPosition = Math.max(boundaryVerticalPosition, Math.round(rect.bottom));
191
+ }
192
+ return true;
193
+ }
194
+ function selectionWillShrink(selection, isForward) {
195
+ return !selection.isCollapsed && selection.isBackward == isForward;
196
+ }
package/src/widget.d.ts CHANGED
@@ -1,91 +1,95 @@
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 } from '@ckeditor/ckeditor5-core';
9
- import { type Element, type Node } from '@ckeditor/ckeditor5-engine';
10
- import { Delete } from '@ckeditor/ckeditor5-typing';
11
- import WidgetTypeAround from './widgettypearound/widgettypearound';
12
- import '../theme/widget.css';
13
- /**
14
- * The widget plugin. It enables base support for widgets.
15
- *
16
- * See {@glink api/widget package page} for more details and documentation.
17
- *
18
- * This plugin enables multiple behaviors required by widgets:
19
- *
20
- * * The model to view selection converter for the editing pipeline (it handles widget custom selection rendering).
21
- * If a converted selection wraps around a widget element, that selection is marked as
22
- * {@link module:engine/view/selection~Selection#isFake fake}. Additionally, the `ck-widget_selected` CSS class
23
- * is added to indicate that widget has been selected.
24
- * * The mouse and keyboard events handling on and around widget elements.
25
- */
26
- export default class Widget extends Plugin {
27
- /**
28
- * Holds previously selected widgets.
29
- */
30
- private _previouslySelected;
31
- /**
32
- * @inheritDoc
33
- */
34
- static get pluginName(): "Widget";
35
- /**
36
- * @inheritDoc
37
- */
38
- static get requires(): readonly [typeof WidgetTypeAround, typeof Delete];
39
- /**
40
- * @inheritDoc
41
- */
42
- init(): void;
43
- /**
44
- * Handles {@link module:engine/view/document~Document#event:mousedown mousedown} events on widget elements.
45
- */
46
- private _onMousedown;
47
- /**
48
- * Handles {@link module:engine/view/document~Document#event:keydown keydown} events and changes
49
- * the model selection when:
50
- *
51
- * * arrow key is pressed when the widget is selected,
52
- * * the selection is next to a widget and the widget should become selected upon the arrow key press.
53
- *
54
- * See {@link #_preventDefaultOnArrowKeyPress}.
55
- */
56
- private _handleSelectionChangeOnArrowKeyPress;
57
- /**
58
- * Handles {@link module:engine/view/document~Document#event:keydown keydown} events and prevents
59
- * the default browser behavior to make sure the fake selection is not being moved from a fake selection
60
- * container.
61
- *
62
- * See {@link #_handleSelectionChangeOnArrowKeyPress}.
63
- */
64
- private _preventDefaultOnArrowKeyPress;
65
- /**
66
- * Handles delete keys: backspace and delete.
67
- *
68
- * @param isForward Set to true if delete was performed in forward direction.
69
- * @returns Returns `true` if keys were handled correctly.
70
- */
71
- private _handleDelete;
72
- /**
73
- * Sets {@link module:engine/model/selection~Selection document's selection} over given element.
74
- *
75
- * @internal
76
- */
77
- _setSelectionOverElement(element: Node): void;
78
- /**
79
- * Checks if {@link module:engine/model/element~Element element} placed next to the current
80
- * {@link module:engine/model/selection~Selection model selection} exists and is marked in
81
- * {@link module:engine/model/schema~Schema schema} as `object`.
82
- *
83
- * @internal
84
- * @param forward Direction of checking.
85
- */
86
- _getObjectElementNextToSelection(forward: boolean): Element | null;
87
- /**
88
- * Removes CSS class from previously selected widgets.
89
- */
90
- private _clearPreviouslySelectedWidgets;
91
- }
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 } from '@ckeditor/ckeditor5-core';
9
+ import { type Element, type Node } from '@ckeditor/ckeditor5-engine';
10
+ import { Delete } from '@ckeditor/ckeditor5-typing';
11
+ import WidgetTypeAround from './widgettypearound/widgettypearound';
12
+ import '../theme/widget.css';
13
+ /**
14
+ * The widget plugin. It enables base support for widgets.
15
+ *
16
+ * See {@glink api/widget package page} for more details and documentation.
17
+ *
18
+ * This plugin enables multiple behaviors required by widgets:
19
+ *
20
+ * * The model to view selection converter for the editing pipeline (it handles widget custom selection rendering).
21
+ * If a converted selection wraps around a widget element, that selection is marked as
22
+ * {@link module:engine/view/selection~Selection#isFake fake}. Additionally, the `ck-widget_selected` CSS class
23
+ * is added to indicate that widget has been selected.
24
+ * * The mouse and keyboard events handling on and around widget elements.
25
+ */
26
+ export default class Widget extends Plugin {
27
+ /**
28
+ * Holds previously selected widgets.
29
+ */
30
+ private _previouslySelected;
31
+ /**
32
+ * @inheritDoc
33
+ */
34
+ static get pluginName(): "Widget";
35
+ /**
36
+ * @inheritDoc
37
+ */
38
+ static get requires(): readonly [typeof WidgetTypeAround, typeof Delete];
39
+ /**
40
+ * @inheritDoc
41
+ */
42
+ init(): void;
43
+ /**
44
+ * Handles {@link module:engine/view/document~Document#event:mousedown mousedown} events on widget elements.
45
+ */
46
+ private _onMousedown;
47
+ /**
48
+ * Selects entire block content, e.g. on triple click it selects entire paragraph.
49
+ */
50
+ private _selectBlockContent;
51
+ /**
52
+ * Handles {@link module:engine/view/document~Document#event:keydown keydown} events and changes
53
+ * the model selection when:
54
+ *
55
+ * * arrow key is pressed when the widget is selected,
56
+ * * the selection is next to a widget and the widget should become selected upon the arrow key press.
57
+ *
58
+ * See {@link #_preventDefaultOnArrowKeyPress}.
59
+ */
60
+ private _handleSelectionChangeOnArrowKeyPress;
61
+ /**
62
+ * Handles {@link module:engine/view/document~Document#event:keydown keydown} events and prevents
63
+ * the default browser behavior to make sure the fake selection is not being moved from a fake selection
64
+ * container.
65
+ *
66
+ * See {@link #_handleSelectionChangeOnArrowKeyPress}.
67
+ */
68
+ private _preventDefaultOnArrowKeyPress;
69
+ /**
70
+ * Handles delete keys: backspace and delete.
71
+ *
72
+ * @param isForward Set to true if delete was performed in forward direction.
73
+ * @returns Returns `true` if keys were handled correctly.
74
+ */
75
+ private _handleDelete;
76
+ /**
77
+ * Sets {@link module:engine/model/selection~Selection document's selection} over given element.
78
+ *
79
+ * @internal
80
+ */
81
+ _setSelectionOverElement(element: Node): void;
82
+ /**
83
+ * Checks if {@link module:engine/model/element~Element element} placed next to the current
84
+ * {@link module:engine/model/selection~Selection model selection} exists and is marked in
85
+ * {@link module:engine/model/schema~Schema schema} as `object`.
86
+ *
87
+ * @internal
88
+ * @param forward Direction of checking.
89
+ */
90
+ _getObjectElementNextToSelection(forward: boolean): Element | null;
91
+ /**
92
+ * Removes CSS class from previously selected widgets.
93
+ */
94
+ private _clearPreviouslySelectedWidgets;
95
+ }