@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.
- package/CHANGELOG.md +24 -24
- package/LICENSE.md +3 -3
- package/package.json +7 -7
- package/src/augmentation.d.ts +13 -13
- package/src/augmentation.js +5 -5
- package/src/highlightstack.d.ts +74 -74
- package/src/highlightstack.js +129 -129
- package/src/index.d.ts +13 -13
- package/src/index.js +13 -13
- package/src/utils.d.ts +198 -198
- package/src/utils.js +348 -348
- package/src/verticalnavigation.d.ts +15 -15
- package/src/verticalnavigation.js +196 -196
- package/src/widget.d.ts +95 -91
- package/src/widget.js +429 -380
- package/src/widgetresize/resizer.d.ts +177 -177
- package/src/widgetresize/resizer.js +372 -372
- package/src/widgetresize/resizerstate.d.ts +125 -125
- package/src/widgetresize/resizerstate.js +150 -150
- package/src/widgetresize/sizeview.d.ts +55 -55
- package/src/widgetresize/sizeview.js +63 -63
- package/src/widgetresize.d.ts +125 -125
- package/src/widgetresize.js +188 -188
- package/src/widgettoolbarrepository.d.ts +94 -94
- package/src/widgettoolbarrepository.js +268 -268
- package/src/widgettypearound/utils.d.ts +38 -38
- package/src/widgettypearound/utils.js +52 -52
- package/src/widgettypearound/widgettypearound.d.ts +229 -229
- package/src/widgettypearound/widgettypearound.js +773 -773
@@ -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
|
-
*
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
*
|
53
|
-
*
|
54
|
-
*
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
*
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
*
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
*
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
*
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
*
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
* @
|
84
|
-
* @
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
*
|
89
|
-
*/
|
90
|
-
|
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
|
+
}
|