@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
package/src/model/liverange.js
DELETED
|
@@ -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
|
-
*/
|