@ckeditor/ckeditor5-typing 35.2.1 → 35.3.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/package.json +31 -18
- package/src/delete.js +68 -123
- package/src/deletecommand.js +205 -242
- package/src/deleteobserver.js +205 -112
- package/src/index.js +0 -6
- package/src/input.js +125 -28
- package/src/inserttextcommand.js +96 -0
- package/src/inserttextobserver.js +104 -0
- package/src/texttransformation.js +174 -384
- package/src/textwatcher.js +131 -171
- package/src/twostepcaretmovement.js +300 -341
- package/src/typing.js +9 -43
- package/src/typingconfig.js +5 -0
- package/src/utils/changebuffer.js +142 -151
- package/src/utils/findattributerange.js +12 -24
- package/src/utils/getlasttextline.js +11 -29
- package/src/utils/inlinehighlight.js +38 -52
- package/src/inputcommand.js +0 -100
- package/src/utils/injecttypingmutationshandling.js +0 -331
- package/src/utils/injectunsafekeystrokeshandling.js +0 -189
- package/src/utils/utils.js +0 -104
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2003-2022, 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 typing/inserttextobserver
|
|
7
|
+
*/
|
|
8
|
+
import DomEventData from '@ckeditor/ckeditor5-engine/src/view/observer/domeventdata';
|
|
9
|
+
import Observer from '@ckeditor/ckeditor5-engine/src/view/observer/observer';
|
|
10
|
+
import EventInfo from '@ckeditor/ckeditor5-utils/src/eventinfo';
|
|
11
|
+
import env from '@ckeditor/ckeditor5-utils/src/env';
|
|
12
|
+
const TYPING_INPUT_TYPES = [
|
|
13
|
+
// For collapsed range:
|
|
14
|
+
// - This one is a regular typing (all browsers, all systems).
|
|
15
|
+
// - This one is used by Chrome when typing accented letter – 2nd step when the user selects the accent (Mac).
|
|
16
|
+
// For non-collapsed range:
|
|
17
|
+
// - This one is used by Chrome when typing accented letter – when the selection box first appears (Mac).
|
|
18
|
+
// - This one is used by Safari when accepting spell check suggestions from the context menu (Mac).
|
|
19
|
+
'insertText',
|
|
20
|
+
// This one is used by Safari when typing accented letter (Mac).
|
|
21
|
+
// This one is used by Safari when accepting spell check suggestions from the autocorrection pop-up (Mac).
|
|
22
|
+
'insertReplacementText'
|
|
23
|
+
];
|
|
24
|
+
/**
|
|
25
|
+
* Text insertion observer introduces the {@link module:engine/view/document~Document#event:insertText} event.
|
|
26
|
+
*
|
|
27
|
+
* @extends module:engine/view/observer/observer~Observer
|
|
28
|
+
*/
|
|
29
|
+
export default class InsertTextObserver extends Observer {
|
|
30
|
+
/**
|
|
31
|
+
* @inheritDoc
|
|
32
|
+
*/
|
|
33
|
+
constructor(view) {
|
|
34
|
+
super(view);
|
|
35
|
+
// On Android composition events should immediately be applied to the model. Rendering is not disabled.
|
|
36
|
+
// On non-Android the model is updated only on composition end.
|
|
37
|
+
// On Android we can't rely on composition start/end to update model.
|
|
38
|
+
if (env.isAndroid) {
|
|
39
|
+
TYPING_INPUT_TYPES.push('insertCompositionText');
|
|
40
|
+
}
|
|
41
|
+
const viewDocument = view.document;
|
|
42
|
+
viewDocument.on('beforeinput', (evt, data) => {
|
|
43
|
+
if (!this.isEnabled) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const { data: text, targetRanges, inputType, domEvent } = data;
|
|
47
|
+
if (!TYPING_INPUT_TYPES.includes(inputType)) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const eventInfo = new EventInfo(viewDocument, 'insertText');
|
|
51
|
+
viewDocument.fire(eventInfo, new DomEventData(view, domEvent, {
|
|
52
|
+
text,
|
|
53
|
+
selection: view.createSelection(targetRanges)
|
|
54
|
+
}));
|
|
55
|
+
// Stop the beforeinput event if `delete` event was stopped.
|
|
56
|
+
// https://github.com/ckeditor/ckeditor5/issues/753
|
|
57
|
+
if (eventInfo.stop.called) {
|
|
58
|
+
evt.stop();
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
// Note: The priority must be lower than the CompositionObserver handler to call it after the renderer is unblocked.
|
|
62
|
+
viewDocument.on('compositionend', (evt, { data, domEvent }) => {
|
|
63
|
+
// On Android composition events are immediately applied to the model.
|
|
64
|
+
// On non-Android the model is updated only on composition end.
|
|
65
|
+
// On Android we can't rely on composition start/end to update model.
|
|
66
|
+
if (!this.isEnabled || env.isAndroid) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
// In case of aborted composition.
|
|
70
|
+
if (!data) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
// @if CK_DEBUG_TYPING // if ( window.logCKETyping ) {
|
|
74
|
+
// @if CK_DEBUG_TYPING // console.log( `%c[InsertTextObserver]%c Fire insertText event, text: ${ JSON.stringify( data ) }`,
|
|
75
|
+
// @if CK_DEBUG_TYPING // 'font-weight: bold; color: green;', ''
|
|
76
|
+
// @if CK_DEBUG_TYPING // );
|
|
77
|
+
// @if CK_DEBUG_TYPING // }
|
|
78
|
+
// How do we know where to insert the composed text?
|
|
79
|
+
// The selection observer is blocked and the view is not updated with the composition changes.
|
|
80
|
+
// There were three options:
|
|
81
|
+
// - Store the selection on `compositionstart` and use it now. This wouldn't work in RTC
|
|
82
|
+
// where the view would change and the stored selection might get incorrect.
|
|
83
|
+
// We'd need to fallback to the current view selection anyway.
|
|
84
|
+
// - Use the current view selection. This is a bit weird and non-intuitive because
|
|
85
|
+
// this isn't necessarily the selection on which the user started composing.
|
|
86
|
+
// We cannot even know whether it's still collapsed (there might be some weird
|
|
87
|
+
// editor feature that changed it in unpredictable ways for us). But it's by far
|
|
88
|
+
// the simplest solution and should be stable (the selection is definitely correct)
|
|
89
|
+
// and probably mostly predictable (features usually don't modify the selection
|
|
90
|
+
// unless called explicitly by the user).
|
|
91
|
+
// - Try to follow it from the `beforeinput` events. This would be really complex as each
|
|
92
|
+
// `beforeinput` would come with just the range it's changing and we'd need to calculate that.
|
|
93
|
+
// We decided to go with the 2nd option for its simplicity and stability.
|
|
94
|
+
viewDocument.fire('insertText', new DomEventData(view, domEvent, {
|
|
95
|
+
text: data,
|
|
96
|
+
selection: viewDocument.selection
|
|
97
|
+
}));
|
|
98
|
+
}, { priority: 'lowest' });
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* @inheritDoc
|
|
102
|
+
*/
|
|
103
|
+
observe() { }
|
|
104
|
+
}
|