@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,121 +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/model/liverange
7
- */
8
- import { ModelRange } from './range.js';
9
- import { EmitterMixin } from '@ckeditor/ckeditor5-utils';
10
- /**
11
- * `ModelLiveRange` is a type of {@link module:engine/model/range~ModelRange Range}
12
- * that updates itself as {@link module:engine/model/document~ModelDocument document}
13
- * is changed through operations. It may be used as a bookmark.
14
- *
15
- * **Note:** Be very careful when dealing with `ModelLiveRange`. Each `ModelLiveRange` instance bind events that might
16
- * have to be unbound. Use {@link module:engine/model/liverange~ModelLiveRange#detach detach} whenever you don't need
17
- * `ModelLiveRange` anymore.
18
- */
19
- export class ModelLiveRange extends /* #__PURE__ */ EmitterMixin(ModelRange) {
20
- /**
21
- * Creates a live range.
22
- *
23
- * @see module:engine/model/range~ModelRange
24
- */
25
- constructor(start, end) {
26
- super(start, end);
27
- bindWithDocument.call(this);
28
- }
29
- /**
30
- * Unbinds all events previously bound by `ModelLiveRange`. Use it whenever you don't need `ModelLiveRange` instance
31
- * anymore (i.e. when leaving scope in which it was declared or before re-assigning variable that was
32
- * referring to it).
33
- */
34
- detach() {
35
- this.stopListening();
36
- }
37
- /**
38
- * Creates a {@link module:engine/model/range~ModelRange range instance} that is equal to this live range.
39
- */
40
- toRange() {
41
- return new ModelRange(this.start, this.end);
42
- }
43
- /**
44
- * Creates a `ModelLiveRange` instance that is equal to the given range.
45
- */
46
- static fromRange(range) {
47
- return new ModelLiveRange(range.start, range.end);
48
- }
49
- }
50
- // The magic of type inference using `is` method is centralized in `TypeCheckable` class.
51
- // Proper overload would interfere with that.
52
- ModelLiveRange.prototype.is = function (type) {
53
- return type === 'liveRange' || type === 'model:liveRange' ||
54
- // From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529.
55
- type == 'range' || type === 'model:range';
56
- };
57
- /**
58
- * Binds this `ModelLiveRange` to the {@link module:engine/model/document~ModelDocument document}
59
- * that owns this range's {@link module:engine/model/range~ModelRange#root root}.
60
- */
61
- function bindWithDocument() {
62
- this.listenTo(this.root.document.model, 'applyOperation', (event, args) => {
63
- const operation = args[0];
64
- if (!operation.isDocumentOperation) {
65
- return;
66
- }
67
- transform.call(this, operation);
68
- }, { priority: 'low' });
69
- }
70
- /**
71
- * Updates this range accordingly to the updates applied to the model. Bases on change events.
72
- */
73
- function transform(operation) {
74
- // Transform the range by the operation. Join the result ranges if needed.
75
- const ranges = this.getTransformedByOperation(operation);
76
- const result = ModelRange._createFromRanges(ranges);
77
- const boundariesChanged = !result.isEqual(this);
78
- const contentChanged = doesOperationChangeRangeContent(this, operation);
79
- let deletionPosition = null;
80
- if (boundariesChanged) {
81
- // If range boundaries have changed, fire `change:range` event.
82
- //
83
- if (result.root.rootName == '$graveyard') {
84
- // If the range was moved to the graveyard root, set `deletionPosition`.
85
- if (operation.type == 'remove') {
86
- deletionPosition = operation.sourcePosition;
87
- }
88
- else {
89
- // Merge operation.
90
- deletionPosition = operation.deletionPosition;
91
- }
92
- }
93
- const oldRange = this.toRange();
94
- this.start = result.start;
95
- this.end = result.end;
96
- this.fire('change:range', oldRange, { deletionPosition });
97
- }
98
- else if (contentChanged) {
99
- // If range boundaries have not changed, but there was change inside the range, fire `change:content` event.
100
- this.fire('change:content', this.toRange(), { deletionPosition });
101
- }
102
- }
103
- /**
104
- * Checks whether given operation changes something inside the range (even if it does not change boundaries).
105
- */
106
- function doesOperationChangeRangeContent(range, operation) {
107
- switch (operation.type) {
108
- case 'insert':
109
- return range.containsPosition(operation.position);
110
- case 'move':
111
- case 'remove':
112
- case 'reinsert':
113
- case 'merge':
114
- return range.containsPosition(operation.sourcePosition) ||
115
- range.start.isEqual(operation.sourcePosition) ||
116
- range.containsPosition(operation.targetPosition);
117
- case 'split':
118
- return range.containsPosition(operation.splitPosition) || range.containsPosition(operation.insertionPosition);
119
- }
120
- return false;
121
- }
@@ -1,436 +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/model/markercollection
7
- */
8
- import { ModelTypeCheckable } from './typecheckable.js';
9
- import { ModelLiveRange } from './liverange.js';
10
- import { CKEditorError, EmitterMixin } from '@ckeditor/ckeditor5-utils';
11
- /**
12
- * The collection of all {@link module:engine/model/markercollection~Marker markers} attached to the document.
13
- * It lets you {@link module:engine/model/markercollection~MarkerCollection#get get} markers or track them using
14
- * {@link module:engine/model/markercollection~MarkerCollection#event:update} event.
15
- *
16
- * To create, change or remove makers use {@link module:engine/model/writer~ModelWriter model writers'} methods:
17
- * {@link module:engine/model/writer~ModelWriter#addMarker} or {@link module:engine/model/writer~ModelWriter#removeMarker}. Since
18
- * the writer is the only proper way to change the data model it is not possible to change markers directly using this
19
- * collection. All markers created by the writer will be automatically added to this collection.
20
- *
21
- * By default there is one marker collection available as {@link module:engine/model/model~Model#markers model property}.
22
- *
23
- * @see module:engine/model/markercollection~Marker
24
- */
25
- export class MarkerCollection extends /* #__PURE__ */ EmitterMixin() {
26
- /**
27
- * Stores {@link ~Marker markers} added to the collection.
28
- */
29
- _markers = new Map();
30
- /**
31
- * Iterable interface.
32
- *
33
- * Iterates over all {@link ~Marker markers} added to the collection.
34
- */
35
- [Symbol.iterator]() {
36
- return this._markers.values();
37
- }
38
- /**
39
- * Checks if given {@link ~Marker marker} or marker name is in the collection.
40
- *
41
- * @param markerOrName Name of marker or marker instance to check.
42
- * @returns `true` if marker is in the collection, `false` otherwise.
43
- */
44
- has(markerOrName) {
45
- const markerName = markerOrName instanceof Marker ? markerOrName.name : markerOrName;
46
- return this._markers.has(markerName);
47
- }
48
- /**
49
- * Returns {@link ~Marker marker} with given `markerName`.
50
- *
51
- * @param markerName Name of marker to get.
52
- * @returns Marker with given name or `null` if such marker was
53
- * not added to the collection.
54
- */
55
- get(markerName) {
56
- return this._markers.get(markerName) || null;
57
- }
58
- /**
59
- * Creates and adds a {@link ~Marker marker} to the `MarkerCollection` with given name on given
60
- * {@link module:engine/model/range~ModelRange range}.
61
- *
62
- * If `MarkerCollection` already had a marker with given name (or {@link ~Marker marker} was passed), the marker in
63
- * collection is updated and {@link module:engine/model/markercollection~MarkerCollection#event:update} event is fired
64
- * but only if there was a change (marker range or {@link module:engine/model/markercollection~Marker#managedUsingOperations}
65
- * flag has changed.
66
- *
67
- * @internal
68
- * @fires update
69
- * @param markerOrName Name of marker to set or marker instance to update.
70
- * @param range Marker range.
71
- * @param managedUsingOperations Specifies whether the marker is managed using operations.
72
- * @param affectsData Specifies whether the marker affects the data produced by the data pipeline
73
- * (is persisted in the editor's data).
74
- * @returns `Marker` instance which was added or updated.
75
- */
76
- _set(markerOrName, range, managedUsingOperations = false, affectsData = false) {
77
- const markerName = markerOrName instanceof Marker ? markerOrName.name : markerOrName;
78
- if (markerName.includes(',')) {
79
- /**
80
- * Marker name cannot contain the "," character.
81
- *
82
- * @error markercollection-incorrect-marker-name
83
- */
84
- throw new CKEditorError('markercollection-incorrect-marker-name', this);
85
- }
86
- const oldMarker = this._markers.get(markerName);
87
- if (oldMarker) {
88
- const oldMarkerData = oldMarker.getData();
89
- const oldRange = oldMarker.getRange();
90
- let hasChanged = false;
91
- if (!oldRange.isEqual(range)) {
92
- oldMarker._attachLiveRange(ModelLiveRange.fromRange(range));
93
- hasChanged = true;
94
- }
95
- if (managedUsingOperations != oldMarker.managedUsingOperations) {
96
- oldMarker._managedUsingOperations = managedUsingOperations;
97
- hasChanged = true;
98
- }
99
- if (typeof affectsData === 'boolean' && affectsData != oldMarker.affectsData) {
100
- oldMarker._affectsData = affectsData;
101
- hasChanged = true;
102
- }
103
- if (hasChanged) {
104
- this.fire(`update:${markerName}`, oldMarker, oldRange, range, oldMarkerData);
105
- }
106
- return oldMarker;
107
- }
108
- const liveRange = ModelLiveRange.fromRange(range);
109
- const marker = new Marker(markerName, liveRange, managedUsingOperations, affectsData);
110
- this._markers.set(markerName, marker);
111
- this.fire(`update:${markerName}`, marker, null, range, { ...marker.getData(), range: null });
112
- return marker;
113
- }
114
- /**
115
- * Removes given {@link ~Marker marker} or a marker with given name from the `MarkerCollection`.
116
- *
117
- * @internal
118
- * @fires update
119
- * @param markerOrName Marker or name of a marker to remove.
120
- * @returns `true` if marker was found and removed, `false` otherwise.
121
- */
122
- _remove(markerOrName) {
123
- const markerName = markerOrName instanceof Marker ? markerOrName.name : markerOrName;
124
- const oldMarker = this._markers.get(markerName);
125
- if (oldMarker) {
126
- this._markers.delete(markerName);
127
- this.fire(`update:${markerName}`, oldMarker, oldMarker.getRange(), null, oldMarker.getData());
128
- this._destroyMarker(oldMarker);
129
- return true;
130
- }
131
- return false;
132
- }
133
- /**
134
- * Fires an {@link module:engine/model/markercollection~MarkerCollection#event:update} event for the given {@link ~Marker marker}
135
- * but does not change the marker. Useful to force {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher downcast
136
- * conversion} for the marker.
137
- *
138
- * @internal
139
- * @fires update
140
- * @param markerOrName Marker or name of a marker to refresh.
141
- */
142
- _refresh(markerOrName) {
143
- const markerName = markerOrName instanceof Marker ? markerOrName.name : markerOrName;
144
- const marker = this._markers.get(markerName);
145
- if (!marker) {
146
- /**
147
- * Marker with provided name does not exists.
148
- *
149
- * @error markercollection-refresh-marker-not-exists
150
- */
151
- throw new CKEditorError('markercollection-refresh-marker-not-exists', this);
152
- }
153
- const range = marker.getRange();
154
- this.fire(`update:${markerName}`, marker, range, range, marker.getData());
155
- }
156
- /**
157
- * Returns iterator that iterates over all markers, which ranges
158
- * contain given {@link module:engine/model/position~ModelPosition position}.
159
- */
160
- *getMarkersAtPosition(position) {
161
- for (const marker of this) {
162
- if (marker.getRange().containsPosition(position)) {
163
- yield marker;
164
- }
165
- }
166
- }
167
- /**
168
- * Returns iterator that iterates over all markers, which intersects with given {@link module:engine/model/range~ModelRange range}.
169
- */
170
- *getMarkersIntersectingRange(range) {
171
- for (const marker of this) {
172
- if (marker.getRange().getIntersection(range) !== null) {
173
- yield marker;
174
- }
175
- }
176
- }
177
- /**
178
- * Destroys marker collection and all markers inside it.
179
- */
180
- destroy() {
181
- for (const marker of this._markers.values()) {
182
- this._destroyMarker(marker);
183
- }
184
- this._markers = null;
185
- this.stopListening();
186
- }
187
- /**
188
- * Iterates over all markers that starts with given `prefix`.
189
- *
190
- * ```ts
191
- * const markerFooA = markersCollection._set( 'foo:a', rangeFooA );
192
- * const markerFooB = markersCollection._set( 'foo:b', rangeFooB );
193
- * const markerBarA = markersCollection._set( 'bar:a', rangeBarA );
194
- * const markerFooBarA = markersCollection._set( 'foobar:a', rangeFooBarA );
195
- * Array.from( markersCollection.getMarkersGroup( 'foo' ) ); // [ markerFooA, markerFooB ]
196
- * Array.from( markersCollection.getMarkersGroup( 'a' ) ); // []
197
- * ```
198
- */
199
- *getMarkersGroup(prefix) {
200
- for (const marker of this._markers.values()) {
201
- if (marker.name.startsWith(prefix + ':')) {
202
- yield marker;
203
- }
204
- }
205
- }
206
- /**
207
- * Destroys the marker.
208
- */
209
- _destroyMarker(marker) {
210
- marker.stopListening();
211
- marker._detachLiveRange();
212
- }
213
- }
214
- /**
215
- * `Marker` is a continuous part of the model (like a range), is named and represents some kind of information about the
216
- * marked part of the model document. In contrary to {@link module:engine/model/node~ModelNode nodes}, which are building blocks of
217
- * the model document tree, markers are not stored directly in the document tree but in the
218
- * {@link module:engine/model/model~Model#markers model markers' collection}. Still, they are document data, by giving
219
- * additional meaning to the part of a model document between marker start and marker end.
220
- *
221
- * In this sense, markers are similar to adding and converting attributes on nodes. The difference is that attribute is
222
- * connected with a given node (e.g. a character is bold no matter if it gets moved or content around it changes).
223
- * Markers on the other hand are continuous ranges and are characterized by their start and end position. This means that
224
- * any character in the marker is marked by the marker. For example, if a character is moved outside of marker it stops being
225
- * "special" and the marker is shrunk. Similarly, when a character is moved into the marker from other place in document
226
- * model, it starts being "special" and the marker is enlarged.
227
- *
228
- * Another upside of markers is that finding marked part of document is fast and easy. Using attributes to mark some nodes
229
- * and then trying to find that part of document would require traversing whole document tree. Marker gives instant access
230
- * to the range which it is marking at the moment.
231
- *
232
- * Markers are built from a name and a range.
233
- *
234
- * Range of the marker is updated automatically when document changes, using
235
- * {@link module:engine/model/liverange~ModelLiveRange live range} mechanism.
236
- *
237
- * Name is used to group and identify markers. Names have to be unique, but markers can be grouped by
238
- * using common prefixes, separated with `:`, for example: `user:john` or `search:3`. That's useful in term of creating
239
- * namespaces for custom elements (e.g. comments, highlights). You can use this prefixes in
240
- * {@link module:engine/model/markercollection~MarkerCollection#event:update} listeners to listen on changes in a group of markers.
241
- * For instance: `model.markers.on( 'update:user', callback );` will be called whenever any `user:*` markers changes.
242
- *
243
- * There are two types of markers.
244
- *
245
- * 1. Markers managed directly, without using operations. They are added directly by {@link module:engine/model/writer~ModelWriter}
246
- * to the {@link module:engine/model/markercollection~MarkerCollection} without any additional mechanism. They can be used
247
- * as bookmarks or visual markers. They are great for showing results of the find, or select link when the focus is in the input.
248
- *
249
- * 1. Markers managed using operations. These markers are also stored in {@link module:engine/model/markercollection~MarkerCollection}
250
- * but changes in these markers is managed the same way all other changes in the model structure - using operations.
251
- * Therefore, they are handled in the undo stack and synchronized between clients if the collaboration plugin is enabled.
252
- * This type of markers is useful for solutions like spell checking or comments.
253
- *
254
- * Both type of them should be added / updated by {@link module:engine/model/writer~ModelWriter#addMarker}
255
- * and removed by {@link module:engine/model/writer~ModelWriter#removeMarker} methods.
256
- *
257
- * ```ts
258
- * model.change( ( writer ) => {
259
- * const marker = writer.addMarker( name, { range, usingOperation: true } );
260
- *
261
- * // ...
262
- *
263
- * writer.removeMarker( marker );
264
- * } );
265
- * ```
266
- *
267
- * See {@link module:engine/model/writer~ModelWriter} to find more examples.
268
- *
269
- * Since markers need to track change in the document, for efficiency reasons, it is best to create and keep as little
270
- * markers as possible and remove them as soon as they are not needed anymore.
271
- *
272
- * Markers can be downcasted and upcasted.
273
- *
274
- * Markers downcast happens on {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:addMarker} and
275
- * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:removeMarker} events.
276
- * Use {@link module:engine/conversion/downcasthelpers downcast converters} or attach a custom converter to mentioned events.
277
- * For {@link module:engine/controller/datacontroller~DataController data pipeline}, marker should be downcasted to an element.
278
- * Then, it can be upcasted back to a marker. Again, use {@link module:engine/conversion/upcasthelpers upcast converters} or
279
- * attach a custom converter to {@link module:engine/conversion/upcastdispatcher~UpcastDispatcher#event:element}.
280
- *
281
- * `Marker` instances are created and destroyed only by {@link ~MarkerCollection MarkerCollection}.
282
- */
283
- class Marker extends /* #__PURE__ */ EmitterMixin(ModelTypeCheckable) {
284
- /**
285
- * Marker's name.
286
- */
287
- name;
288
- /**
289
- * Flag indicates if the marker is managed using operations or not.
290
- *
291
- * @internal
292
- */
293
- _managedUsingOperations;
294
- /**
295
- * Specifies whether the marker affects the data produced by the data pipeline
296
- * (is persisted in the editor's data).
297
- *
298
- * @internal
299
- */
300
- _affectsData;
301
- /**
302
- * Range marked by the marker.
303
- */
304
- _liveRange;
305
- /**
306
- * Creates a marker instance.
307
- *
308
- * @param name Marker name.
309
- * @param liveRange Range marked by the marker.
310
- * @param managedUsingOperations Specifies whether the marker is managed using operations.
311
- * @param affectsData Specifies whether the marker affects the data produced by the data pipeline (is persisted in the editor's data).
312
- */
313
- constructor(name, liveRange, managedUsingOperations, affectsData) {
314
- super();
315
- this.name = name;
316
- this._liveRange = this._attachLiveRange(liveRange);
317
- this._managedUsingOperations = managedUsingOperations;
318
- this._affectsData = affectsData;
319
- }
320
- /**
321
- * A value indicating if the marker is managed using operations.
322
- * See {@link ~Marker marker class description} to learn more about marker types.
323
- * See {@link module:engine/model/writer~ModelWriter#addMarker}.
324
- */
325
- get managedUsingOperations() {
326
- if (!this._liveRange) {
327
- throw new CKEditorError('marker-destroyed', this);
328
- }
329
- return this._managedUsingOperations;
330
- }
331
- /**
332
- * A value indicating if the marker changes the data.
333
- */
334
- get affectsData() {
335
- if (!this._liveRange) {
336
- throw new CKEditorError('marker-destroyed', this);
337
- }
338
- return this._affectsData;
339
- }
340
- /**
341
- * Returns the marker data (properties defining the marker).
342
- */
343
- getData() {
344
- return {
345
- range: this.getRange(),
346
- affectsData: this.affectsData,
347
- managedUsingOperations: this.managedUsingOperations
348
- };
349
- }
350
- /**
351
- * Returns current marker start position.
352
- */
353
- getStart() {
354
- if (!this._liveRange) {
355
- throw new CKEditorError('marker-destroyed', this);
356
- }
357
- return this._liveRange.start.clone();
358
- }
359
- /**
360
- * Returns current marker end position.
361
- */
362
- getEnd() {
363
- if (!this._liveRange) {
364
- throw new CKEditorError('marker-destroyed', this);
365
- }
366
- return this._liveRange.end.clone();
367
- }
368
- /**
369
- * Returns a range that represents the current state of the marker.
370
- *
371
- * Keep in mind that returned value is a {@link module:engine/model/range~ModelRange Range}, not a
372
- * {@link module:engine/model/liverange~ModelLiveRange ModelLiveRange}. This means that it is up-to-date and relevant only
373
- * until next model document change. Do not store values returned by this method. Instead, store {@link ~Marker#name}
374
- * and get `Marker` instance from {@link module:engine/model/markercollection~MarkerCollection MarkerCollection} every
375
- * time there is a need to read marker properties. This will guarantee that the marker has not been removed and
376
- * that it's data is up-to-date.
377
- */
378
- getRange() {
379
- if (!this._liveRange) {
380
- throw new CKEditorError('marker-destroyed', this);
381
- }
382
- return this._liveRange.toRange();
383
- }
384
- /**
385
- * Converts `Marker` to plain object and returns it.
386
- *
387
- * @returns `Marker` converted to plain object.
388
- */
389
- toJSON() {
390
- return {
391
- name: this.name,
392
- range: this._liveRange?.toJSON(),
393
- usingOperations: this._managedUsingOperations,
394
- affectsData: this._affectsData
395
- };
396
- }
397
- /**
398
- * Binds new live range to the marker and detach the old one if is attached.
399
- *
400
- * @internal
401
- * @param liveRange Live range to attach
402
- * @returns Attached live range.
403
- */
404
- _attachLiveRange(liveRange) {
405
- if (this._liveRange) {
406
- this._detachLiveRange();
407
- }
408
- // Delegating does not work with namespaces. Alternatively, we could delegate all events (using `*`).
409
- liveRange.delegate('change:range').to(this);
410
- liveRange.delegate('change:content').to(this);
411
- this._liveRange = liveRange;
412
- return liveRange;
413
- }
414
- /**
415
- * Unbinds and destroys currently attached live range.
416
- *
417
- * @internal
418
- */
419
- _detachLiveRange() {
420
- this._liveRange.stopDelegating('change:range', this);
421
- this._liveRange.stopDelegating('change:content', this);
422
- this._liveRange.detach();
423
- this._liveRange = null;
424
- }
425
- }
426
- // The magic of type inference using `is` method is centralized in `TypeCheckable` class.
427
- // Proper overload would interfere with that.
428
- Marker.prototype.is = function (type) {
429
- return type === 'marker' || type === 'model:marker';
430
- };
431
- export { Marker };
432
- /**
433
- * Cannot use a {@link module:engine/model/markercollection~MarkerCollection#destroy destroyed marker} instance.
434
- *
435
- * @error marker-destroyed
436
- */