@ckeditor/ckeditor5-widget 40.0.0 → 40.1.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.
- 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
|
+
}
|