@kerebron/extension-yjs 0.6.7 → 0.7.1
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/esm/ExtensionYjs.d.ts +3 -11
- package/esm/ExtensionYjs.d.ts.map +1 -1
- package/esm/ExtensionYjs.js +71 -45
- package/esm/ExtensionYjs.js.map +1 -1
- package/esm/WebsocketProvider.d.ts +70 -0
- package/esm/WebsocketProvider.d.ts.map +1 -0
- package/esm/WebsocketProvider.js +377 -0
- package/esm/WebsocketProvider.js.map +1 -0
- package/esm/YjsProvider.d.ts +48 -0
- package/esm/YjsProvider.d.ts.map +1 -0
- package/esm/YjsProvider.js +12 -0
- package/esm/YjsProvider.js.map +1 -0
- package/esm/_dnt.shims.d.ts +2 -0
- package/esm/_dnt.shims.d.ts.map +1 -0
- package/esm/_dnt.shims.js +58 -0
- package/esm/_dnt.shims.js.map +1 -0
- package/esm/binding/BindingMetadata.d.ts +6 -0
- package/esm/binding/BindingMetadata.d.ts.map +1 -0
- package/esm/binding/BindingMetadata.js +2 -0
- package/esm/binding/BindingMetadata.js.map +1 -0
- package/esm/binding/DiffViewer.d.ts +17 -0
- package/esm/binding/DiffViewer.d.ts.map +1 -0
- package/esm/binding/DiffViewer.js +96 -0
- package/esm/binding/DiffViewer.js.map +1 -0
- package/esm/binding/PmYjsBinding.d.ts +45 -0
- package/esm/binding/PmYjsBinding.d.ts.map +1 -0
- package/esm/binding/PmYjsBinding.js +230 -0
- package/esm/binding/PmYjsBinding.js.map +1 -0
- package/esm/binding/convertUtils.d.ts +48 -0
- package/esm/binding/convertUtils.d.ts.map +1 -0
- package/esm/binding/convertUtils.js +80 -0
- package/esm/binding/convertUtils.js.map +1 -0
- package/esm/{createNodeFromYElement.d.ts → binding/createNodeFromYElement.d.ts} +2 -2
- package/esm/binding/createNodeFromYElement.d.ts.map +1 -0
- package/esm/{createNodeFromYElement.js → binding/createNodeFromYElement.js} +2 -2
- package/esm/binding/createNodeFromYElement.js.map +1 -0
- package/esm/{updateYFragment.d.ts → binding/updateYFragment.d.ts} +3 -3
- package/esm/binding/updateYFragment.d.ts.map +1 -0
- package/esm/{updateYFragment.js → binding/updateYFragment.js} +10 -7
- package/esm/binding/updateYFragment.js.map +1 -0
- package/esm/debug.d.ts.map +1 -1
- package/esm/debug.js +11 -0
- package/esm/debug.js.map +1 -1
- package/esm/lib.d.ts +1 -7
- package/esm/lib.d.ts.map +1 -1
- package/esm/lib.js +1 -200
- package/esm/lib.js.map +1 -1
- package/esm/position.d.ts +8 -0
- package/esm/position.d.ts.map +1 -0
- package/esm/position.js +165 -0
- package/esm/position.js.map +1 -0
- package/esm/ui/selection.d.ts +29 -0
- package/esm/ui/selection.d.ts.map +1 -0
- package/esm/ui/selection.js +129 -0
- package/esm/ui/selection.js.map +1 -0
- package/esm/utils.d.ts +1 -1
- package/esm/utils.d.ts.map +1 -1
- package/esm/utils.js.map +1 -1
- package/esm/yPositionPlugin.d.ts +6 -1
- package/esm/yPositionPlugin.d.ts.map +1 -1
- package/esm/yPositionPlugin.js +91 -50
- package/esm/yPositionPlugin.js.map +1 -1
- package/esm/ySyncPlugin.d.ts +5 -22
- package/esm/ySyncPlugin.d.ts.map +1 -1
- package/esm/ySyncPlugin.js +70 -101
- package/esm/ySyncPlugin.js.map +1 -1
- package/esm/yUndoPlugin.d.ts +11 -10
- package/esm/yUndoPlugin.d.ts.map +1 -1
- package/esm/yUndoPlugin.js +90 -52
- package/esm/yUndoPlugin.js.map +1 -1
- package/package.json +9 -6
- package/src/ExtensionYjs.ts +98 -67
- package/src/WebsocketProvider.ts +528 -0
- package/src/YjsProvider.ts +75 -0
- package/src/_dnt.shims.ts +60 -0
- package/src/binding/BindingMetadata.ts +6 -0
- package/src/binding/DiffViewer.ts +138 -0
- package/src/binding/PmYjsBinding.ts +360 -0
- package/src/binding/convertUtils.ts +124 -0
- package/src/{createNodeFromYElement.ts → binding/createNodeFromYElement.ts} +4 -4
- package/src/{updateYFragment.ts → binding/updateYFragment.ts} +15 -8
- package/src/debug.ts +21 -0
- package/src/lib.ts +4 -230
- package/src/position.ts +191 -0
- package/src/ui/selection.ts +218 -0
- package/src/utils.ts +1 -1
- package/src/yPositionPlugin.ts +122 -74
- package/src/ySyncPlugin.ts +111 -155
- package/src/yUndoPlugin.ts +113 -62
- package/esm/ProsemirrorBinding.d.ts +0 -60
- package/esm/ProsemirrorBinding.d.ts.map +0 -1
- package/esm/ProsemirrorBinding.js +0 -405
- package/esm/ProsemirrorBinding.js.map +0 -1
- package/esm/createNodeFromYElement.d.ts.map +0 -1
- package/esm/createNodeFromYElement.js.map +0 -1
- package/esm/updateYFragment.d.ts.map +0 -1
- package/esm/updateYFragment.js.map +0 -1
- package/esm/userColors.d.ts +0 -5
- package/esm/userColors.d.ts.map +0 -1
- package/esm/userColors.js +0 -11
- package/esm/userColors.js.map +0 -1
- package/src/ProsemirrorBinding.ts +0 -607
- package/src/userColors.ts +0 -10
package/esm/position.js
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import * as Y from 'yjs';
|
|
2
|
+
/**
|
|
3
|
+
* Transforms a Prosemirror based absolute position to a Yjs Cursor (relative position in the Yjs model).
|
|
4
|
+
*/
|
|
5
|
+
export const absolutePositionToRelativePosition = (pos, type, mapping) => {
|
|
6
|
+
if (pos === 0) {
|
|
7
|
+
// if the type is later populated, we want to retain the 0 position (hence assoc=-1)
|
|
8
|
+
return Y.createRelativePositionFromTypeIndex(type, 0, type.length === 0 ? -1 : 0);
|
|
9
|
+
}
|
|
10
|
+
let n = type._first === null
|
|
11
|
+
? null
|
|
12
|
+
: /** @type {Y.ContentType} */ (type._first.content).type;
|
|
13
|
+
while (n !== null && type !== n) {
|
|
14
|
+
if (n instanceof Y.XmlText) {
|
|
15
|
+
if (n._length >= pos) {
|
|
16
|
+
return Y.createRelativePositionFromTypeIndex(n, pos, type.length === 0 ? -1 : 0);
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
pos -= n._length;
|
|
20
|
+
}
|
|
21
|
+
if (n._item !== null && n._item.next !== null) {
|
|
22
|
+
n = /** @type {Y.ContentType} */ (n._item.next.content).type;
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
do {
|
|
26
|
+
n = n._item === null ? null : n._item.parent;
|
|
27
|
+
pos--;
|
|
28
|
+
} while (n !== type && n !== null && n._item !== null && n._item.next === null);
|
|
29
|
+
if (n !== null && n !== type) {
|
|
30
|
+
// @ts-gnore we know that n.next !== null because of above loop conditition
|
|
31
|
+
n = n._item === null
|
|
32
|
+
? null
|
|
33
|
+
: /** @type {Y.ContentType} */ ( /** @type Y.Item */(n._item.next)
|
|
34
|
+
.content).type;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
const pNodeSize =
|
|
40
|
+
/** @type {any} */ (mapping.get(n) || { nodeSize: 0 }).nodeSize;
|
|
41
|
+
if (n._first !== null && pos < pNodeSize) {
|
|
42
|
+
n = /** @type {Y.ContentType} */ (n._first.content).type;
|
|
43
|
+
pos--;
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
if (pos === 1 && n._length === 0 && pNodeSize > 1) {
|
|
47
|
+
// edge case, should end in this paragraph
|
|
48
|
+
return new Y.RelativePosition(n._item === null ? null : n._item.id, n._item === null ? Y.findRootTypeKey(n) : null, null);
|
|
49
|
+
}
|
|
50
|
+
pos -= pNodeSize;
|
|
51
|
+
if (n._item !== null && n._item.next !== null) {
|
|
52
|
+
n = /** @type {Y.ContentType} */ (n._item.next.content).type;
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
if (pos === 0) {
|
|
56
|
+
// set to end of n.parent
|
|
57
|
+
n = n._item === null ? n : n._item.parent;
|
|
58
|
+
return new Y.RelativePosition(n._item === null ? null : n._item.id, n._item === null ? Y.findRootTypeKey(n) : null, null);
|
|
59
|
+
}
|
|
60
|
+
do {
|
|
61
|
+
n = n._item.parent;
|
|
62
|
+
pos--;
|
|
63
|
+
} while (n !== type && /** @type {Y.Item} */ (n._item).next === null);
|
|
64
|
+
// if n is null at this point, we have an unexpected case
|
|
65
|
+
if (n !== type) {
|
|
66
|
+
// We know that n._item.next is defined because of above loop condition
|
|
67
|
+
n =
|
|
68
|
+
/** @type {Y.ContentType} */ ( /** @type {Y.Item} */( /** @type {Y.Item} */(n
|
|
69
|
+
._item).next).content).type;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (n === null) {
|
|
75
|
+
throw new Error('Unexpected case');
|
|
76
|
+
}
|
|
77
|
+
if (pos === 0 && n.constructor !== Y.XmlText && n !== type) { // TODO: set to <= 0
|
|
78
|
+
return createRelativePosition(n._item.parent, n._item);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return Y.createRelativePositionFromTypeIndex(type, type._length, type.length === 0 ? -1 : 0);
|
|
82
|
+
};
|
|
83
|
+
const createRelativePosition = (type, item) => {
|
|
84
|
+
let typeid = null;
|
|
85
|
+
let tname = null;
|
|
86
|
+
if (type._item === null) {
|
|
87
|
+
tname = Y.findRootTypeKey(type);
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
typeid = Y.createID(type._item.id.client, type._item.id.clock);
|
|
91
|
+
}
|
|
92
|
+
return new Y.RelativePosition(typeid, tname, item.id);
|
|
93
|
+
};
|
|
94
|
+
export const relativePositionToAbsolutePosition = (yDoc, documentType, relPos, mapping) => {
|
|
95
|
+
const decodedPos = Y.createAbsolutePositionFromRelativePosition(relPos, yDoc);
|
|
96
|
+
if (decodedPos === null ||
|
|
97
|
+
(decodedPos.type !== documentType &&
|
|
98
|
+
!Y.isParentOf(documentType, decodedPos.type._item))) {
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
let type = decodedPos.type;
|
|
102
|
+
let pos = 0;
|
|
103
|
+
if (type instanceof Y.XmlText) {
|
|
104
|
+
pos = decodedPos.index;
|
|
105
|
+
}
|
|
106
|
+
else if (type._item === null || !type._item.deleted) {
|
|
107
|
+
let n = type._first;
|
|
108
|
+
let i = 0;
|
|
109
|
+
while (i < type._length && i < decodedPos.index && n !== null) {
|
|
110
|
+
if (!n.deleted) {
|
|
111
|
+
const t = n.content.type;
|
|
112
|
+
i++;
|
|
113
|
+
if (t instanceof Y.XmlText) {
|
|
114
|
+
pos += t._length;
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
const node = mapping.get(t);
|
|
118
|
+
if (Array.isArray(node)) {
|
|
119
|
+
pos += node.reduce((prev, curr) => prev + curr?.nodeSize || 0, 0);
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
pos += node?.nodeSize || 0;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
n = n.right;
|
|
127
|
+
}
|
|
128
|
+
pos += 1; // increase because we go out of n
|
|
129
|
+
}
|
|
130
|
+
while (type !== documentType && type._item !== null) {
|
|
131
|
+
const parent = type._item.parent;
|
|
132
|
+
if (parent instanceof Y.ID || parent === null) {
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
if (parent._item === null || !parent._item.deleted) {
|
|
136
|
+
pos += 1; // the start tag
|
|
137
|
+
let n = /** @type {Y.AbstractType} */ (parent)._first;
|
|
138
|
+
// now iterate until we found type
|
|
139
|
+
while (n !== null) {
|
|
140
|
+
const contentType = n.content.type;
|
|
141
|
+
if (contentType === type) {
|
|
142
|
+
break;
|
|
143
|
+
}
|
|
144
|
+
if (!n.deleted) {
|
|
145
|
+
if (contentType instanceof Y.XmlText) {
|
|
146
|
+
pos += contentType._length;
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
const node = mapping.get(contentType);
|
|
150
|
+
if (Array.isArray(node)) {
|
|
151
|
+
pos += node.reduce((prev, curr) => prev + curr?.nodeSize || 0, 0);
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
pos += node?.nodeSize || 0;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
n = n.right;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
type = parent;
|
|
162
|
+
}
|
|
163
|
+
return pos - 1; // we don't count the most outer tag, because it is a fragment
|
|
164
|
+
};
|
|
165
|
+
//# sourceMappingURL=position.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"position.js","sourceRoot":"","sources":["../src/position.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAGzB;;GAEG;AACH,MAAM,CAAC,MAAM,kCAAkC,GAAG,CAChD,GAAW,EACX,IAAmB,EACnB,OAA2B,EACtB,EAAE;IACP,IAAI,GAAG,KAAK,CAAC,EAAE,CAAC;QACd,oFAAoF;QACpF,OAAO,CAAC,CAAC,mCAAmC,CAC1C,IAAI,EACJ,CAAC,EACD,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAC3B,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,GAA+B,IAAI,CAAC,MAAM,KAAK,IAAI;QACtD,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,4BAA4B,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC;IAC5D,OAAO,CAAC,KAAK,IAAI,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;QAChC,IAAI,CAAC,YAAY,CAAC,CAAC,OAAO,EAAE,CAAC;YAC3B,IAAI,CAAC,CAAC,OAAO,IAAI,GAAG,EAAE,CAAC;gBACrB,OAAO,CAAC,CAAC,mCAAmC,CAC1C,CAAC,EACD,GAAG,EACH,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAC3B,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACN,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC;YACnB,CAAC;YACD,IAAI,CAAC,CAAC,KAAK,KAAK,IAAI,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;gBAC9C,CAAC,GAAG,4BAA4B,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC;YAC/D,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC;oBACF,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC;oBAC7C,GAAG,EAAE,CAAC;gBACR,CAAC,QACC,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,KAAK,KAAK,IAAI,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,EACrE;gBACF,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;oBAC7B,2EAA2E;oBAC3E,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,IAAI;wBAClB,CAAC,CAAC,IAAI;wBACN,CAAC,CAAC,4BAA4B,CAAC,EAAC,mBAAoB,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;6BAC/D,OAAO,CAAC,CAAC,IAAI,CAAC;gBACrB,CAAC;YACH,CAAC;QACH,CAAC;aAAM,CAAC;YACN,MAAM,SAAS;YACb,kBAAkB,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC;YAClE,IAAI,CAAC,CAAC,MAAM,KAAK,IAAI,IAAI,GAAG,GAAG,SAAS,EAAE,CAAC;gBACzC,CAAC,GAAG,4BAA4B,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC;gBACzD,GAAG,EAAE,CAAC;YACR,CAAC;iBAAM,CAAC;gBACN,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,OAAO,KAAK,CAAC,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;oBAClD,0CAA0C;oBAC1C,OAAO,IAAI,CAAC,CAAC,gBAAgB,CAC3B,CAAC,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,EACpC,CAAC,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAC9C,IAAI,CACL,CAAC;gBACJ,CAAC;gBACD,GAAG,IAAI,SAAS,CAAC;gBACjB,IAAI,CAAC,CAAC,KAAK,KAAK,IAAI,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;oBAC9C,CAAC,GAAG,4BAA4B,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC;gBAC/D,CAAC;qBAAM,CAAC;oBACN,IAAI,GAAG,KAAK,CAAC,EAAE,CAAC;wBACd,yBAAyB;wBACzB,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC;wBAC1C,OAAO,IAAI,CAAC,CAAC,gBAAgB,CAC3B,CAAC,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,EACpC,CAAC,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAC9C,IAAI,CACL,CAAC;oBACJ,CAAC;oBACD,GAAG,CAAC;wBACF,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC;wBACnB,GAAG,EAAE,CAAC;oBACR,CAAC,QAAQ,CAAC,KAAK,IAAI,IAAI,qBAAqB,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,IAAI,EAAE;oBACtE,yDAAyD;oBACzD,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;wBACf,uEAAuE;wBACvE,CAAC;4BACC,4BAA4B,CAAC,EAAC,qBAAsB,EAAC,qBAAsB,CAAC,CAAC;iCAC1E,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC;oBAClC,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QACD,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;QACrC,CAAC;QACD,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,WAAW,KAAK,CAAC,CAAC,OAAO,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,oBAAoB;YAChF,OAAO,sBAAsB,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC;QACzD,CAAC;IACH,CAAC;IACD,OAAO,CAAC,CAAC,mCAAmC,CAC1C,IAAI,EACJ,IAAI,CAAC,OAAO,EACZ,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAC3B,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,sBAAsB,GAAG,CAAC,IAAyB,EAAE,IAAY,EAAE,EAAE;IACzE,IAAI,MAAM,GAAG,IAAI,CAAC;IAClB,IAAI,KAAK,GAAG,IAAI,CAAC;IACjB,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;QACxB,KAAK,GAAG,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC;SAAM,CAAC;QACN,MAAM,GAAG,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;IACjE,CAAC;IACD,OAAO,IAAI,CAAC,CAAC,gBAAgB,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;AACxD,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,kCAAkC,GAAG,CAChD,IAAW,EACX,YAA2B,EAC3B,MAAW,EACX,OAA2B,EACZ,EAAE;IACjB,MAAM,UAAU,GAAG,CAAC,CAAC,0CAA0C,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC9E,IACE,UAAU,KAAK,IAAI;QACnB,CAAC,UAAU,CAAC,IAAI,KAAK,YAAY;YAC/B,CAAC,CAAC,CAAC,UAAU,CAAC,YAAY,EAAE,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EACrD,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC;IAC3B,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,IAAI,IAAI,YAAY,CAAC,CAAC,OAAO,EAAE,CAAC;QAC9B,GAAG,GAAG,UAAU,CAAC,KAAK,CAAC;IACzB,CAAC;SAAM,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;QACtD,IAAI,CAAC,GAAkB,IAAI,CAAC,MAAM,CAAC;QACnC,IAAI,CAAC,GAAG,CAAC,CAAC;QACV,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,IAAI,CAAC,GAAG,UAAU,CAAC,KAAK,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;YAC9D,IAAI,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;gBACf,MAAM,CAAC,GAAwB,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC;gBAC9C,CAAC,EAAE,CAAC;gBACJ,IAAI,CAAC,YAAY,CAAC,CAAC,OAAO,EAAE,CAAC;oBAC3B,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC;gBACnB,CAAC;qBAAM,CAAC;oBACN,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;oBAC5B,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;wBACxB,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,GAAG,IAAI,EAAE,QAAQ,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;oBACpE,CAAC;yBAAM,CAAC;wBACN,GAAG,IAAI,IAAI,EAAE,QAAQ,IAAI,CAAC,CAAC;oBAC7B,CAAC;gBACH,CAAC;YACH,CAAC;YACD,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC;QACd,CAAC;QACD,GAAG,IAAI,CAAC,CAAC,CAAC,kCAAkC;IAC9C,CAAC;IACD,OAAO,IAAI,KAAK,YAAY,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;QACpD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;QACjC,IAAI,MAAM,YAAY,CAAC,CAAC,EAAE,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YAC9C,SAAS;QACX,CAAC;QACD,IAAI,MAAM,CAAC,KAAK,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;YACnD,GAAG,IAAI,CAAC,CAAC,CAAC,gBAAgB;YAC1B,IAAI,CAAC,GAAG,6BAA6B,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;YACtD,kCAAkC;YAClC,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC;gBAClB,MAAM,WAAW,GAAwB,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC;gBACxD,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;oBACzB,MAAM;gBACR,CAAC;gBACD,IAAI,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;oBACf,IAAI,WAAW,YAAY,CAAC,CAAC,OAAO,EAAE,CAAC;wBACrC,GAAG,IAAI,WAAW,CAAC,OAAO,CAAC;oBAC7B,CAAC;yBAAM,CAAC;wBACN,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;wBACtC,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;4BACxB,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,GAAG,IAAI,EAAE,QAAQ,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;wBACpE,CAAC;6BAAM,CAAC;4BACN,GAAG,IAAI,IAAI,EAAE,QAAQ,IAAI,CAAC,CAAC;wBAC7B,CAAC;oBACH,CAAC;gBACH,CAAC;gBACD,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC;YACd,CAAC;QACH,CAAC;QACD,IAAI,GAAG,MAAM,CAAC;IAChB,CAAC;IACD,OAAO,GAAG,GAAG,CAAC,CAAC,CAAC,8DAA8D;AAChF,CAAC,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import * as Y from 'yjs';
|
|
2
|
+
import { EditorState, Transaction } from 'prosemirror-state';
|
|
3
|
+
import { YjsData } from '../binding/PmYjsBinding.js';
|
|
4
|
+
import { ProsemirrorMapping } from '../lib.js';
|
|
5
|
+
import { CoreEditor } from '@kerebron/editor';
|
|
6
|
+
interface TransactionSelection {
|
|
7
|
+
type: string;
|
|
8
|
+
anchor: Y.RelativePosition;
|
|
9
|
+
head: Y.RelativePosition;
|
|
10
|
+
}
|
|
11
|
+
export declare const getRelativeSelection: (xmlFragment: Y.XmlFragment, mapping: ProsemirrorMapping, state: EditorState) => TransactionSelection;
|
|
12
|
+
export declare class SelectionStash {
|
|
13
|
+
private yjs;
|
|
14
|
+
private mapping;
|
|
15
|
+
private editor;
|
|
16
|
+
private readonly beforeAllTransactions;
|
|
17
|
+
private readonly afterAllTransactions;
|
|
18
|
+
private _beforeTransactionSelection;
|
|
19
|
+
private _domSelectionInView;
|
|
20
|
+
constructor(yjs: YjsData, mapping: ProsemirrorMapping, editor: CoreEditor);
|
|
21
|
+
destroy(): void;
|
|
22
|
+
store(): void;
|
|
23
|
+
overwrite(transactionSelection: TransactionSelection): void;
|
|
24
|
+
restore(tr: Transaction): void;
|
|
25
|
+
_isLocalCursorInView(): boolean;
|
|
26
|
+
_isDomSelectionInView(): boolean;
|
|
27
|
+
}
|
|
28
|
+
export {};
|
|
29
|
+
//# sourceMappingURL=selection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"selection.d.ts","sourceRoot":"","sources":["../../src/ui/selection.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAEzB,OAAO,EAEL,WAAW,EAIX,WAAW,EACZ,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAK/C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,UAAU,oBAAoB;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,CAAC,CAAC,gBAAgB,CAAC;IAC3B,IAAI,EAAE,CAAC,CAAC,gBAAgB,CAAC;CAC1B;AA+CD,eAAO,MAAM,oBAAoB,GAC/B,aAAa,CAAC,CAAC,WAAW,EAC1B,SAAS,kBAAkB,EAC3B,OAAO,WAAW,KACjB,oBAYD,CAAC;AAeH,qBAAa,cAAc;IAQvB,OAAO,CAAC,GAAG;IACX,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,MAAM;IAThB,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAa;IACnD,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAa;IAElD,OAAO,CAAC,2BAA2B,CAAqC;IACxE,OAAO,CAAC,mBAAmB,CAAkB;gBAGnC,GAAG,EAAE,OAAO,EACZ,OAAO,EAAE,kBAAkB,EAC3B,MAAM,EAAE,UAAU;IAsB5B,OAAO;IAKP,KAAK;IAQL,SAAS,CAAC,oBAAoB,EAAE,oBAAoB;IAIpD,OAAO,CAAC,EAAE,EAAE,WAAW;IAcvB,oBAAoB,IAAI,OAAO;IAkB/B,qBAAqB,IAAI,OAAO;CAkCjC"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import * as dntShim from "../_dnt.shims.js";
|
|
2
|
+
import { AllSelection, NodeSelection, TextSelection, } from 'prosemirror-state';
|
|
3
|
+
import { absolutePositionToRelativePosition, relativePositionToAbsolutePosition, } from '../position.js';
|
|
4
|
+
const restoreRelativeSelection = (tr, relSel, yjs, mapping) => {
|
|
5
|
+
const { ydoc, xmlFragment } = yjs;
|
|
6
|
+
if (relSel !== null && relSel.anchor !== null && relSel.head !== null) {
|
|
7
|
+
if (relSel.type === 'all') {
|
|
8
|
+
tr.setSelection(new AllSelection(tr.doc));
|
|
9
|
+
}
|
|
10
|
+
else if (relSel.type === 'node') {
|
|
11
|
+
const anchor = relativePositionToAbsolutePosition(ydoc, xmlFragment, relSel.anchor, mapping);
|
|
12
|
+
if (anchor !== null) {
|
|
13
|
+
tr.setSelection(NodeSelection.create(tr.doc, anchor));
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
const anchor = relativePositionToAbsolutePosition(ydoc, xmlFragment, relSel.anchor, mapping);
|
|
18
|
+
const head = relativePositionToAbsolutePosition(ydoc, xmlFragment, relSel.head, mapping);
|
|
19
|
+
if (anchor !== null && head !== null) {
|
|
20
|
+
const sel = TextSelection.between(tr.doc.resolve(anchor), tr.doc.resolve(head));
|
|
21
|
+
tr.setSelection(sel);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
export const getRelativeSelection = (xmlFragment, mapping, state) => ({
|
|
27
|
+
type: getSelectionType(state.selection),
|
|
28
|
+
anchor: absolutePositionToRelativePosition(state.selection.anchor, xmlFragment, mapping),
|
|
29
|
+
head: absolutePositionToRelativePosition(state.selection.head, xmlFragment, mapping),
|
|
30
|
+
});
|
|
31
|
+
function getSelectionType(selection) {
|
|
32
|
+
if (selection instanceof TextSelection) {
|
|
33
|
+
return 'text';
|
|
34
|
+
}
|
|
35
|
+
if (selection instanceof AllSelection) {
|
|
36
|
+
return 'all';
|
|
37
|
+
}
|
|
38
|
+
if (selection instanceof NodeSelection) {
|
|
39
|
+
return 'node';
|
|
40
|
+
}
|
|
41
|
+
return 'other_selection';
|
|
42
|
+
}
|
|
43
|
+
export class SelectionStash {
|
|
44
|
+
yjs;
|
|
45
|
+
mapping;
|
|
46
|
+
editor;
|
|
47
|
+
beforeAllTransactions;
|
|
48
|
+
afterAllTransactions;
|
|
49
|
+
_beforeTransactionSelection = null;
|
|
50
|
+
_domSelectionInView = false;
|
|
51
|
+
constructor(yjs, mapping, editor) {
|
|
52
|
+
this.yjs = yjs;
|
|
53
|
+
this.mapping = mapping;
|
|
54
|
+
this.editor = editor;
|
|
55
|
+
this.beforeAllTransactions = () => {
|
|
56
|
+
if (!this._beforeTransactionSelection &&
|
|
57
|
+
editor.view) {
|
|
58
|
+
this._beforeTransactionSelection = getRelativeSelection(yjs.xmlFragment, mapping, editor.state);
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
this.afterAllTransactions = () => {
|
|
62
|
+
this._beforeTransactionSelection = null;
|
|
63
|
+
};
|
|
64
|
+
this.yjs.ydoc.on('beforeAllTransactions', this.beforeAllTransactions);
|
|
65
|
+
this.yjs.ydoc.on('afterAllTransactions', this.afterAllTransactions);
|
|
66
|
+
}
|
|
67
|
+
destroy() {
|
|
68
|
+
this.yjs.ydoc.off('beforeAllTransactions', this.beforeAllTransactions);
|
|
69
|
+
this.yjs.ydoc.off('afterAllTransactions', this.afterAllTransactions);
|
|
70
|
+
}
|
|
71
|
+
store() {
|
|
72
|
+
this._beforeTransactionSelection = getRelativeSelection(this.yjs.xmlFragment, this.mapping, this.editor.state);
|
|
73
|
+
}
|
|
74
|
+
overwrite(transactionSelection) {
|
|
75
|
+
this._beforeTransactionSelection = transactionSelection;
|
|
76
|
+
}
|
|
77
|
+
restore(tr) {
|
|
78
|
+
if (this._beforeTransactionSelection) {
|
|
79
|
+
restoreRelativeSelection(tr, this._beforeTransactionSelection, this.yjs, this.mapping);
|
|
80
|
+
if (this._isLocalCursorInView()) {
|
|
81
|
+
tr.scrollIntoView();
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
_isLocalCursorInView() {
|
|
86
|
+
if (!this.editor.view.hasFocus())
|
|
87
|
+
return false;
|
|
88
|
+
// const isNode = /* @__PURE__ */(() => typeof process !== 'undefined' && process.release && /node|io\.js/.test(process.release.name) && Object.prototype.toString.call(typeof process !== 'undefined' ? process : 0) === '[object process]')()
|
|
89
|
+
const isBrowser =
|
|
90
|
+
/* @__PURE__ */ (() => typeof dntShim.dntGlobalThis !== 'undefined' && typeof document !== 'undefined')(); // && !isNode
|
|
91
|
+
if (isBrowser && this._domSelectionInView === false) {
|
|
92
|
+
// Calculate the domSelectionInView and clear by next tick after all events are finished
|
|
93
|
+
setTimeout(() => {
|
|
94
|
+
this._domSelectionInView = false;
|
|
95
|
+
}, 0);
|
|
96
|
+
this._domSelectionInView = this._isDomSelectionInView();
|
|
97
|
+
}
|
|
98
|
+
return this._domSelectionInView;
|
|
99
|
+
}
|
|
100
|
+
_isDomSelectionInView() {
|
|
101
|
+
const view = this.editor.view;
|
|
102
|
+
if (!('root' in view)) {
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
const selection = document.getSelection();
|
|
106
|
+
if (!selection || selection.anchorNode == null || selection.focusNode == null)
|
|
107
|
+
return false;
|
|
108
|
+
const range = document.createRange();
|
|
109
|
+
range.setStart(selection.anchorNode, selection.anchorOffset);
|
|
110
|
+
range.setEnd(selection.focusNode, selection.focusOffset);
|
|
111
|
+
// This is a workaround for an edgecase where getBoundingClientRect will
|
|
112
|
+
// return zero values if the selection is collapsed at the start of a newline
|
|
113
|
+
// see reference here: https://stackoverflow.com/a/59780954
|
|
114
|
+
const rects = range.getClientRects();
|
|
115
|
+
if (rects.length === 0) {
|
|
116
|
+
// probably buggy newline behavior, explicitly select the node contents
|
|
117
|
+
if (range.startContainer && range.collapsed) {
|
|
118
|
+
range.selectNodeContents(range.startContainer);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
const bounding = range.getBoundingClientRect();
|
|
122
|
+
const documentElement = document.documentElement;
|
|
123
|
+
return bounding.bottom >= 0 && bounding.right >= 0 &&
|
|
124
|
+
bounding.left <=
|
|
125
|
+
(globalThis.innerWidth || documentElement.clientWidth || 0) &&
|
|
126
|
+
bounding.top <= (globalThis.innerHeight || documentElement.clientHeight || 0);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=selection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"selection.js","sourceRoot":"","sources":["../../src/ui/selection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,kBAAkB,CAAC;AAG5C,OAAO,EACL,YAAY,EAEZ,aAAa,EAEb,aAAa,GAEd,MAAM,mBAAmB,CAAC;AAI3B,OAAO,EACL,kCAAkC,EAClC,kCAAkC,GACnC,MAAM,gBAAgB,CAAC;AASxB,MAAM,wBAAwB,GAAG,CAC/B,EAAe,EACf,MAA+C,EAC/C,GAAY,EACZ,OAA2B,EAC3B,EAAE;IACF,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,GAAG,CAAC;IAElC,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,CAAC,MAAM,KAAK,IAAI,IAAI,MAAM,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;QACtE,IAAI,MAAM,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;YAC1B,EAAE,CAAC,YAAY,CAAC,IAAI,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QAC5C,CAAC;aAAM,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAClC,MAAM,MAAM,GAAG,kCAAkC,CAC/C,IAAI,EACJ,WAAW,EACX,MAAM,CAAC,MAAM,EACb,OAAO,CACR,CAAC;YACF,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;gBACpB,EAAE,CAAC,YAAY,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC;YACxD,CAAC;QACH,CAAC;aAAM,CAAC;YACN,MAAM,MAAM,GAAG,kCAAkC,CAC/C,IAAI,EACJ,WAAW,EACX,MAAM,CAAC,MAAM,EACb,OAAO,CACR,CAAC;YACF,MAAM,IAAI,GAAG,kCAAkC,CAC7C,IAAI,EACJ,WAAW,EACX,MAAM,CAAC,IAAI,EACX,OAAO,CACR,CAAC;YACF,IAAI,MAAM,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;gBACrC,MAAM,GAAG,GAAG,aAAa,CAAC,OAAO,CAC/B,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,EACtB,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CACrB,CAAC;gBACF,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;YACvB,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAClC,WAA0B,EAC1B,OAA2B,EAC3B,KAAkB,EACI,EAAE,CAAC,CAAC;IAC1B,IAAI,EAAE,gBAAgB,CAAC,KAAK,CAAC,SAAS,CAAC;IACvC,MAAM,EAAE,kCAAkC,CACxC,KAAK,CAAC,SAAS,CAAC,MAAM,EACtB,WAAW,EACX,OAAO,CACR;IACD,IAAI,EAAE,kCAAkC,CACtC,KAAK,CAAC,SAAS,CAAC,IAAI,EACpB,WAAW,EACX,OAAO,CACR;CACF,CAAC,CAAC;AAEH,SAAS,gBAAgB,CAAC,SAAoB;IAC5C,IAAI,SAAS,YAAY,aAAa,EAAE,CAAC;QACvC,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,IAAI,SAAS,YAAY,YAAY,EAAE,CAAC;QACtC,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,SAAS,YAAY,aAAa,EAAE,CAAC;QACvC,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,OAAO,iBAAiB,CAAC;AAC3B,CAAC;AAED,MAAM,OAAO,cAAc;IAQf;IACA;IACA;IATO,qBAAqB,CAAa;IAClC,oBAAoB,CAAa;IAE1C,2BAA2B,GAAgC,IAAI,CAAC;IAChE,mBAAmB,GAAY,KAAK,CAAC;IAE7C,YACU,GAAY,EACZ,OAA2B,EAC3B,MAAkB;QAFlB,QAAG,GAAH,GAAG,CAAS;QACZ,YAAO,GAAP,OAAO,CAAoB;QAC3B,WAAM,GAAN,MAAM,CAAY;QAE1B,IAAI,CAAC,qBAAqB,GAAG,GAAG,EAAE;YAChC,IACE,CAAC,IAAI,CAAC,2BAA2B;gBACjC,MAAM,CAAC,IAAI,EACX,CAAC;gBACD,IAAI,CAAC,2BAA2B,GAAG,oBAAoB,CACrD,GAAG,CAAC,WAAW,EACf,OAAO,EACP,MAAM,CAAC,KAAK,CACb,CAAC;YACJ,CAAC;QACH,CAAC,CAAC;QACF,IAAI,CAAC,oBAAoB,GAAG,GAAG,EAAE;YAC/B,IAAI,CAAC,2BAA2B,GAAG,IAAI,CAAC;QAC1C,CAAC,CAAC;QAEF,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,uBAAuB,EAAE,IAAI,CAAC,qBAAqB,CAAC,CAAC;QACtE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,sBAAsB,EAAE,IAAI,CAAC,oBAAoB,CAAC,CAAC;IACtE,CAAC;IAED,OAAO;QACL,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,uBAAuB,EAAE,IAAI,CAAC,qBAAqB,CAAC,CAAC;QACvE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,sBAAsB,EAAE,IAAI,CAAC,oBAAoB,CAAC,CAAC;IACvE,CAAC;IAED,KAAK;QACH,IAAI,CAAC,2BAA2B,GAAG,oBAAoB,CACrD,IAAI,CAAC,GAAG,CAAC,WAAW,EACpB,IAAI,CAAC,OAAO,EACZ,IAAI,CAAC,MAAM,CAAC,KAAK,CAClB,CAAC;IACJ,CAAC;IAED,SAAS,CAAC,oBAA0C;QAClD,IAAI,CAAC,2BAA2B,GAAG,oBAAoB,CAAC;IAC1D,CAAC;IAED,OAAO,CAAC,EAAe;QACrB,IAAI,IAAI,CAAC,2BAA2B,EAAE,CAAC;YACrC,wBAAwB,CACtB,EAAE,EACF,IAAI,CAAC,2BAA2B,EAChC,IAAI,CAAC,GAAG,EACR,IAAI,CAAC,OAAO,CACb,CAAC;YACF,IAAI,IAAI,CAAC,oBAAoB,EAAE,EAAE,CAAC;gBAChC,EAAE,CAAC,cAAc,EAAE,CAAC;YACtB,CAAC;QACH,CAAC;IACH,CAAC;IAED,oBAAoB;QAClB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE;YAAE,OAAO,KAAK,CAAC;QAE/C,+OAA+O;QAC/O,MAAM,SAAS;QACb,eAAe,CAAC,CAAC,GAAG,EAAE,CACpB,OAAO,OAAO,CAAC,aAAa,KAAK,WAAW,IAAI,OAAO,QAAQ,KAAK,WAAW,CAAC,EAAE,CAAC,CAAC,cAAc;QAEtG,IAAI,SAAS,IAAI,IAAI,CAAC,mBAAmB,KAAK,KAAK,EAAE,CAAC;YACpD,wFAAwF;YACxF,UAAU,CAAC,GAAG,EAAE;gBACd,IAAI,CAAC,mBAAmB,GAAG,KAAK,CAAC;YACnC,CAAC,EAAE,CAAC,CAAC,CAAC;YACN,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAC1D,CAAC;QACD,OAAO,IAAI,CAAC,mBAAmB,CAAC;IAClC,CAAC;IAED,qBAAqB;QACnB,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;QAC9B,IAAI,CAAC,CAAC,MAAM,IAAI,IAAI,CAAC,EAAE,CAAC;YACtB,OAAO,KAAK,CAAC;QACf,CAAC;QACD,MAAM,SAAS,GAAG,QAAQ,CAAC,YAAY,EAAE,CAAC;QAE1C,IACE,CAAC,SAAS,IAAI,SAAS,CAAC,UAAU,IAAI,IAAI,IAAI,SAAS,CAAC,SAAS,IAAI,IAAI;YACzE,OAAO,KAAK,CAAC;QAEf,MAAM,KAAK,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;QACrC,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,UAAU,EAAE,SAAS,CAAC,YAAY,CAAC,CAAC;QAC7D,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,EAAE,SAAS,CAAC,WAAW,CAAC,CAAC;QAEzD,wEAAwE;QACxE,6EAA6E;QAC7E,2DAA2D;QAC3D,MAAM,KAAK,GAAG,KAAK,CAAC,cAAc,EAAE,CAAC;QACrC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,uEAAuE;YACvE,IAAI,KAAK,CAAC,cAAc,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;gBAC5C,KAAK,CAAC,kBAAkB,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;YACjD,CAAC;QACH,CAAC;QAED,MAAM,QAAQ,GAAG,KAAK,CAAC,qBAAqB,EAAE,CAAC;QAC/C,MAAM,eAAe,GAAG,QAAQ,CAAC,eAAe,CAAC;QAEjD,OAAO,QAAQ,CAAC,MAAM,IAAI,CAAC,IAAI,QAAQ,CAAC,KAAK,IAAI,CAAC;YAChD,QAAQ,CAAC,IAAI;gBACX,CAAC,UAAU,CAAC,UAAU,IAAI,eAAe,CAAC,WAAW,IAAI,CAAC,CAAC;YAC7D,QAAQ,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,WAAW,IAAI,eAAe,CAAC,YAAY,IAAI,CAAC,CAAC,CAAC;IAClF,CAAC;CACF"}
|
package/esm/utils.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import * as Y from 'yjs';
|
|
2
2
|
export declare const hashOfJSON: (json: any) => string;
|
|
3
|
-
export declare const isVisible: (item: Y.Item, snapshot
|
|
3
|
+
export declare const isVisible: (item: Y.Item, snapshot?: Y.Snapshot) => boolean;
|
|
4
4
|
//# sourceMappingURL=utils.d.ts.map
|
package/esm/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAYzB,eAAO,MAAM,UAAU,GAAI,MAAM,GAAG,WAC0B,CAAC;AAE/D,eAAO,MAAM,SAAS,GAAI,MAAM,CAAC,CAAC,IAAI,EAAE,
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAYzB,eAAO,MAAM,UAAU,GAAI,MAAM,GAAG,WAC0B,CAAC;AAE/D,eAAO,MAAM,SAAS,GAAI,MAAM,CAAC,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,QAAQ,YAGtB,CAAC"}
|
package/esm/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AACzB,OAAO,KAAK,MAAM,MAAM,kBAAkB,CAAC;AAC3C,OAAO,KAAK,GAAG,MAAM,aAAa,CAAC;AAEnC,MAAM,UAAU,GAAG,CAAC,MAAkB,EAAE,EAAE;IACxC,MAAM,CAAC,GAAG,CAAC,CAAC;IACZ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACvC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IAC5C,CAAC;IACD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAC5B,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,IAAS,EAAE,EAAE,CACtC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AAE/D,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,IAAY,EAAE,
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AACzB,OAAO,KAAK,MAAM,MAAM,kBAAkB,CAAC;AAC3C,OAAO,KAAK,GAAG,MAAM,aAAa,CAAC;AAEnC,MAAM,UAAU,GAAG,CAAC,MAAkB,EAAE,EAAE;IACxC,MAAM,CAAC,GAAG,CAAC,CAAC;IACZ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACvC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IAC5C,CAAC;IACD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAC5B,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,IAAS,EAAE,EAAE,CACtC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AAE/D,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,IAAY,EAAE,QAAqB,EAAE,EAAE,CAC/D,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC;IACvE,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAE,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,KAAK;IAClD,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC"}
|
package/esm/yPositionPlugin.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Awareness } from 'y-protocols/awareness';
|
|
2
2
|
import { Plugin } from 'prosemirror-state';
|
|
3
3
|
import type { CoreEditor } from '@kerebron/editor';
|
|
4
|
+
import { type ColorMapper, type User } from '@kerebron/editor/user';
|
|
4
5
|
type AwarenessListener = ({ added, updated, removed }: {
|
|
5
6
|
added: number[];
|
|
6
7
|
updated: number[];
|
|
@@ -12,11 +13,15 @@ interface PositionPluginConfig {
|
|
|
12
13
|
export interface YPositionPluginState {
|
|
13
14
|
awareness?: Awareness;
|
|
14
15
|
awarenessListener?: AwarenessListener;
|
|
16
|
+
cursorStateField: string;
|
|
17
|
+
userStateField: string;
|
|
18
|
+
me: User;
|
|
19
|
+
colorMapper: ColorMapper;
|
|
15
20
|
}
|
|
16
21
|
/**
|
|
17
22
|
* Default awareness state filter
|
|
18
23
|
*/
|
|
19
24
|
export declare const defaultAwarenessStateFilter: (currentClientId: number, userClientId: number, _user: any) => boolean;
|
|
20
|
-
export declare const yPositionPlugin: (editor: CoreEditor, { getSelection, }?: PositionPluginConfig
|
|
25
|
+
export declare const yPositionPlugin: (editor: CoreEditor, { getSelection, }?: PositionPluginConfig) => Plugin<YPositionPluginState>;
|
|
21
26
|
export {};
|
|
22
27
|
//# sourceMappingURL=yPositionPlugin.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"yPositionPlugin.d.ts","sourceRoot":"","sources":["../src/yPositionPlugin.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"yPositionPlugin.d.ts","sourceRoot":"","sources":["../src/yPositionPlugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAGlD,OAAO,EAAe,MAAM,EAAe,MAAM,mBAAmB,CAAC;AAGrE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EACL,KAAK,WAAW,EAGhB,KAAK,IAAI,EACV,MAAM,uBAAuB,CAAC;AAmC/B,KAAK,iBAAiB,GAAG,CACvB,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE;IAC3B,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,EACD,CAAC,EAAE,GAAG,EACN,CAAC,EAAE,GAAG,KACH,IAAI,CAAC;AAEV,UAAU,oBAAoB;IAC5B,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,GAAG,CAAC;CACnC;AAED,MAAM,WAAW,oBAAoB;IACnC,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,EAAE,EAAE,IAAI,CAAC;IACT,WAAW,EAAE,WAAW,CAAC;CAC1B;AA0FD;;GAEG;AACH,eAAO,MAAM,2BAA2B,GACtC,iBAAiB,MAAM,EACvB,cAAc,MAAM,EACpB,OAAO,GAAG,KACT,OAA2C,CAAC;AAE/C,eAAO,MAAM,eAAe,GAC1B,QAAQ,UAAU,EAClB,oBAEG,oBAAyB,iCAmL7B,CAAC"}
|
package/esm/yPositionPlugin.js
CHANGED
|
@@ -1,17 +1,41 @@
|
|
|
1
1
|
import * as Y from 'yjs';
|
|
2
2
|
import { Plugin } from 'prosemirror-state';
|
|
3
|
-
import {
|
|
4
|
-
import { absolutePositionToRelativePosition, relativePositionToAbsolutePosition, setMeta, } from './lib.js';
|
|
3
|
+
import { defaultColorMapper, generateBlankUser, } from '@kerebron/editor/user';
|
|
5
4
|
import { yPositionPluginKey, ySyncPluginKey } from './keys.js';
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
import { absolutePositionToRelativePosition, relativePositionToAbsolutePosition, } from './position.js';
|
|
6
|
+
/**
|
|
7
|
+
* Is null if no timeout is in progress.
|
|
8
|
+
* Is defined if a timeout is in progress.
|
|
9
|
+
* Maps from view
|
|
10
|
+
*/
|
|
11
|
+
let viewsToUpdate = null;
|
|
12
|
+
const updateMetas = () => {
|
|
13
|
+
const ups = viewsToUpdate;
|
|
14
|
+
viewsToUpdate = null;
|
|
15
|
+
if (!ups) {
|
|
8
16
|
return;
|
|
9
17
|
}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
18
|
+
ups.forEach((metas, view) => {
|
|
19
|
+
const tr = view.state.tr;
|
|
20
|
+
const syncState = ySyncPluginKey.getState(view.state);
|
|
21
|
+
if (syncState && syncState.binding) { // && !syncState.binding.isDestroyed
|
|
22
|
+
metas.forEach((val, key) => {
|
|
23
|
+
tr.setMeta(key, val);
|
|
24
|
+
});
|
|
25
|
+
view.dispatch(tr);
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
function destroyAwareness(pluginState) {
|
|
30
|
+
if (!pluginState.awareness) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const awareness = pluginState.awareness;
|
|
34
|
+
if (pluginState.awarenessListener) {
|
|
35
|
+
awareness.off('change', pluginState.awarenessListener);
|
|
13
36
|
}
|
|
14
|
-
awareness.setLocalStateField(cursorStateField, null);
|
|
37
|
+
awareness.setLocalStateField(pluginState.cursorStateField, null);
|
|
38
|
+
pluginState.awareness = undefined;
|
|
15
39
|
}
|
|
16
40
|
function initAwareness(state, editor) {
|
|
17
41
|
if (!state.awareness) {
|
|
@@ -21,39 +45,35 @@ function initAwareness(state, editor) {
|
|
|
21
45
|
const view = editor.view;
|
|
22
46
|
state.awarenessListener = ({ added, updated, removed }) => {
|
|
23
47
|
const ystate = ySyncPluginKey.getState(view.state);
|
|
24
|
-
if (!ystate.
|
|
48
|
+
if (!ystate.binding) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const yjs = ystate.binding.getYjs();
|
|
52
|
+
if (!yjs) {
|
|
25
53
|
return;
|
|
26
54
|
}
|
|
27
|
-
const awareness = ystate.provider.awareness;
|
|
28
55
|
const clients = added.concat(updated).concat(removed);
|
|
29
56
|
if (clients.findIndex((id) => id !== awareness.doc.clientID) ===
|
|
30
57
|
-1) {
|
|
31
58
|
return;
|
|
32
59
|
}
|
|
33
|
-
|
|
34
|
-
setMeta(view, remoteSelectionPluginKey, {
|
|
35
|
-
remotePositionUpdated: true,
|
|
36
|
-
});
|
|
37
|
-
}
|
|
60
|
+
const { ydoc, xmlFragment } = yjs;
|
|
38
61
|
const remoteStates = [];
|
|
39
|
-
const ydoc = ystate.ydoc;
|
|
40
62
|
awareness.getStates().forEach((aw, clientId) => {
|
|
41
63
|
if (!defaultAwarenessStateFilter(ydoc.clientID, clientId, aw)) {
|
|
42
64
|
return;
|
|
43
65
|
}
|
|
44
|
-
|
|
66
|
+
const cursor = aw[state.cursorStateField];
|
|
67
|
+
const user = aw[state.userStateField];
|
|
68
|
+
if (!cursor || !user) {
|
|
45
69
|
return;
|
|
46
70
|
}
|
|
47
|
-
const anchor = relativePositionToAbsolutePosition(ydoc,
|
|
48
|
-
const head = relativePositionToAbsolutePosition(ydoc,
|
|
71
|
+
const anchor = relativePositionToAbsolutePosition(ydoc, xmlFragment, Y.createRelativePositionFromJSON(cursor.anchor), ystate.binding.getMapping());
|
|
72
|
+
const head = relativePositionToAbsolutePosition(ydoc, xmlFragment, Y.createRelativePositionFromJSON(cursor.head), ystate.binding.getMapping());
|
|
49
73
|
if (anchor !== null && head !== null) {
|
|
50
74
|
remoteStates.push({
|
|
51
75
|
clientId,
|
|
52
|
-
user:
|
|
53
|
-
name: aw.user?.name,
|
|
54
|
-
color: aw.user?.color,
|
|
55
|
-
colorLight: aw.user?.colorLight,
|
|
56
|
-
},
|
|
76
|
+
user: user,
|
|
57
77
|
cursor: {
|
|
58
78
|
anchor,
|
|
59
79
|
head,
|
|
@@ -61,9 +81,9 @@ function initAwareness(state, editor) {
|
|
|
61
81
|
});
|
|
62
82
|
}
|
|
63
83
|
});
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
84
|
+
const tr = editor.state.tr;
|
|
85
|
+
tr.setMeta('remoteSelectionChange', { remoteStates });
|
|
86
|
+
editor.dispatchTransaction(tr);
|
|
67
87
|
};
|
|
68
88
|
awareness.on('change', state.awarenessListener);
|
|
69
89
|
}
|
|
@@ -71,38 +91,47 @@ function initAwareness(state, editor) {
|
|
|
71
91
|
* Default awareness state filter
|
|
72
92
|
*/
|
|
73
93
|
export const defaultAwarenessStateFilter = (currentClientId, userClientId, _user) => currentClientId !== userClientId;
|
|
74
|
-
export const yPositionPlugin = (editor, { getSelection = (state) => state.selection, } = {}
|
|
94
|
+
export const yPositionPlugin = (editor, { getSelection = (state) => state.selection, } = {}) => {
|
|
75
95
|
return new Plugin({
|
|
76
96
|
key: yPositionPluginKey,
|
|
77
97
|
state: {
|
|
78
|
-
init: (
|
|
98
|
+
init: () => {
|
|
79
99
|
return {
|
|
80
100
|
awareness: undefined,
|
|
101
|
+
cursorStateField: 'kerebron:cursor',
|
|
102
|
+
userStateField: 'kerebron:user',
|
|
103
|
+
me: generateBlankUser(),
|
|
104
|
+
colorMapper: defaultColorMapper,
|
|
81
105
|
};
|
|
82
106
|
},
|
|
83
107
|
apply: (tr, pluginState) => {
|
|
84
|
-
const
|
|
108
|
+
const changeUser = tr.getMeta('changeUser');
|
|
109
|
+
if (changeUser) {
|
|
110
|
+
pluginState.me = { ...changeUser.user };
|
|
111
|
+
}
|
|
112
|
+
const setColorMapper = tr.getMeta('setColorMapper');
|
|
113
|
+
if (setColorMapper) {
|
|
114
|
+
pluginState.colorMapper = setColorMapper.colorMapper;
|
|
115
|
+
}
|
|
116
|
+
const awareness = tr.getMeta('yjs:setAwareness');
|
|
85
117
|
if (awareness) {
|
|
86
118
|
if (pluginState.awareness) {
|
|
87
|
-
destroyAwareness(pluginState
|
|
119
|
+
destroyAwareness(pluginState);
|
|
88
120
|
}
|
|
89
121
|
pluginState.awareness = awareness;
|
|
90
122
|
if (pluginState.awareness) {
|
|
91
123
|
initAwareness(pluginState, editor);
|
|
92
124
|
}
|
|
93
125
|
}
|
|
126
|
+
if (tr.getMeta('yjs:removeAwareness')) {
|
|
127
|
+
if (pluginState.awareness) {
|
|
128
|
+
destroyAwareness(pluginState);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
94
131
|
return pluginState;
|
|
95
132
|
},
|
|
96
133
|
},
|
|
97
134
|
view: (view) => {
|
|
98
|
-
// const ystate: YSyncPluginState = ySyncPluginKey.getState(view.state)!;
|
|
99
|
-
// if (
|
|
100
|
-
// ystate.snapshot != null || ystate.prevSnapshot != null ||
|
|
101
|
-
// ystate.binding.mapping.size === 0
|
|
102
|
-
// ) {
|
|
103
|
-
// // do not render cursors while snapshot is active
|
|
104
|
-
// return DecorationSet.empty;
|
|
105
|
-
// }
|
|
106
135
|
const updateAwareness = (selectionAnchor, selectionHead) => {
|
|
107
136
|
const state = yPositionPluginKey.getState(view.state);
|
|
108
137
|
if (!state.awareness) {
|
|
@@ -111,12 +140,18 @@ export const yPositionPlugin = (editor, { getSelection = (state) => state.select
|
|
|
111
140
|
const awareness = state.awareness;
|
|
112
141
|
const current = awareness.getLocalState() || {};
|
|
113
142
|
const ystate = ySyncPluginKey.getState(view.state);
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
143
|
+
const yjs = ystate.binding.getYjs();
|
|
144
|
+
if (!yjs) {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
const { xmlFragment } = yjs;
|
|
148
|
+
const anchor = absolutePositionToRelativePosition(selectionAnchor, xmlFragment, ystate.binding.getMapping());
|
|
149
|
+
const head = absolutePositionToRelativePosition(selectionHead, xmlFragment, ystate.binding.getMapping());
|
|
150
|
+
const cursor = current[state.cursorStateField];
|
|
151
|
+
if (cursor == null ||
|
|
152
|
+
!Y.compareRelativePositions(Y.createRelativePositionFromJSON(cursor.anchor), anchor) ||
|
|
153
|
+
!Y.compareRelativePositions(Y.createRelativePositionFromJSON(cursor.head), head)) {
|
|
154
|
+
awareness.setLocalStateField(state.cursorStateField, {
|
|
120
155
|
anchor,
|
|
121
156
|
head,
|
|
122
157
|
});
|
|
@@ -127,13 +162,19 @@ export const yPositionPlugin = (editor, { getSelection = (state) => state.select
|
|
|
127
162
|
if (!state.awareness) {
|
|
128
163
|
return;
|
|
129
164
|
}
|
|
130
|
-
const awareness = state.awareness;
|
|
131
165
|
const ystate = ySyncPluginKey.getState(view.state);
|
|
166
|
+
const yjs = ystate.binding.getYjs();
|
|
167
|
+
if (!yjs) {
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
const awareness = state.awareness;
|
|
132
171
|
const current = awareness.getLocalState() || {};
|
|
133
|
-
|
|
134
|
-
|
|
172
|
+
const { ydoc, xmlFragment } = yjs;
|
|
173
|
+
const cursor = current[state.cursorStateField];
|
|
174
|
+
if (cursor &&
|
|
175
|
+
relativePositionToAbsolutePosition(ydoc, xmlFragment, Y.createRelativePositionFromJSON(cursor.anchor), ystate.binding.getMapping()) !== null) {
|
|
135
176
|
// delete cursor information if current cursor information is owned by this editor binding
|
|
136
|
-
awareness.setLocalStateField(cursorStateField, null);
|
|
177
|
+
awareness.setLocalStateField(state.cursorStateField, null);
|
|
137
178
|
}
|
|
138
179
|
};
|
|
139
180
|
const updateCursorInfo = () => {
|
|
@@ -161,7 +202,7 @@ export const yPositionPlugin = (editor, { getSelection = (state) => state.select
|
|
|
161
202
|
view.dom.removeEventListener('focusout', updateCursorInfo);
|
|
162
203
|
const pluginState = yPositionPluginKey.getState(view.state);
|
|
163
204
|
if (pluginState) {
|
|
164
|
-
destroyAwareness(pluginState
|
|
205
|
+
destroyAwareness(pluginState);
|
|
165
206
|
}
|
|
166
207
|
editor.removeEventListener('localPositionChanged', localPositionChangedListener);
|
|
167
208
|
},
|