@ckeditor/ckeditor5-engine 47.6.1 → 48.0.0-alpha.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 +1 -1
- package/{src → dist}/engineconfig.d.ts +6 -15
- package/dist/index-editor.css +38 -15
- package/dist/index.css +37 -37
- package/dist/index.css.map +1 -1
- package/{src → dist}/index.d.ts +0 -1
- package/dist/index.js +588 -94
- package/dist/index.js.map +1 -1
- package/{src → dist}/model/model.d.ts +10 -4
- package/{src → dist}/model/selection.d.ts +1 -1
- package/{src → dist}/view/downcastwriter.d.ts +3 -2
- package/{src → dist}/view/element.d.ts +2 -2
- package/{src → dist}/view/matcher.d.ts +4 -2
- package/dist/view/styles/background.d.ts +18 -0
- package/{src → dist}/view/styles/border.d.ts +0 -12
- package/{src → dist}/view/styles/margin.d.ts +0 -13
- package/{src → dist}/view/styles/padding.d.ts +0 -13
- package/{src → dist}/view/styles/utils.d.ts +12 -0
- package/package.json +20 -39
- package/src/controller/datacontroller.js +0 -522
- package/src/controller/editingcontroller.js +0 -181
- package/src/conversion/conversion.js +0 -606
- package/src/conversion/conversionhelpers.js +0 -33
- package/src/conversion/downcastdispatcher.js +0 -563
- package/src/conversion/downcasthelpers.js +0 -2160
- package/src/conversion/mapper.js +0 -1050
- package/src/conversion/modelconsumable.js +0 -331
- package/src/conversion/upcastdispatcher.js +0 -470
- package/src/conversion/upcasthelpers.js +0 -952
- package/src/conversion/viewconsumable.js +0 -541
- package/src/dataprocessor/basichtmlwriter.js +0 -22
- package/src/dataprocessor/dataprocessor.js +0 -5
- package/src/dataprocessor/htmldataprocessor.js +0 -107
- package/src/dataprocessor/htmlwriter.js +0 -5
- package/src/dataprocessor/xmldataprocessor.js +0 -127
- package/src/dev-utils/model.js +0 -396
- package/src/dev-utils/operationreplayer.js +0 -116
- package/src/dev-utils/utils.js +0 -122
- package/src/dev-utils/view.js +0 -990
- package/src/engineconfig.js +0 -5
- package/src/index.js +0 -134
- package/src/legacyerrors.js +0 -17
- package/src/model/batch.js +0 -98
- package/src/model/differ.js +0 -1288
- package/src/model/document.js +0 -398
- package/src/model/documentfragment.js +0 -332
- package/src/model/documentselection.js +0 -1026
- package/src/model/element.js +0 -323
- package/src/model/history.js +0 -206
- package/src/model/item.js +0 -5
- package/src/model/liveposition.js +0 -93
- package/src/model/liverange.js +0 -121
- package/src/model/markercollection.js +0 -436
- package/src/model/model.js +0 -866
- package/src/model/node.js +0 -371
- package/src/model/nodelist.js +0 -244
- package/src/model/operation/attributeoperation.js +0 -172
- package/src/model/operation/detachoperation.js +0 -87
- package/src/model/operation/insertoperation.js +0 -153
- package/src/model/operation/markeroperation.js +0 -136
- package/src/model/operation/mergeoperation.js +0 -184
- package/src/model/operation/moveoperation.js +0 -179
- package/src/model/operation/nooperation.js +0 -48
- package/src/model/operation/operation.js +0 -78
- package/src/model/operation/operationfactory.js +0 -44
- package/src/model/operation/renameoperation.js +0 -128
- package/src/model/operation/rootattributeoperation.js +0 -173
- package/src/model/operation/rootoperation.js +0 -106
- package/src/model/operation/splitoperation.js +0 -214
- package/src/model/operation/transform.js +0 -2211
- package/src/model/operation/utils.js +0 -217
- package/src/model/position.js +0 -1041
- package/src/model/range.js +0 -880
- package/src/model/rootelement.js +0 -82
- package/src/model/schema.js +0 -1542
- package/src/model/selection.js +0 -814
- package/src/model/text.js +0 -92
- package/src/model/textproxy.js +0 -202
- package/src/model/treewalker.js +0 -313
- package/src/model/typecheckable.js +0 -16
- package/src/model/utils/autoparagraphing.js +0 -63
- package/src/model/utils/deletecontent.js +0 -509
- package/src/model/utils/getselectedcontent.js +0 -126
- package/src/model/utils/insertcontent.js +0 -750
- package/src/model/utils/insertobject.js +0 -135
- package/src/model/utils/modifyselection.js +0 -187
- package/src/model/utils/selection-post-fixer.js +0 -264
- package/src/model/writer.js +0 -1318
- package/src/view/attributeelement.js +0 -220
- package/src/view/containerelement.js +0 -91
- package/src/view/datatransfer.js +0 -106
- package/src/view/document.js +0 -139
- package/src/view/documentfragment.js +0 -251
- package/src/view/documentselection.js +0 -270
- package/src/view/domconverter.js +0 -1661
- package/src/view/downcastwriter.js +0 -1589
- package/src/view/editableelement.js +0 -74
- package/src/view/element.js +0 -1053
- package/src/view/elementdefinition.js +0 -5
- package/src/view/emptyelement.js +0 -83
- package/src/view/filler.js +0 -161
- package/src/view/item.js +0 -5
- package/src/view/matcher.js +0 -437
- package/src/view/node.js +0 -238
- package/src/view/observer/arrowkeysobserver.js +0 -40
- package/src/view/observer/bubblingemittermixin.js +0 -215
- package/src/view/observer/bubblingeventinfo.js +0 -49
- package/src/view/observer/clickobserver.js +0 -26
- package/src/view/observer/compositionobserver.js +0 -64
- package/src/view/observer/domeventdata.js +0 -63
- package/src/view/observer/domeventobserver.js +0 -81
- package/src/view/observer/fakeselectionobserver.js +0 -95
- package/src/view/observer/focusobserver.js +0 -166
- package/src/view/observer/inputobserver.js +0 -236
- package/src/view/observer/keyobserver.js +0 -36
- package/src/view/observer/mouseobserver.js +0 -26
- package/src/view/observer/mutationobserver.js +0 -219
- package/src/view/observer/observer.js +0 -92
- package/src/view/observer/pointerobserver.js +0 -26
- package/src/view/observer/selectionobserver.js +0 -318
- package/src/view/observer/tabobserver.js +0 -42
- package/src/view/observer/touchobserver.js +0 -26
- package/src/view/placeholder.js +0 -285
- package/src/view/position.js +0 -341
- package/src/view/range.js +0 -451
- package/src/view/rawelement.js +0 -115
- package/src/view/renderer.js +0 -1148
- package/src/view/rooteditableelement.js +0 -78
- package/src/view/selection.js +0 -594
- package/src/view/styles/background.d.ts +0 -33
- package/src/view/styles/background.js +0 -74
- package/src/view/styles/border.js +0 -316
- package/src/view/styles/margin.js +0 -34
- package/src/view/styles/padding.js +0 -34
- package/src/view/styles/utils.js +0 -219
- package/src/view/stylesmap.js +0 -941
- package/src/view/text.js +0 -110
- package/src/view/textproxy.js +0 -136
- package/src/view/tokenlist.js +0 -194
- package/src/view/treewalker.js +0 -389
- package/src/view/typecheckable.js +0 -19
- package/src/view/uielement.js +0 -194
- package/src/view/upcastwriter.js +0 -363
- package/src/view/view.js +0 -579
- package/theme/placeholder.css +0 -36
- package/theme/renderer.css +0 -9
- /package/{src → dist}/controller/datacontroller.d.ts +0 -0
- /package/{src → dist}/controller/editingcontroller.d.ts +0 -0
- /package/{src → dist}/conversion/conversion.d.ts +0 -0
- /package/{src → dist}/conversion/conversionhelpers.d.ts +0 -0
- /package/{src → dist}/conversion/downcastdispatcher.d.ts +0 -0
- /package/{src → dist}/conversion/downcasthelpers.d.ts +0 -0
- /package/{src → dist}/conversion/mapper.d.ts +0 -0
- /package/{src → dist}/conversion/modelconsumable.d.ts +0 -0
- /package/{src → dist}/conversion/upcastdispatcher.d.ts +0 -0
- /package/{src → dist}/conversion/upcasthelpers.d.ts +0 -0
- /package/{src → dist}/conversion/viewconsumable.d.ts +0 -0
- /package/{src → dist}/dataprocessor/basichtmlwriter.d.ts +0 -0
- /package/{src → dist}/dataprocessor/dataprocessor.d.ts +0 -0
- /package/{src → dist}/dataprocessor/htmldataprocessor.d.ts +0 -0
- /package/{src → dist}/dataprocessor/htmlwriter.d.ts +0 -0
- /package/{src → dist}/dataprocessor/xmldataprocessor.d.ts +0 -0
- /package/{src → dist}/dev-utils/model.d.ts +0 -0
- /package/{src → dist}/dev-utils/operationreplayer.d.ts +0 -0
- /package/{src → dist}/dev-utils/utils.d.ts +0 -0
- /package/{src → dist}/dev-utils/view.d.ts +0 -0
- /package/{src → dist}/legacyerrors.d.ts +0 -0
- /package/{src → dist}/model/batch.d.ts +0 -0
- /package/{src → dist}/model/differ.d.ts +0 -0
- /package/{src → dist}/model/document.d.ts +0 -0
- /package/{src → dist}/model/documentfragment.d.ts +0 -0
- /package/{src → dist}/model/documentselection.d.ts +0 -0
- /package/{src → dist}/model/element.d.ts +0 -0
- /package/{src → dist}/model/history.d.ts +0 -0
- /package/{src → dist}/model/item.d.ts +0 -0
- /package/{src → dist}/model/liveposition.d.ts +0 -0
- /package/{src → dist}/model/liverange.d.ts +0 -0
- /package/{src → dist}/model/markercollection.d.ts +0 -0
- /package/{src → dist}/model/node.d.ts +0 -0
- /package/{src → dist}/model/nodelist.d.ts +0 -0
- /package/{src → dist}/model/operation/attributeoperation.d.ts +0 -0
- /package/{src → dist}/model/operation/detachoperation.d.ts +0 -0
- /package/{src → dist}/model/operation/insertoperation.d.ts +0 -0
- /package/{src → dist}/model/operation/markeroperation.d.ts +0 -0
- /package/{src → dist}/model/operation/mergeoperation.d.ts +0 -0
- /package/{src → dist}/model/operation/moveoperation.d.ts +0 -0
- /package/{src → dist}/model/operation/nooperation.d.ts +0 -0
- /package/{src → dist}/model/operation/operation.d.ts +0 -0
- /package/{src → dist}/model/operation/operationfactory.d.ts +0 -0
- /package/{src → dist}/model/operation/renameoperation.d.ts +0 -0
- /package/{src → dist}/model/operation/rootattributeoperation.d.ts +0 -0
- /package/{src → dist}/model/operation/rootoperation.d.ts +0 -0
- /package/{src → dist}/model/operation/splitoperation.d.ts +0 -0
- /package/{src → dist}/model/operation/transform.d.ts +0 -0
- /package/{src → dist}/model/operation/utils.d.ts +0 -0
- /package/{src → dist}/model/position.d.ts +0 -0
- /package/{src → dist}/model/range.d.ts +0 -0
- /package/{src → dist}/model/rootelement.d.ts +0 -0
- /package/{src → dist}/model/schema.d.ts +0 -0
- /package/{src → dist}/model/text.d.ts +0 -0
- /package/{src → dist}/model/textproxy.d.ts +0 -0
- /package/{src → dist}/model/treewalker.d.ts +0 -0
- /package/{src → dist}/model/typecheckable.d.ts +0 -0
- /package/{src → dist}/model/utils/autoparagraphing.d.ts +0 -0
- /package/{src → dist}/model/utils/deletecontent.d.ts +0 -0
- /package/{src → dist}/model/utils/getselectedcontent.d.ts +0 -0
- /package/{src → dist}/model/utils/insertcontent.d.ts +0 -0
- /package/{src → dist}/model/utils/insertobject.d.ts +0 -0
- /package/{src → dist}/model/utils/modifyselection.d.ts +0 -0
- /package/{src → dist}/model/utils/selection-post-fixer.d.ts +0 -0
- /package/{src → dist}/model/writer.d.ts +0 -0
- /package/{src → dist}/view/attributeelement.d.ts +0 -0
- /package/{src → dist}/view/containerelement.d.ts +0 -0
- /package/{src → dist}/view/datatransfer.d.ts +0 -0
- /package/{src → dist}/view/document.d.ts +0 -0
- /package/{src → dist}/view/documentfragment.d.ts +0 -0
- /package/{src → dist}/view/documentselection.d.ts +0 -0
- /package/{src → dist}/view/domconverter.d.ts +0 -0
- /package/{src → dist}/view/editableelement.d.ts +0 -0
- /package/{src → dist}/view/elementdefinition.d.ts +0 -0
- /package/{src → dist}/view/emptyelement.d.ts +0 -0
- /package/{src → dist}/view/filler.d.ts +0 -0
- /package/{src → dist}/view/item.d.ts +0 -0
- /package/{src → dist}/view/node.d.ts +0 -0
- /package/{src → dist}/view/observer/arrowkeysobserver.d.ts +0 -0
- /package/{src → dist}/view/observer/bubblingemittermixin.d.ts +0 -0
- /package/{src → dist}/view/observer/bubblingeventinfo.d.ts +0 -0
- /package/{src → dist}/view/observer/clickobserver.d.ts +0 -0
- /package/{src → dist}/view/observer/compositionobserver.d.ts +0 -0
- /package/{src → dist}/view/observer/domeventdata.d.ts +0 -0
- /package/{src → dist}/view/observer/domeventobserver.d.ts +0 -0
- /package/{src → dist}/view/observer/fakeselectionobserver.d.ts +0 -0
- /package/{src → dist}/view/observer/focusobserver.d.ts +0 -0
- /package/{src → dist}/view/observer/inputobserver.d.ts +0 -0
- /package/{src → dist}/view/observer/keyobserver.d.ts +0 -0
- /package/{src → dist}/view/observer/mouseobserver.d.ts +0 -0
- /package/{src → dist}/view/observer/mutationobserver.d.ts +0 -0
- /package/{src → dist}/view/observer/observer.d.ts +0 -0
- /package/{src → dist}/view/observer/pointerobserver.d.ts +0 -0
- /package/{src → dist}/view/observer/selectionobserver.d.ts +0 -0
- /package/{src → dist}/view/observer/tabobserver.d.ts +0 -0
- /package/{src → dist}/view/observer/touchobserver.d.ts +0 -0
- /package/{src → dist}/view/placeholder.d.ts +0 -0
- /package/{src → dist}/view/position.d.ts +0 -0
- /package/{src → dist}/view/range.d.ts +0 -0
- /package/{src → dist}/view/rawelement.d.ts +0 -0
- /package/{src → dist}/view/renderer.d.ts +0 -0
- /package/{src → dist}/view/rooteditableelement.d.ts +0 -0
- /package/{src → dist}/view/selection.d.ts +0 -0
- /package/{src → dist}/view/stylesmap.d.ts +0 -0
- /package/{src → dist}/view/text.d.ts +0 -0
- /package/{src → dist}/view/textproxy.d.ts +0 -0
- /package/{src → dist}/view/tokenlist.d.ts +0 -0
- /package/{src → dist}/view/treewalker.d.ts +0 -0
- /package/{src → dist}/view/typecheckable.d.ts +0 -0
- /package/{src → dist}/view/uielement.d.ts +0 -0
- /package/{src → dist}/view/upcastwriter.d.ts +0 -0
- /package/{src → dist}/view/view.d.ts +0 -0
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
-
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* @module engine/view/observer/domeventdata
|
|
7
|
-
*/
|
|
8
|
-
import { extend } from 'es-toolkit/compat';
|
|
9
|
-
/**
|
|
10
|
-
* Information about a DOM event in context of the {@link module:engine/view/document~ViewDocument}.
|
|
11
|
-
* It wraps the native event, which usually should not be used as the wrapper contains
|
|
12
|
-
* additional data (like key code for keyboard events).
|
|
13
|
-
*
|
|
14
|
-
* @typeParam TEvent The type of DOM Event that this class represents.
|
|
15
|
-
*/
|
|
16
|
-
export class ViewDocumentDomEventData {
|
|
17
|
-
/**
|
|
18
|
-
* Instance of the view controller.
|
|
19
|
-
*/
|
|
20
|
-
view;
|
|
21
|
-
/**
|
|
22
|
-
* The instance of the document.
|
|
23
|
-
*/
|
|
24
|
-
document;
|
|
25
|
-
/**
|
|
26
|
-
* The DOM event.
|
|
27
|
-
*/
|
|
28
|
-
domEvent;
|
|
29
|
-
/**
|
|
30
|
-
* The DOM target.
|
|
31
|
-
*/
|
|
32
|
-
domTarget;
|
|
33
|
-
/**
|
|
34
|
-
* @param view The instance of the view controller.
|
|
35
|
-
* @param domEvent The DOM event.
|
|
36
|
-
* @param additionalData Additional properties that the instance should contain.
|
|
37
|
-
*/
|
|
38
|
-
constructor(view, domEvent, additionalData) {
|
|
39
|
-
this.view = view;
|
|
40
|
-
this.document = view.document;
|
|
41
|
-
this.domEvent = domEvent;
|
|
42
|
-
this.domTarget = domEvent.target;
|
|
43
|
-
extend(this, additionalData);
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* The tree view element representing the target.
|
|
47
|
-
*/
|
|
48
|
-
get target() {
|
|
49
|
-
return this.view.domConverter.mapDomToView(this.domTarget);
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* Prevents the native's event default action.
|
|
53
|
-
*/
|
|
54
|
-
preventDefault() {
|
|
55
|
-
this.domEvent.preventDefault();
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* Stops native event propagation.
|
|
59
|
-
*/
|
|
60
|
-
stopPropagation() {
|
|
61
|
-
this.domEvent.stopPropagation();
|
|
62
|
-
}
|
|
63
|
-
}
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
-
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* @module engine/view/observer/domeventobserver
|
|
7
|
-
*/
|
|
8
|
-
import { Observer } from './observer.js';
|
|
9
|
-
import { ViewDocumentDomEventData } from './domeventdata.js';
|
|
10
|
-
/**
|
|
11
|
-
* Base class for DOM event observers. This class handles
|
|
12
|
-
* {@link module:engine/view/observer/observer~Observer#observe adding} listeners to DOM elements,
|
|
13
|
-
* {@link module:engine/view/observer/observer~Observer#disable disabling} and
|
|
14
|
-
* {@link module:engine/view/observer/observer~Observer#enable re-enabling} events.
|
|
15
|
-
* Child class needs to define
|
|
16
|
-
* {@link module:engine/view/observer/domeventobserver~DomEventObserver#domEventType DOM event type} and
|
|
17
|
-
* {@link module:engine/view/observer/domeventobserver~DomEventObserver#onDomEvent callback}.
|
|
18
|
-
*
|
|
19
|
-
* For instance:
|
|
20
|
-
*
|
|
21
|
-
* ```ts
|
|
22
|
-
* class ClickObserver extends DomEventObserver<'click'> {
|
|
23
|
-
* // It can also be defined as a normal property in the constructor.
|
|
24
|
-
* get domEventType(): 'click' {
|
|
25
|
-
* return 'click';
|
|
26
|
-
* }
|
|
27
|
-
*
|
|
28
|
-
* onDomEvent( domEvent: MouseEvent ): void {
|
|
29
|
-
* this.fire( 'click', domEvent );
|
|
30
|
-
* }
|
|
31
|
-
* }
|
|
32
|
-
* ```
|
|
33
|
-
*
|
|
34
|
-
* @typeParam EventType DOM Event type name or an union of those.
|
|
35
|
-
* @typeParam AdditionalData Additional data passed along with the event.
|
|
36
|
-
*/
|
|
37
|
-
export class DomEventObserver extends Observer {
|
|
38
|
-
/**
|
|
39
|
-
* If set to `true` DOM events will be listened on the capturing phase.
|
|
40
|
-
* Default value is `false`.
|
|
41
|
-
*/
|
|
42
|
-
useCapture = false;
|
|
43
|
-
/**
|
|
44
|
-
* If set to `true`, indicates that the function specified by listener will never call `preventDefault()`.
|
|
45
|
-
* Default value is `false`.
|
|
46
|
-
*/
|
|
47
|
-
usePassive = false;
|
|
48
|
-
/**
|
|
49
|
-
* @inheritDoc
|
|
50
|
-
*/
|
|
51
|
-
observe(domElement) {
|
|
52
|
-
const types = typeof this.domEventType == 'string' ? [this.domEventType] : this.domEventType;
|
|
53
|
-
types.forEach(type => {
|
|
54
|
-
this.listenTo(domElement, type, (eventInfo, domEvent) => {
|
|
55
|
-
if (this.isEnabled && !this.checkShouldIgnoreEventFromTarget(domEvent.target)) {
|
|
56
|
-
this.onDomEvent(domEvent);
|
|
57
|
-
}
|
|
58
|
-
}, { useCapture: this.useCapture, usePassive: this.usePassive });
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* @inheritDoc
|
|
63
|
-
*/
|
|
64
|
-
stopObserving(domElement) {
|
|
65
|
-
this.stopListening(domElement);
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* Calls `Document#fire()` if observer {@link #isEnabled is enabled}.
|
|
69
|
-
*
|
|
70
|
-
* @see module:utils/emittermixin~Emitter#fire
|
|
71
|
-
* @param eventType The event type (name).
|
|
72
|
-
* @param domEvent The DOM event.
|
|
73
|
-
* @param additionalData The additional data which should extend the
|
|
74
|
-
* {@link module:engine/view/observer/domeventdata~ViewDocumentDomEventData event data} object.
|
|
75
|
-
*/
|
|
76
|
-
fire(eventType, domEvent, additionalData) {
|
|
77
|
-
if (this.isEnabled) {
|
|
78
|
-
this.document.fire(eventType, new ViewDocumentDomEventData(this.view, domEvent, additionalData));
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
}
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
-
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* @module engine/view/observer/fakeselectionobserver
|
|
7
|
-
*/
|
|
8
|
-
import { Observer } from './observer.js';
|
|
9
|
-
import { ViewSelection } from '../selection.js';
|
|
10
|
-
import { keyCodes } from '@ckeditor/ckeditor5-utils';
|
|
11
|
-
import { debounce } from 'es-toolkit/compat';
|
|
12
|
-
/**
|
|
13
|
-
* Fake selection observer class. If view selection is fake it is placed in dummy DOM container. This observer listens
|
|
14
|
-
* on {@link module:engine/view/document~ViewDocument#event:keydown keydown} events and handles moving
|
|
15
|
-
* fake view selection to the correct place if arrow keys are pressed.
|
|
16
|
-
* Fires {@link module:engine/view/document~ViewDocument#event:selectionChange selectionChange event} simulating natural behaviour of
|
|
17
|
-
* {@link module:engine/view/observer/selectionobserver~SelectionObserver SelectionObserver}.
|
|
18
|
-
*/
|
|
19
|
-
export class FakeSelectionObserver extends Observer {
|
|
20
|
-
/**
|
|
21
|
-
* Fires debounced event `selectionChangeDone`. It uses `es-toolkit#debounce` method to delay function call.
|
|
22
|
-
*/
|
|
23
|
-
_fireSelectionChangeDoneDebounced;
|
|
24
|
-
/**
|
|
25
|
-
* Creates new FakeSelectionObserver instance.
|
|
26
|
-
*/
|
|
27
|
-
constructor(view) {
|
|
28
|
-
super(view);
|
|
29
|
-
this._fireSelectionChangeDoneDebounced = debounce(data => {
|
|
30
|
-
this.document.fire('selectionChangeDone', data);
|
|
31
|
-
}, 200);
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* @inheritDoc
|
|
35
|
-
*/
|
|
36
|
-
observe() {
|
|
37
|
-
const document = this.document;
|
|
38
|
-
document.on('arrowKey', (eventInfo, data) => {
|
|
39
|
-
const selection = document.selection;
|
|
40
|
-
if (selection.isFake && this.isEnabled) {
|
|
41
|
-
// Prevents default key down handling - no selection change will occur.
|
|
42
|
-
data.preventDefault();
|
|
43
|
-
}
|
|
44
|
-
}, { context: '$capture' });
|
|
45
|
-
document.on('arrowKey', (eventInfo, data) => {
|
|
46
|
-
const selection = document.selection;
|
|
47
|
-
if (selection.isFake && this.isEnabled) {
|
|
48
|
-
this._handleSelectionMove(data.keyCode);
|
|
49
|
-
}
|
|
50
|
-
}, { priority: 'lowest' });
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* @inheritDoc
|
|
54
|
-
*/
|
|
55
|
-
stopObserving() { }
|
|
56
|
-
/**
|
|
57
|
-
* @inheritDoc
|
|
58
|
-
*/
|
|
59
|
-
destroy() {
|
|
60
|
-
super.destroy();
|
|
61
|
-
this._fireSelectionChangeDoneDebounced.cancel();
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* Handles collapsing view selection according to given key code. If left or up key is provided - new selection will be
|
|
65
|
-
* collapsed to left. If right or down key is pressed - new selection will be collapsed to right.
|
|
66
|
-
*
|
|
67
|
-
* This method fires {@link module:engine/view/document~ViewDocument#event:selectionChange} and
|
|
68
|
-
* {@link module:engine/view/document~ViewDocument#event:selectionChangeDone} events imitating behaviour of
|
|
69
|
-
* {@link module:engine/view/observer/selectionobserver~SelectionObserver}.
|
|
70
|
-
*/
|
|
71
|
-
_handleSelectionMove(keyCode) {
|
|
72
|
-
const selection = this.document.selection;
|
|
73
|
-
const newSelection = new ViewSelection(selection.getRanges(), { backward: selection.isBackward, fake: false });
|
|
74
|
-
// Left or up arrow pressed - move selection to start.
|
|
75
|
-
if (keyCode == keyCodes.arrowleft || keyCode == keyCodes.arrowup) {
|
|
76
|
-
newSelection.setTo(newSelection.getFirstPosition());
|
|
77
|
-
}
|
|
78
|
-
// Right or down arrow pressed - move selection to end.
|
|
79
|
-
if (keyCode == keyCodes.arrowright || keyCode == keyCodes.arrowdown) {
|
|
80
|
-
newSelection.setTo(newSelection.getLastPosition());
|
|
81
|
-
}
|
|
82
|
-
const data = {
|
|
83
|
-
oldSelection: selection,
|
|
84
|
-
newSelection,
|
|
85
|
-
domSelection: null
|
|
86
|
-
};
|
|
87
|
-
// Fire dummy selection change event.
|
|
88
|
-
this.document.fire('selectionChange', data);
|
|
89
|
-
// Call` #_fireSelectionChangeDoneDebounced` every time when `selectionChange` event is fired.
|
|
90
|
-
// This function is debounced what means that `selectionChangeDone` event will be fired only when
|
|
91
|
-
// defined int the function time will elapse since the last time the function was called.
|
|
92
|
-
// So `selectionChangeDone` will be fired when selection will stop changing.
|
|
93
|
-
this._fireSelectionChangeDoneDebounced(data);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
@@ -1,166 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
-
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* @module engine/view/observer/focusobserver
|
|
7
|
-
*/
|
|
8
|
-
import { DomEventObserver } from './domeventobserver.js';
|
|
9
|
-
// @if CK_DEBUG_TYPING // const { _debouncedLine, _buildLogMessage } = require( '../../dev-utils/utils.js' );
|
|
10
|
-
/**
|
|
11
|
-
* {@link module:engine/view/document~ViewDocument#event:focus Focus}
|
|
12
|
-
* and {@link module:engine/view/document~ViewDocument#event:blur blur} events observer.
|
|
13
|
-
* Focus observer handle also {@link module:engine/view/rooteditableelement~ViewRootEditableElement#isFocused isFocused} property of the
|
|
14
|
-
* {@link module:engine/view/rooteditableelement~ViewRootEditableElement root elements}.
|
|
15
|
-
*
|
|
16
|
-
* Note that this observer is attached by the {@link module:engine/view/view~EditingView} and is available by default.
|
|
17
|
-
*/
|
|
18
|
-
export class FocusObserver extends DomEventObserver {
|
|
19
|
-
/**
|
|
20
|
-
* Identifier of the timeout currently used by focus listener to delay rendering execution.
|
|
21
|
-
*/
|
|
22
|
-
_renderTimeoutId = null;
|
|
23
|
-
/**
|
|
24
|
-
* Set to `true` if the document is in the process of setting the focus.
|
|
25
|
-
*
|
|
26
|
-
* The flag is used to indicate that setting the focus is in progress.
|
|
27
|
-
*/
|
|
28
|
-
_isFocusChanging = false;
|
|
29
|
-
/**
|
|
30
|
-
* @inheritDoc
|
|
31
|
-
*/
|
|
32
|
-
domEventType = ['focus', 'blur'];
|
|
33
|
-
/**
|
|
34
|
-
* @inheritDoc
|
|
35
|
-
*/
|
|
36
|
-
constructor(view) {
|
|
37
|
-
super(view);
|
|
38
|
-
this.useCapture = true;
|
|
39
|
-
const document = this.document;
|
|
40
|
-
document.on('focus', () => this._handleFocus());
|
|
41
|
-
document.on('blur', (evt, data) => this._handleBlur(data));
|
|
42
|
-
// Focus the editor in cases where browser dispatches `beforeinput` event to a not-focused editable element.
|
|
43
|
-
// This is flushed by the beforeinput listener in the `InsertTextObserver`.
|
|
44
|
-
// Note that focus is set only if the document is not focused yet.
|
|
45
|
-
// See https://github.com/ckeditor/ckeditor5/issues/14702.
|
|
46
|
-
document.on('beforeinput', () => {
|
|
47
|
-
if (!document.isFocused) {
|
|
48
|
-
this._handleFocus();
|
|
49
|
-
}
|
|
50
|
-
}, { priority: 'highest' });
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Finishes setting the document focus state.
|
|
54
|
-
*/
|
|
55
|
-
flush() {
|
|
56
|
-
if (this._isFocusChanging) {
|
|
57
|
-
// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
|
|
58
|
-
// @if CK_DEBUG_TYPING // _debouncedLine();
|
|
59
|
-
// @if CK_DEBUG_TYPING // console.group( ..._buildLogMessage( this, 'FocusObserver',
|
|
60
|
-
// @if CK_DEBUG_TYPING // 'flush focus'
|
|
61
|
-
// @if CK_DEBUG_TYPING // ) );
|
|
62
|
-
// @if CK_DEBUG_TYPING // }
|
|
63
|
-
this._isFocusChanging = false;
|
|
64
|
-
this.document.isFocused = true;
|
|
65
|
-
// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
|
|
66
|
-
// @if CK_DEBUG_TYPING // console.groupEnd();
|
|
67
|
-
// @if CK_DEBUG_TYPING // }
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* @inheritDoc
|
|
72
|
-
*/
|
|
73
|
-
onDomEvent(domEvent) {
|
|
74
|
-
// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
|
|
75
|
-
// @if CK_DEBUG_TYPING // _debouncedLine();
|
|
76
|
-
// @if CK_DEBUG_TYPING // console.group( ..._buildLogMessage( this, 'FocusObserver',
|
|
77
|
-
// @if CK_DEBUG_TYPING // `${ domEvent.type } event`
|
|
78
|
-
// @if CK_DEBUG_TYPING // ) );
|
|
79
|
-
// @if CK_DEBUG_TYPING // console.info( ..._buildLogMessage( this, 'FocusObserver',
|
|
80
|
-
// @if CK_DEBUG_TYPING // 'DOM target:',
|
|
81
|
-
// @if CK_DEBUG_TYPING // { target: domEvent.target, relatedTarget: domEvent.relatedTarget }
|
|
82
|
-
// @if CK_DEBUG_TYPING // ) );
|
|
83
|
-
// @if CK_DEBUG_TYPING // const domSelection = window.getSelection();
|
|
84
|
-
// @if CK_DEBUG_TYPING // console.info( ..._buildLogMessage( this, 'FocusObserver',
|
|
85
|
-
// @if CK_DEBUG_TYPING // 'DOM Selection:',
|
|
86
|
-
// @if CK_DEBUG_TYPING // { node: domSelection!.anchorNode, offset: domSelection!.anchorOffset },
|
|
87
|
-
// @if CK_DEBUG_TYPING // { node: domSelection!.focusNode, offset: domSelection!.focusOffset }
|
|
88
|
-
// @if CK_DEBUG_TYPING // ) );
|
|
89
|
-
// @if CK_DEBUG_TYPING // }
|
|
90
|
-
this.fire(domEvent.type, domEvent);
|
|
91
|
-
// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
|
|
92
|
-
// @if CK_DEBUG_TYPING // console.groupEnd();
|
|
93
|
-
// @if CK_DEBUG_TYPING // }
|
|
94
|
-
}
|
|
95
|
-
/**
|
|
96
|
-
* @inheritDoc
|
|
97
|
-
*/
|
|
98
|
-
destroy() {
|
|
99
|
-
this._clearTimeout();
|
|
100
|
-
super.destroy();
|
|
101
|
-
}
|
|
102
|
-
/**
|
|
103
|
-
* The `focus` event handler.
|
|
104
|
-
*/
|
|
105
|
-
_handleFocus() {
|
|
106
|
-
this._clearTimeout();
|
|
107
|
-
this._isFocusChanging = true;
|
|
108
|
-
// Unfortunately native `selectionchange` event is fired asynchronously.
|
|
109
|
-
// We need to wait until `SelectionObserver` handle the event and then render. Otherwise rendering will
|
|
110
|
-
// overwrite new DOM selection with selection from the view.
|
|
111
|
-
// See https://github.com/ckeditor/ckeditor5-engine/issues/795 for more details.
|
|
112
|
-
// Long timeout is needed to solve #676 and https://github.com/ckeditor/ckeditor5-engine/issues/1157 issues.
|
|
113
|
-
//
|
|
114
|
-
// Using `view.change()` instead of `view.forceRender()` to prevent double rendering
|
|
115
|
-
// in a situation where `selectionchange` already caused selection change.
|
|
116
|
-
this._renderTimeoutId = setTimeout(() => {
|
|
117
|
-
this._renderTimeoutId = null;
|
|
118
|
-
// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
|
|
119
|
-
// @if CK_DEBUG_TYPING // console.group( ..._buildLogMessage( this, 'FocusObserver',
|
|
120
|
-
// @if CK_DEBUG_TYPING // 'flush on timeout'
|
|
121
|
-
// @if CK_DEBUG_TYPING // ) );
|
|
122
|
-
// @if CK_DEBUG_TYPING // }
|
|
123
|
-
this.flush();
|
|
124
|
-
this.view.change(() => { });
|
|
125
|
-
// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
|
|
126
|
-
// @if CK_DEBUG_TYPING // console.groupEnd();
|
|
127
|
-
// @if CK_DEBUG_TYPING // }
|
|
128
|
-
}, 50);
|
|
129
|
-
}
|
|
130
|
-
/**
|
|
131
|
-
* The `blur` event handler.
|
|
132
|
-
*/
|
|
133
|
-
_handleBlur(data) {
|
|
134
|
-
const selectedEditable = this.document.selection.editableElement;
|
|
135
|
-
// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
|
|
136
|
-
// @if CK_DEBUG_TYPING // console.info( ..._buildLogMessage( this, 'FocusObserver',
|
|
137
|
-
// @if CK_DEBUG_TYPING // 'selectedEditable:',
|
|
138
|
-
// @if CK_DEBUG_TYPING // { selectedEditable }
|
|
139
|
-
// @if CK_DEBUG_TYPING // ) );
|
|
140
|
-
// @if CK_DEBUG_TYPING // }
|
|
141
|
-
if (selectedEditable === null || selectedEditable === data.target) {
|
|
142
|
-
// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
|
|
143
|
-
// @if CK_DEBUG_TYPING // console.group( ..._buildLogMessage( this, 'FocusObserver',
|
|
144
|
-
// @if CK_DEBUG_TYPING // 'document no longer focused'
|
|
145
|
-
// @if CK_DEBUG_TYPING // ) );
|
|
146
|
-
// @if CK_DEBUG_TYPING // }
|
|
147
|
-
this.document.isFocused = false;
|
|
148
|
-
this._isFocusChanging = false;
|
|
149
|
-
// Re-render the document to update view elements
|
|
150
|
-
// (changing document.isFocused already marked view as changed since last rendering).
|
|
151
|
-
this.view.change(() => { });
|
|
152
|
-
// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
|
|
153
|
-
// @if CK_DEBUG_TYPING // console.groupEnd();
|
|
154
|
-
// @if CK_DEBUG_TYPING // }
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
/**
|
|
158
|
-
* Clears timeout.
|
|
159
|
-
*/
|
|
160
|
-
_clearTimeout() {
|
|
161
|
-
if (this._renderTimeoutId) {
|
|
162
|
-
clearTimeout(this._renderTimeoutId);
|
|
163
|
-
this._renderTimeoutId = null;
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
}
|
|
@@ -1,236 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
-
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* @module engine/view/observer/inputobserver
|
|
7
|
-
*/
|
|
8
|
-
import { DomEventObserver } from './domeventobserver.js';
|
|
9
|
-
import { ViewDataTransfer } from '../datatransfer.js';
|
|
10
|
-
import { env, isText, indexOf } from '@ckeditor/ckeditor5-utils';
|
|
11
|
-
import { INLINE_FILLER_LENGTH, startsWithFiller } from '../filler.js';
|
|
12
|
-
// @if CK_DEBUG_TYPING // const { _debouncedLine, _buildLogMessage } = require( '../../dev-utils/utils.js' );
|
|
13
|
-
/**
|
|
14
|
-
* Observer for events connected with data input.
|
|
15
|
-
*
|
|
16
|
-
* **Note**: This observer is attached by {@link module:engine/view/view~EditingView} and available by default in all
|
|
17
|
-
* editor instances.
|
|
18
|
-
*/
|
|
19
|
-
export class InputObserver extends DomEventObserver {
|
|
20
|
-
/**
|
|
21
|
-
* @inheritDoc
|
|
22
|
-
*/
|
|
23
|
-
domEventType = 'beforeinput';
|
|
24
|
-
/**
|
|
25
|
-
* @inheritDoc
|
|
26
|
-
*/
|
|
27
|
-
onDomEvent(domEvent) {
|
|
28
|
-
// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
|
|
29
|
-
// @if CK_DEBUG_TYPING // _debouncedLine();
|
|
30
|
-
// @if CK_DEBUG_TYPING // console.group( ..._buildLogMessage( this, 'InputObserver',
|
|
31
|
-
// @if CK_DEBUG_TYPING // `${ domEvent.type }: ${ domEvent.inputType } - ${ domEvent.isComposing ? 'is' : 'not' } composing`,
|
|
32
|
-
// @if CK_DEBUG_TYPING // ) );
|
|
33
|
-
// @if CK_DEBUG_TYPING // }
|
|
34
|
-
const domTargetRanges = domEvent.getTargetRanges();
|
|
35
|
-
const view = this.view;
|
|
36
|
-
const viewDocument = view.document;
|
|
37
|
-
let dataTransfer = null;
|
|
38
|
-
let data = null;
|
|
39
|
-
let targetRanges = [];
|
|
40
|
-
if (domEvent.dataTransfer) {
|
|
41
|
-
dataTransfer = new ViewDataTransfer(domEvent.dataTransfer);
|
|
42
|
-
}
|
|
43
|
-
if (domEvent.data !== null) {
|
|
44
|
-
data = domEvent.data;
|
|
45
|
-
// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
|
|
46
|
-
// @if CK_DEBUG_TYPING // console.info( ..._buildLogMessage( this, 'InputObserver',
|
|
47
|
-
// @if CK_DEBUG_TYPING // `%cevent data: %c${ JSON.stringify( data ) }`,
|
|
48
|
-
// @if CK_DEBUG_TYPING // 'font-weight: bold',
|
|
49
|
-
// @if CK_DEBUG_TYPING // 'color: blue;'
|
|
50
|
-
// @if CK_DEBUG_TYPING // ) );
|
|
51
|
-
// @if CK_DEBUG_TYPING // }
|
|
52
|
-
}
|
|
53
|
-
else if (dataTransfer) {
|
|
54
|
-
data = dataTransfer.getData('text/plain');
|
|
55
|
-
// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
|
|
56
|
-
// @if CK_DEBUG_TYPING // console.info( ..._buildLogMessage( this, 'InputObserver',
|
|
57
|
-
// @if CK_DEBUG_TYPING // `%cevent data transfer: %c${ JSON.stringify( data ) }`,
|
|
58
|
-
// @if CK_DEBUG_TYPING // 'font-weight: bold',
|
|
59
|
-
// @if CK_DEBUG_TYPING // 'color: blue;'
|
|
60
|
-
// @if CK_DEBUG_TYPING // ) );
|
|
61
|
-
// @if CK_DEBUG_TYPING // }
|
|
62
|
-
}
|
|
63
|
-
// If the editor selection is fake (an object is selected), the DOM range does not make sense because it is anchored
|
|
64
|
-
// in the fake selection container.
|
|
65
|
-
if (viewDocument.selection.isFake) {
|
|
66
|
-
// Future-proof: in case of multi-range fake selections being possible.
|
|
67
|
-
targetRanges = Array.from(viewDocument.selection.getRanges());
|
|
68
|
-
// Do not allow typing inside a fake selection container, we will handle it manually.
|
|
69
|
-
domEvent.preventDefault();
|
|
70
|
-
// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
|
|
71
|
-
// @if CK_DEBUG_TYPING // console.info( ..._buildLogMessage( this, 'InputObserver',
|
|
72
|
-
// @if CK_DEBUG_TYPING // '%cusing fake selection:',
|
|
73
|
-
// @if CK_DEBUG_TYPING // 'font-weight: bold',
|
|
74
|
-
// @if CK_DEBUG_TYPING // targetRanges,
|
|
75
|
-
// @if CK_DEBUG_TYPING // viewDocument.selection.isFake ? 'fake view selection' : 'fake DOM parent'
|
|
76
|
-
// @if CK_DEBUG_TYPING // ) );
|
|
77
|
-
// @if CK_DEBUG_TYPING // }
|
|
78
|
-
}
|
|
79
|
-
else if (domTargetRanges.length) {
|
|
80
|
-
targetRanges = domTargetRanges.map(domRange => {
|
|
81
|
-
// Sometimes browser provides range that starts before editable node.
|
|
82
|
-
// We try to fall back to collapsed range at the valid end position.
|
|
83
|
-
// See https://github.com/ckeditor/ckeditor5/issues/14411.
|
|
84
|
-
// See https://github.com/ckeditor/ckeditor5/issues/14050.
|
|
85
|
-
let viewStart = view.domConverter.domPositionToView(domRange.startContainer, domRange.startOffset);
|
|
86
|
-
const viewEnd = view.domConverter.domPositionToView(domRange.endContainer, domRange.endOffset);
|
|
87
|
-
// When text replacement is enabled and browser tries to replace double space with dot, and space,
|
|
88
|
-
// but the first space is no longer where browser put it (it was moved to an attribute element),
|
|
89
|
-
// then we must extend the target range so it does not include a part of an inline filler.
|
|
90
|
-
if (viewStart && startsWithFiller(domRange.startContainer) && domRange.startOffset < INLINE_FILLER_LENGTH) {
|
|
91
|
-
// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
|
|
92
|
-
// @if CK_DEBUG_TYPING // console.info( ..._buildLogMessage( this, 'InputObserver',
|
|
93
|
-
// @if CK_DEBUG_TYPING // '%cTarget range starts in an inline filler - adjusting it',
|
|
94
|
-
// @if CK_DEBUG_TYPING // 'font-style: italic'
|
|
95
|
-
// @if CK_DEBUG_TYPING // ) );
|
|
96
|
-
// @if CK_DEBUG_TYPING // }
|
|
97
|
-
domEvent.preventDefault();
|
|
98
|
-
let count = INLINE_FILLER_LENGTH - domRange.startOffset;
|
|
99
|
-
viewStart = viewStart.getLastMatchingPosition(value => {
|
|
100
|
-
// Ignore attribute and UI elements but stop on container elements.
|
|
101
|
-
if (value.item.is('attributeElement') || value.item.is('uiElement')) {
|
|
102
|
-
return true;
|
|
103
|
-
}
|
|
104
|
-
// Skip as many characters as inline filler was overlapped.
|
|
105
|
-
if (value.item.is('$textProxy') && count--) {
|
|
106
|
-
return true;
|
|
107
|
-
}
|
|
108
|
-
return false;
|
|
109
|
-
}, { direction: 'backward', singleCharacters: true });
|
|
110
|
-
}
|
|
111
|
-
// Check if there is no an inline filler just after the target range.
|
|
112
|
-
if (isFollowedByInlineFiller(domRange.endContainer, domRange.endOffset)) {
|
|
113
|
-
// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
|
|
114
|
-
// @if CK_DEBUG_TYPING // console.info( ..._buildLogMessage( this, 'InputObserver',
|
|
115
|
-
// @if CK_DEBUG_TYPING // '%cTarget range ends just before an inline filler - prevent default behavior',
|
|
116
|
-
// @if CK_DEBUG_TYPING // 'font-style: italic'
|
|
117
|
-
// @if CK_DEBUG_TYPING // ) );
|
|
118
|
-
// @if CK_DEBUG_TYPING // }
|
|
119
|
-
domEvent.preventDefault();
|
|
120
|
-
}
|
|
121
|
-
if (viewStart) {
|
|
122
|
-
return view.createRange(viewStart, viewEnd);
|
|
123
|
-
}
|
|
124
|
-
else if (viewEnd) {
|
|
125
|
-
return view.createRange(viewEnd);
|
|
126
|
-
}
|
|
127
|
-
}).filter((range) => !!range);
|
|
128
|
-
// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
|
|
129
|
-
// @if CK_DEBUG_TYPING // console.info( ..._buildLogMessage( this, 'InputObserver',
|
|
130
|
-
// @if CK_DEBUG_TYPING // '%cusing target ranges:',
|
|
131
|
-
// @if CK_DEBUG_TYPING // 'font-weight: bold',
|
|
132
|
-
// @if CK_DEBUG_TYPING // targetRanges
|
|
133
|
-
// @if CK_DEBUG_TYPING // ) );
|
|
134
|
-
// @if CK_DEBUG_TYPING // }
|
|
135
|
-
}
|
|
136
|
-
// For Android devices we use a fallback to the current DOM selection, Android modifies it according
|
|
137
|
-
// to the expected target ranges of input event.
|
|
138
|
-
else if (env.isAndroid) {
|
|
139
|
-
const domSelection = domEvent.target.ownerDocument.defaultView.getSelection();
|
|
140
|
-
targetRanges = Array.from(view.domConverter.domSelectionToView(domSelection).getRanges());
|
|
141
|
-
// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
|
|
142
|
-
// @if CK_DEBUG_TYPING // console.info( ..._buildLogMessage( this, 'InputObserver',
|
|
143
|
-
// @if CK_DEBUG_TYPING // '%cusing selection ranges:',
|
|
144
|
-
// @if CK_DEBUG_TYPING // 'font-weight: bold',
|
|
145
|
-
// @if CK_DEBUG_TYPING // targetRanges
|
|
146
|
-
// @if CK_DEBUG_TYPING // ) );
|
|
147
|
-
// @if CK_DEBUG_TYPING // }
|
|
148
|
-
}
|
|
149
|
-
// Android sometimes fires insertCompositionText with a new-line character at the end of the data
|
|
150
|
-
// instead of firing insertParagraph beforeInput event.
|
|
151
|
-
// Fire the correct type of beforeInput event and ignore the replaced fragment of text because
|
|
152
|
-
// it wants to replace "test" with "test\n".
|
|
153
|
-
// https://github.com/ckeditor/ckeditor5/issues/12368.
|
|
154
|
-
if (env.isAndroid && domEvent.inputType == 'insertCompositionText' && data && data.endsWith('\n')) {
|
|
155
|
-
this.fire(domEvent.type, domEvent, {
|
|
156
|
-
inputType: 'insertParagraph',
|
|
157
|
-
targetRanges: [view.createRange(targetRanges[0].end)]
|
|
158
|
-
});
|
|
159
|
-
// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
|
|
160
|
-
// @if CK_DEBUG_TYPING // console.groupEnd();
|
|
161
|
-
// @if CK_DEBUG_TYPING // }
|
|
162
|
-
return;
|
|
163
|
-
}
|
|
164
|
-
// Normalize the insertText data that includes new-line characters.
|
|
165
|
-
// https://github.com/ckeditor/ckeditor5/issues/2045.
|
|
166
|
-
if (['insertText', 'insertReplacementText'].includes(domEvent.inputType) && data && data.includes('\n')) {
|
|
167
|
-
// There might be a single new-line or double for new paragraph, but we translate
|
|
168
|
-
// it to paragraphs as it is our default action for enter handling.
|
|
169
|
-
const parts = data.split(/\n{1,2}/g);
|
|
170
|
-
let partTargetRanges = targetRanges;
|
|
171
|
-
// Handle all parts on our side as we rely on paragraph inserting and synchronously updated view selection.
|
|
172
|
-
domEvent.preventDefault();
|
|
173
|
-
for (let i = 0; i < parts.length; i++) {
|
|
174
|
-
const dataPart = parts[i];
|
|
175
|
-
if (dataPart != '') {
|
|
176
|
-
this.fire(domEvent.type, domEvent, {
|
|
177
|
-
data: dataPart,
|
|
178
|
-
dataTransfer,
|
|
179
|
-
targetRanges: partTargetRanges,
|
|
180
|
-
inputType: domEvent.inputType,
|
|
181
|
-
isComposing: domEvent.isComposing
|
|
182
|
-
});
|
|
183
|
-
// Use the result view selection so following events will be added one after another.
|
|
184
|
-
partTargetRanges = [viewDocument.selection.getFirstRange()];
|
|
185
|
-
}
|
|
186
|
-
if (i + 1 < parts.length) {
|
|
187
|
-
this.fire(domEvent.type, domEvent, {
|
|
188
|
-
inputType: 'insertParagraph',
|
|
189
|
-
targetRanges: partTargetRanges
|
|
190
|
-
});
|
|
191
|
-
// Use the result view selection so following events will be added one after another.
|
|
192
|
-
partTargetRanges = [viewDocument.selection.getFirstRange()];
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
|
|
196
|
-
// @if CK_DEBUG_TYPING // console.groupEnd();
|
|
197
|
-
// @if CK_DEBUG_TYPING // }
|
|
198
|
-
return;
|
|
199
|
-
}
|
|
200
|
-
// Fire the normalized beforeInput event.
|
|
201
|
-
this.fire(domEvent.type, domEvent, {
|
|
202
|
-
data,
|
|
203
|
-
dataTransfer,
|
|
204
|
-
targetRanges,
|
|
205
|
-
inputType: domEvent.inputType,
|
|
206
|
-
isComposing: domEvent.isComposing
|
|
207
|
-
});
|
|
208
|
-
// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
|
|
209
|
-
// @if CK_DEBUG_TYPING // console.groupEnd();
|
|
210
|
-
// @if CK_DEBUG_TYPING // }
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
/**
|
|
214
|
-
* Returns `true` if there is an inline filler just after the position in DOM.
|
|
215
|
-
* It walks up the DOM tree if the offset is at the end of the node.
|
|
216
|
-
*/
|
|
217
|
-
function isFollowedByInlineFiller(node, offset) {
|
|
218
|
-
while (node.parentNode) {
|
|
219
|
-
if (isText(node)) {
|
|
220
|
-
if (offset != node.data.length) {
|
|
221
|
-
return false;
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
else {
|
|
225
|
-
if (offset != node.childNodes.length) {
|
|
226
|
-
return false;
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
offset = indexOf(node) + 1;
|
|
230
|
-
node = node.parentNode;
|
|
231
|
-
if (offset < node.childNodes.length && startsWithFiller(node.childNodes[offset])) {
|
|
232
|
-
return true;
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
return false;
|
|
236
|
-
}
|