@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.
Files changed (258) hide show
  1. package/LICENSE.md +1 -1
  2. package/{src → dist}/engineconfig.d.ts +6 -15
  3. package/dist/index-editor.css +38 -15
  4. package/dist/index.css +37 -37
  5. package/dist/index.css.map +1 -1
  6. package/{src → dist}/index.d.ts +0 -1
  7. package/dist/index.js +588 -94
  8. package/dist/index.js.map +1 -1
  9. package/{src → dist}/model/model.d.ts +10 -4
  10. package/{src → dist}/model/selection.d.ts +1 -1
  11. package/{src → dist}/view/downcastwriter.d.ts +3 -2
  12. package/{src → dist}/view/element.d.ts +2 -2
  13. package/{src → dist}/view/matcher.d.ts +4 -2
  14. package/dist/view/styles/background.d.ts +18 -0
  15. package/{src → dist}/view/styles/border.d.ts +0 -12
  16. package/{src → dist}/view/styles/margin.d.ts +0 -13
  17. package/{src → dist}/view/styles/padding.d.ts +0 -13
  18. package/{src → dist}/view/styles/utils.d.ts +12 -0
  19. package/package.json +20 -39
  20. package/src/controller/datacontroller.js +0 -522
  21. package/src/controller/editingcontroller.js +0 -181
  22. package/src/conversion/conversion.js +0 -606
  23. package/src/conversion/conversionhelpers.js +0 -33
  24. package/src/conversion/downcastdispatcher.js +0 -563
  25. package/src/conversion/downcasthelpers.js +0 -2160
  26. package/src/conversion/mapper.js +0 -1050
  27. package/src/conversion/modelconsumable.js +0 -331
  28. package/src/conversion/upcastdispatcher.js +0 -470
  29. package/src/conversion/upcasthelpers.js +0 -952
  30. package/src/conversion/viewconsumable.js +0 -541
  31. package/src/dataprocessor/basichtmlwriter.js +0 -22
  32. package/src/dataprocessor/dataprocessor.js +0 -5
  33. package/src/dataprocessor/htmldataprocessor.js +0 -107
  34. package/src/dataprocessor/htmlwriter.js +0 -5
  35. package/src/dataprocessor/xmldataprocessor.js +0 -127
  36. package/src/dev-utils/model.js +0 -396
  37. package/src/dev-utils/operationreplayer.js +0 -116
  38. package/src/dev-utils/utils.js +0 -122
  39. package/src/dev-utils/view.js +0 -990
  40. package/src/engineconfig.js +0 -5
  41. package/src/index.js +0 -134
  42. package/src/legacyerrors.js +0 -17
  43. package/src/model/batch.js +0 -98
  44. package/src/model/differ.js +0 -1288
  45. package/src/model/document.js +0 -398
  46. package/src/model/documentfragment.js +0 -332
  47. package/src/model/documentselection.js +0 -1026
  48. package/src/model/element.js +0 -323
  49. package/src/model/history.js +0 -206
  50. package/src/model/item.js +0 -5
  51. package/src/model/liveposition.js +0 -93
  52. package/src/model/liverange.js +0 -121
  53. package/src/model/markercollection.js +0 -436
  54. package/src/model/model.js +0 -866
  55. package/src/model/node.js +0 -371
  56. package/src/model/nodelist.js +0 -244
  57. package/src/model/operation/attributeoperation.js +0 -172
  58. package/src/model/operation/detachoperation.js +0 -87
  59. package/src/model/operation/insertoperation.js +0 -153
  60. package/src/model/operation/markeroperation.js +0 -136
  61. package/src/model/operation/mergeoperation.js +0 -184
  62. package/src/model/operation/moveoperation.js +0 -179
  63. package/src/model/operation/nooperation.js +0 -48
  64. package/src/model/operation/operation.js +0 -78
  65. package/src/model/operation/operationfactory.js +0 -44
  66. package/src/model/operation/renameoperation.js +0 -128
  67. package/src/model/operation/rootattributeoperation.js +0 -173
  68. package/src/model/operation/rootoperation.js +0 -106
  69. package/src/model/operation/splitoperation.js +0 -214
  70. package/src/model/operation/transform.js +0 -2211
  71. package/src/model/operation/utils.js +0 -217
  72. package/src/model/position.js +0 -1041
  73. package/src/model/range.js +0 -880
  74. package/src/model/rootelement.js +0 -82
  75. package/src/model/schema.js +0 -1542
  76. package/src/model/selection.js +0 -814
  77. package/src/model/text.js +0 -92
  78. package/src/model/textproxy.js +0 -202
  79. package/src/model/treewalker.js +0 -313
  80. package/src/model/typecheckable.js +0 -16
  81. package/src/model/utils/autoparagraphing.js +0 -63
  82. package/src/model/utils/deletecontent.js +0 -509
  83. package/src/model/utils/getselectedcontent.js +0 -126
  84. package/src/model/utils/insertcontent.js +0 -750
  85. package/src/model/utils/insertobject.js +0 -135
  86. package/src/model/utils/modifyselection.js +0 -187
  87. package/src/model/utils/selection-post-fixer.js +0 -264
  88. package/src/model/writer.js +0 -1318
  89. package/src/view/attributeelement.js +0 -220
  90. package/src/view/containerelement.js +0 -91
  91. package/src/view/datatransfer.js +0 -106
  92. package/src/view/document.js +0 -139
  93. package/src/view/documentfragment.js +0 -251
  94. package/src/view/documentselection.js +0 -270
  95. package/src/view/domconverter.js +0 -1661
  96. package/src/view/downcastwriter.js +0 -1589
  97. package/src/view/editableelement.js +0 -74
  98. package/src/view/element.js +0 -1053
  99. package/src/view/elementdefinition.js +0 -5
  100. package/src/view/emptyelement.js +0 -83
  101. package/src/view/filler.js +0 -161
  102. package/src/view/item.js +0 -5
  103. package/src/view/matcher.js +0 -437
  104. package/src/view/node.js +0 -238
  105. package/src/view/observer/arrowkeysobserver.js +0 -40
  106. package/src/view/observer/bubblingemittermixin.js +0 -215
  107. package/src/view/observer/bubblingeventinfo.js +0 -49
  108. package/src/view/observer/clickobserver.js +0 -26
  109. package/src/view/observer/compositionobserver.js +0 -64
  110. package/src/view/observer/domeventdata.js +0 -63
  111. package/src/view/observer/domeventobserver.js +0 -81
  112. package/src/view/observer/fakeselectionobserver.js +0 -95
  113. package/src/view/observer/focusobserver.js +0 -166
  114. package/src/view/observer/inputobserver.js +0 -236
  115. package/src/view/observer/keyobserver.js +0 -36
  116. package/src/view/observer/mouseobserver.js +0 -26
  117. package/src/view/observer/mutationobserver.js +0 -219
  118. package/src/view/observer/observer.js +0 -92
  119. package/src/view/observer/pointerobserver.js +0 -26
  120. package/src/view/observer/selectionobserver.js +0 -318
  121. package/src/view/observer/tabobserver.js +0 -42
  122. package/src/view/observer/touchobserver.js +0 -26
  123. package/src/view/placeholder.js +0 -285
  124. package/src/view/position.js +0 -341
  125. package/src/view/range.js +0 -451
  126. package/src/view/rawelement.js +0 -115
  127. package/src/view/renderer.js +0 -1148
  128. package/src/view/rooteditableelement.js +0 -78
  129. package/src/view/selection.js +0 -594
  130. package/src/view/styles/background.d.ts +0 -33
  131. package/src/view/styles/background.js +0 -74
  132. package/src/view/styles/border.js +0 -316
  133. package/src/view/styles/margin.js +0 -34
  134. package/src/view/styles/padding.js +0 -34
  135. package/src/view/styles/utils.js +0 -219
  136. package/src/view/stylesmap.js +0 -941
  137. package/src/view/text.js +0 -110
  138. package/src/view/textproxy.js +0 -136
  139. package/src/view/tokenlist.js +0 -194
  140. package/src/view/treewalker.js +0 -389
  141. package/src/view/typecheckable.js +0 -19
  142. package/src/view/uielement.js +0 -194
  143. package/src/view/upcastwriter.js +0 -363
  144. package/src/view/view.js +0 -579
  145. package/theme/placeholder.css +0 -36
  146. package/theme/renderer.css +0 -9
  147. /package/{src → dist}/controller/datacontroller.d.ts +0 -0
  148. /package/{src → dist}/controller/editingcontroller.d.ts +0 -0
  149. /package/{src → dist}/conversion/conversion.d.ts +0 -0
  150. /package/{src → dist}/conversion/conversionhelpers.d.ts +0 -0
  151. /package/{src → dist}/conversion/downcastdispatcher.d.ts +0 -0
  152. /package/{src → dist}/conversion/downcasthelpers.d.ts +0 -0
  153. /package/{src → dist}/conversion/mapper.d.ts +0 -0
  154. /package/{src → dist}/conversion/modelconsumable.d.ts +0 -0
  155. /package/{src → dist}/conversion/upcastdispatcher.d.ts +0 -0
  156. /package/{src → dist}/conversion/upcasthelpers.d.ts +0 -0
  157. /package/{src → dist}/conversion/viewconsumable.d.ts +0 -0
  158. /package/{src → dist}/dataprocessor/basichtmlwriter.d.ts +0 -0
  159. /package/{src → dist}/dataprocessor/dataprocessor.d.ts +0 -0
  160. /package/{src → dist}/dataprocessor/htmldataprocessor.d.ts +0 -0
  161. /package/{src → dist}/dataprocessor/htmlwriter.d.ts +0 -0
  162. /package/{src → dist}/dataprocessor/xmldataprocessor.d.ts +0 -0
  163. /package/{src → dist}/dev-utils/model.d.ts +0 -0
  164. /package/{src → dist}/dev-utils/operationreplayer.d.ts +0 -0
  165. /package/{src → dist}/dev-utils/utils.d.ts +0 -0
  166. /package/{src → dist}/dev-utils/view.d.ts +0 -0
  167. /package/{src → dist}/legacyerrors.d.ts +0 -0
  168. /package/{src → dist}/model/batch.d.ts +0 -0
  169. /package/{src → dist}/model/differ.d.ts +0 -0
  170. /package/{src → dist}/model/document.d.ts +0 -0
  171. /package/{src → dist}/model/documentfragment.d.ts +0 -0
  172. /package/{src → dist}/model/documentselection.d.ts +0 -0
  173. /package/{src → dist}/model/element.d.ts +0 -0
  174. /package/{src → dist}/model/history.d.ts +0 -0
  175. /package/{src → dist}/model/item.d.ts +0 -0
  176. /package/{src → dist}/model/liveposition.d.ts +0 -0
  177. /package/{src → dist}/model/liverange.d.ts +0 -0
  178. /package/{src → dist}/model/markercollection.d.ts +0 -0
  179. /package/{src → dist}/model/node.d.ts +0 -0
  180. /package/{src → dist}/model/nodelist.d.ts +0 -0
  181. /package/{src → dist}/model/operation/attributeoperation.d.ts +0 -0
  182. /package/{src → dist}/model/operation/detachoperation.d.ts +0 -0
  183. /package/{src → dist}/model/operation/insertoperation.d.ts +0 -0
  184. /package/{src → dist}/model/operation/markeroperation.d.ts +0 -0
  185. /package/{src → dist}/model/operation/mergeoperation.d.ts +0 -0
  186. /package/{src → dist}/model/operation/moveoperation.d.ts +0 -0
  187. /package/{src → dist}/model/operation/nooperation.d.ts +0 -0
  188. /package/{src → dist}/model/operation/operation.d.ts +0 -0
  189. /package/{src → dist}/model/operation/operationfactory.d.ts +0 -0
  190. /package/{src → dist}/model/operation/renameoperation.d.ts +0 -0
  191. /package/{src → dist}/model/operation/rootattributeoperation.d.ts +0 -0
  192. /package/{src → dist}/model/operation/rootoperation.d.ts +0 -0
  193. /package/{src → dist}/model/operation/splitoperation.d.ts +0 -0
  194. /package/{src → dist}/model/operation/transform.d.ts +0 -0
  195. /package/{src → dist}/model/operation/utils.d.ts +0 -0
  196. /package/{src → dist}/model/position.d.ts +0 -0
  197. /package/{src → dist}/model/range.d.ts +0 -0
  198. /package/{src → dist}/model/rootelement.d.ts +0 -0
  199. /package/{src → dist}/model/schema.d.ts +0 -0
  200. /package/{src → dist}/model/text.d.ts +0 -0
  201. /package/{src → dist}/model/textproxy.d.ts +0 -0
  202. /package/{src → dist}/model/treewalker.d.ts +0 -0
  203. /package/{src → dist}/model/typecheckable.d.ts +0 -0
  204. /package/{src → dist}/model/utils/autoparagraphing.d.ts +0 -0
  205. /package/{src → dist}/model/utils/deletecontent.d.ts +0 -0
  206. /package/{src → dist}/model/utils/getselectedcontent.d.ts +0 -0
  207. /package/{src → dist}/model/utils/insertcontent.d.ts +0 -0
  208. /package/{src → dist}/model/utils/insertobject.d.ts +0 -0
  209. /package/{src → dist}/model/utils/modifyselection.d.ts +0 -0
  210. /package/{src → dist}/model/utils/selection-post-fixer.d.ts +0 -0
  211. /package/{src → dist}/model/writer.d.ts +0 -0
  212. /package/{src → dist}/view/attributeelement.d.ts +0 -0
  213. /package/{src → dist}/view/containerelement.d.ts +0 -0
  214. /package/{src → dist}/view/datatransfer.d.ts +0 -0
  215. /package/{src → dist}/view/document.d.ts +0 -0
  216. /package/{src → dist}/view/documentfragment.d.ts +0 -0
  217. /package/{src → dist}/view/documentselection.d.ts +0 -0
  218. /package/{src → dist}/view/domconverter.d.ts +0 -0
  219. /package/{src → dist}/view/editableelement.d.ts +0 -0
  220. /package/{src → dist}/view/elementdefinition.d.ts +0 -0
  221. /package/{src → dist}/view/emptyelement.d.ts +0 -0
  222. /package/{src → dist}/view/filler.d.ts +0 -0
  223. /package/{src → dist}/view/item.d.ts +0 -0
  224. /package/{src → dist}/view/node.d.ts +0 -0
  225. /package/{src → dist}/view/observer/arrowkeysobserver.d.ts +0 -0
  226. /package/{src → dist}/view/observer/bubblingemittermixin.d.ts +0 -0
  227. /package/{src → dist}/view/observer/bubblingeventinfo.d.ts +0 -0
  228. /package/{src → dist}/view/observer/clickobserver.d.ts +0 -0
  229. /package/{src → dist}/view/observer/compositionobserver.d.ts +0 -0
  230. /package/{src → dist}/view/observer/domeventdata.d.ts +0 -0
  231. /package/{src → dist}/view/observer/domeventobserver.d.ts +0 -0
  232. /package/{src → dist}/view/observer/fakeselectionobserver.d.ts +0 -0
  233. /package/{src → dist}/view/observer/focusobserver.d.ts +0 -0
  234. /package/{src → dist}/view/observer/inputobserver.d.ts +0 -0
  235. /package/{src → dist}/view/observer/keyobserver.d.ts +0 -0
  236. /package/{src → dist}/view/observer/mouseobserver.d.ts +0 -0
  237. /package/{src → dist}/view/observer/mutationobserver.d.ts +0 -0
  238. /package/{src → dist}/view/observer/observer.d.ts +0 -0
  239. /package/{src → dist}/view/observer/pointerobserver.d.ts +0 -0
  240. /package/{src → dist}/view/observer/selectionobserver.d.ts +0 -0
  241. /package/{src → dist}/view/observer/tabobserver.d.ts +0 -0
  242. /package/{src → dist}/view/observer/touchobserver.d.ts +0 -0
  243. /package/{src → dist}/view/placeholder.d.ts +0 -0
  244. /package/{src → dist}/view/position.d.ts +0 -0
  245. /package/{src → dist}/view/range.d.ts +0 -0
  246. /package/{src → dist}/view/rawelement.d.ts +0 -0
  247. /package/{src → dist}/view/renderer.d.ts +0 -0
  248. /package/{src → dist}/view/rooteditableelement.d.ts +0 -0
  249. /package/{src → dist}/view/selection.d.ts +0 -0
  250. /package/{src → dist}/view/stylesmap.d.ts +0 -0
  251. /package/{src → dist}/view/text.d.ts +0 -0
  252. /package/{src → dist}/view/textproxy.d.ts +0 -0
  253. /package/{src → dist}/view/tokenlist.d.ts +0 -0
  254. /package/{src → dist}/view/treewalker.d.ts +0 -0
  255. /package/{src → dist}/view/typecheckable.d.ts +0 -0
  256. /package/{src → dist}/view/uielement.d.ts +0 -0
  257. /package/{src → dist}/view/upcastwriter.d.ts +0 -0
  258. /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
- }