@textbus/collaborate 4.1.0-alpha.0 → 4.1.0
Sign up to get free protection for your applications and to get access to all the features.
- package/bundles/collab-history.d.ts +0 -2
- package/bundles/collaborate.d.ts +17 -2
- package/bundles/connectors/hocuspocus-connector.d.ts +2 -1
- package/bundles/connectors/y-websocket-connector.d.ts +2 -1
- package/bundles/index.esm.js +92 -63
- package/bundles/index.js +91 -62
- package/bundles/multiple-doc-collab-history.d.ts +4 -2
- package/package.json +3 -3
package/bundles/collaborate.d.ts
CHANGED
@@ -1,7 +1,19 @@
|
|
1
1
|
import { Observable } from '@tanbo/stream';
|
2
|
-
import { Component, Registry, Scheduler, Selection, Slot } from '@textbus/core';
|
3
|
-
import { AbstractType, Doc as YDoc, Map as YMap, Text as YText } from 'yjs';
|
2
|
+
import { Component, Registry, Scheduler, Selection, Slot, AbstractSelection } from '@textbus/core';
|
3
|
+
import { AbstractType, Doc as YDoc, Map as YMap, RelativePosition, Text as YText } from 'yjs';
|
4
4
|
import { SubModelLoader } from './sub-model-loader';
|
5
|
+
export interface RelativePositionRecord {
|
6
|
+
doc: YDoc;
|
7
|
+
position: RelativePosition;
|
8
|
+
}
|
9
|
+
export interface CursorPosition {
|
10
|
+
anchor: RelativePositionRecord;
|
11
|
+
focus: RelativePositionRecord;
|
12
|
+
}
|
13
|
+
export interface CollaborateHistorySelectionPosition {
|
14
|
+
before: CursorPosition | null;
|
15
|
+
after: CursorPosition | null;
|
16
|
+
}
|
5
17
|
declare class SlotMap {
|
6
18
|
private slotAndYTextMap;
|
7
19
|
private yTextAndSlotMap;
|
@@ -31,6 +43,9 @@ export declare class Collaborate {
|
|
31
43
|
constructor(scheduler: Scheduler, registry: Registry, selection: Selection, subModelLoader: SubModelLoader);
|
32
44
|
syncRootComponent(yDoc: YDoc, sharedComponent: YMap<any>, localComponent: Component<any>): void;
|
33
45
|
syncRootSlot(yDoc: YDoc, sharedSlot: YText, localSlot: Slot): void;
|
46
|
+
getAbstractSelection(position: CursorPosition): AbstractSelection | null;
|
47
|
+
getRelativeCursorLocation(): CursorPosition | null;
|
48
|
+
restoreCursorPosition(position: CursorPosition | null): void;
|
34
49
|
private initSyncEvent;
|
35
50
|
private syncComponent;
|
36
51
|
private syncSlot;
|
@@ -1,7 +1,8 @@
|
|
1
|
+
import { HocuspocusProvider } from '@hocuspocus/provider';
|
1
2
|
import { HocuspocusProviderConfiguration } from '@hocuspocus/provider';
|
2
3
|
import { SyncConnector } from '../sync-connector';
|
3
4
|
export declare class HocuspocusConnector extends SyncConnector {
|
4
|
-
|
5
|
+
provide: HocuspocusProvider;
|
5
6
|
constructor(config: HocuspocusProviderConfiguration);
|
6
7
|
setLocalStateField(key: string, data: Record<string, any>): void;
|
7
8
|
onDestroy(): void;
|
@@ -1,7 +1,8 @@
|
|
1
1
|
import { Doc as YDoc } from 'yjs';
|
2
|
+
import { WebsocketProvider } from 'y-websocket';
|
2
3
|
import { SyncConnector } from '../sync-connector';
|
3
4
|
export declare class YWebsocketConnector extends SyncConnector {
|
4
|
-
|
5
|
+
provide: WebsocketProvider;
|
5
6
|
constructor(url: string, roomName: string, yDoc: YDoc);
|
6
7
|
setLocalStateField(key: string, data: Record<string, any>): void;
|
7
8
|
onDestroy(): void;
|
package/bundles/index.esm.js
CHANGED
@@ -3,7 +3,7 @@ import { Subject, map, filter, Subscription } from '@tanbo/stream';
|
|
3
3
|
import { WebsocketProvider } from 'y-websocket';
|
4
4
|
import { Injectable, Inject, Optional } from '@viewfly/core';
|
5
5
|
import { makeError, ChangeOrigin, Slot, createObjectProxy, createArrayProxy, AsyncSlot, AsyncComponent, Component, Scheduler, Registry, Selection, HISTORY_STACK_SIZE, RootComponentRef, History } from '@textbus/core';
|
6
|
-
import { Doc, Map, Array as Array$1, Text, UndoManager
|
6
|
+
import { Doc, createAbsolutePositionFromRelativePosition, createRelativePositionFromTypeIndex, Map, Array as Array$1, Text, UndoManager } from 'yjs';
|
7
7
|
|
8
8
|
/**
|
9
9
|
* 协作通信通用接口
|
@@ -209,11 +209,66 @@ let Collaborate = class Collaborate {
|
|
209
209
|
this.initLocalSlotBySharedSlot(sharedSlot, localSlot);
|
210
210
|
}
|
211
211
|
else {
|
212
|
-
|
212
|
+
yDoc.transact(() => {
|
213
|
+
this.initSharedSlotByLocalSlot(sharedSlot, localSlot);
|
214
|
+
});
|
213
215
|
}
|
214
216
|
this.initSyncEvent(yDoc);
|
215
217
|
this.syncSlot(sharedSlot, localSlot);
|
216
218
|
}
|
219
|
+
getAbstractSelection(position) {
|
220
|
+
const anchorPosition = createAbsolutePositionFromRelativePosition(position.anchor.position, position.anchor.doc);
|
221
|
+
const focusPosition = createAbsolutePositionFromRelativePosition(position.focus.position, position.focus.doc);
|
222
|
+
if (anchorPosition && focusPosition) {
|
223
|
+
const focusSlot = this.slotMap.get(focusPosition.type);
|
224
|
+
const anchorSlot = this.slotMap.get(anchorPosition.type);
|
225
|
+
if (focusSlot && anchorSlot) {
|
226
|
+
return {
|
227
|
+
anchorSlot,
|
228
|
+
anchorOffset: anchorPosition.index,
|
229
|
+
focusSlot,
|
230
|
+
focusOffset: focusPosition.index
|
231
|
+
};
|
232
|
+
}
|
233
|
+
}
|
234
|
+
return null;
|
235
|
+
}
|
236
|
+
getRelativeCursorLocation() {
|
237
|
+
const { anchorSlot, anchorOffset, focusSlot, focusOffset } = this.selection;
|
238
|
+
if (anchorSlot) {
|
239
|
+
const anchorYText = this.slotMap.get(anchorSlot);
|
240
|
+
if (anchorYText) {
|
241
|
+
const anchorPosition = createRelativePositionFromTypeIndex(anchorYText, anchorOffset);
|
242
|
+
if (focusSlot) {
|
243
|
+
const focusYText = this.slotMap.get(focusSlot);
|
244
|
+
if (focusYText) {
|
245
|
+
const focusPosition = createRelativePositionFromTypeIndex(focusYText, focusOffset);
|
246
|
+
return {
|
247
|
+
focus: {
|
248
|
+
doc: focusYText.doc,
|
249
|
+
position: focusPosition
|
250
|
+
},
|
251
|
+
anchor: {
|
252
|
+
doc: anchorYText.doc,
|
253
|
+
position: anchorPosition
|
254
|
+
}
|
255
|
+
};
|
256
|
+
}
|
257
|
+
}
|
258
|
+
}
|
259
|
+
}
|
260
|
+
return null;
|
261
|
+
}
|
262
|
+
restoreCursorPosition(position) {
|
263
|
+
if (!position) {
|
264
|
+
this.selection.unSelect();
|
265
|
+
return;
|
266
|
+
}
|
267
|
+
const selection = this.getAbstractSelection(position);
|
268
|
+
if (selection) {
|
269
|
+
this.selection.setBaseAndExtent(selection.anchorSlot, selection.anchorOffset, selection.focusSlot, selection.focusOffset);
|
270
|
+
}
|
271
|
+
}
|
217
272
|
initSyncEvent(yDoc) {
|
218
273
|
this.subscriptions.push(this.scheduler.onDocChanged.pipe(map(item => {
|
219
274
|
return item.filter(i => {
|
@@ -469,6 +524,7 @@ let Collaborate = class Collaborate {
|
|
469
524
|
yDoc: subDocument,
|
470
525
|
yType: content
|
471
526
|
});
|
527
|
+
this.initSyncEvent(subDocument);
|
472
528
|
localSlot.loader.markAsLoaded();
|
473
529
|
});
|
474
530
|
localSlot.__changeMarker__.destroyCallbacks.push(() => {
|
@@ -626,6 +682,7 @@ let Collaborate = class Collaborate {
|
|
626
682
|
yType: state,
|
627
683
|
yDoc: subDocument
|
628
684
|
});
|
685
|
+
this.initSyncEvent(subDocument);
|
629
686
|
component.loader.markAsLoaded();
|
630
687
|
});
|
631
688
|
return sharedComponent;
|
@@ -899,7 +956,7 @@ let CollabHistory = class CollabHistory {
|
|
899
956
|
this.manager = manager;
|
900
957
|
let beforePosition = null;
|
901
958
|
this.subscriptions.push(this.scheduler.onLocalChangeBefore.subscribe(() => {
|
902
|
-
beforePosition = this.getRelativeCursorLocation();
|
959
|
+
beforePosition = this.collaborate.getRelativeCursorLocation();
|
903
960
|
}), this.collaborate.onAddSubModel.subscribe(() => {
|
904
961
|
throw collabHistoryErrorFn('single document does not support submodels.');
|
905
962
|
}));
|
@@ -912,7 +969,7 @@ let CollabHistory = class CollabHistory {
|
|
912
969
|
this.historyItems.length = this.index;
|
913
970
|
this.historyItems.push({
|
914
971
|
before: beforePosition,
|
915
|
-
after: this.getRelativeCursorLocation()
|
972
|
+
after: this.collaborate.getRelativeCursorLocation()
|
916
973
|
});
|
917
974
|
this.index++;
|
918
975
|
}
|
@@ -933,14 +990,7 @@ let CollabHistory = class CollabHistory {
|
|
933
990
|
const index = ev.type === 'undo' ? this.index : this.index - 1;
|
934
991
|
const position = this.historyItems[index] || null;
|
935
992
|
const p = ev.type === 'undo' ? position === null || position === void 0 ? void 0 : position.before : position === null || position === void 0 ? void 0 : position.after;
|
936
|
-
|
937
|
-
const selection = this.getAbstractSelection(p);
|
938
|
-
if (selection) {
|
939
|
-
this.selection.setBaseAndExtent(selection.anchorSlot, selection.anchorOffset, selection.focusSlot, selection.focusOffset);
|
940
|
-
return;
|
941
|
-
}
|
942
|
-
}
|
943
|
-
this.selection.unSelect();
|
993
|
+
this.collaborate.restoreCursorPosition(p);
|
944
994
|
});
|
945
995
|
}
|
946
996
|
back() {
|
@@ -972,43 +1022,6 @@ let CollabHistory = class CollabHistory {
|
|
972
1022
|
this.subscriptions.forEach(i => i.unsubscribe());
|
973
1023
|
(_a = this.manager) === null || _a === void 0 ? void 0 : _a.destroy();
|
974
1024
|
}
|
975
|
-
getAbstractSelection(position) {
|
976
|
-
const anchorPosition = createAbsolutePositionFromRelativePosition(position.anchor, this.collaborate.yDoc);
|
977
|
-
const focusPosition = createAbsolutePositionFromRelativePosition(position.focus, this.collaborate.yDoc);
|
978
|
-
if (anchorPosition && focusPosition) {
|
979
|
-
const focusSlot = this.collaborate.slotMap.get(focusPosition.type);
|
980
|
-
const anchorSlot = this.collaborate.slotMap.get(anchorPosition.type);
|
981
|
-
if (focusSlot && anchorSlot) {
|
982
|
-
return {
|
983
|
-
anchorSlot,
|
984
|
-
anchorOffset: anchorPosition.index,
|
985
|
-
focusSlot,
|
986
|
-
focusOffset: focusPosition.index
|
987
|
-
};
|
988
|
-
}
|
989
|
-
}
|
990
|
-
return null;
|
991
|
-
}
|
992
|
-
getRelativeCursorLocation() {
|
993
|
-
const { anchorSlot, anchorOffset, focusSlot, focusOffset } = this.selection;
|
994
|
-
if (anchorSlot) {
|
995
|
-
const anchorYText = this.collaborate.slotMap.get(anchorSlot);
|
996
|
-
if (anchorYText) {
|
997
|
-
const anchorPosition = createRelativePositionFromTypeIndex(anchorYText, anchorOffset);
|
998
|
-
if (focusSlot) {
|
999
|
-
const focusYText = this.collaborate.slotMap.get(focusSlot);
|
1000
|
-
if (focusYText) {
|
1001
|
-
const focusPosition = createRelativePositionFromTypeIndex(focusYText, focusOffset);
|
1002
|
-
return {
|
1003
|
-
focus: focusPosition,
|
1004
|
-
anchor: anchorPosition
|
1005
|
-
};
|
1006
|
-
}
|
1007
|
-
}
|
1008
|
-
}
|
1009
|
-
}
|
1010
|
-
return null;
|
1011
|
-
}
|
1012
1025
|
};
|
1013
1026
|
CollabHistory = __decorate([
|
1014
1027
|
Injectable(),
|
@@ -1105,8 +1118,9 @@ let MultipleDocCollabHistory = class MultipleDocCollabHistory {
|
|
1105
1118
|
get canForward() {
|
1106
1119
|
return this.actionStack.length > 0 && this.index < this.actionStack.length;
|
1107
1120
|
}
|
1108
|
-
constructor(collaborate, rootComponentRef, stackSize, undoManagerConfig) {
|
1121
|
+
constructor(collaborate, scheduler, rootComponentRef, stackSize, undoManagerConfig) {
|
1109
1122
|
this.collaborate = collaborate;
|
1123
|
+
this.scheduler = scheduler;
|
1110
1124
|
this.rootComponentRef = rootComponentRef;
|
1111
1125
|
this.stackSize = stackSize;
|
1112
1126
|
this.undoManagerConfig = undoManagerConfig;
|
@@ -1119,6 +1133,7 @@ let MultipleDocCollabHistory = class MultipleDocCollabHistory {
|
|
1119
1133
|
this.index = 0;
|
1120
1134
|
this.stackItem = null;
|
1121
1135
|
this.timer = null;
|
1136
|
+
this.beforePosition = null;
|
1122
1137
|
this.subscription = new Subscription();
|
1123
1138
|
this.subDocs = new Set();
|
1124
1139
|
this.listenerCaches = new Set();
|
@@ -1141,6 +1156,8 @@ let MultipleDocCollabHistory = class MultipleDocCollabHistory {
|
|
1141
1156
|
if (this.isListen) {
|
1142
1157
|
this.listenItem(yType, yDoc);
|
1143
1158
|
}
|
1159
|
+
}), this.scheduler.onLocalChangeBefore.subscribe(() => {
|
1160
|
+
this.beforePosition = this.collaborate.getRelativeCursorLocation();
|
1144
1161
|
}));
|
1145
1162
|
}
|
1146
1163
|
forward() {
|
@@ -1150,9 +1167,10 @@ let MultipleDocCollabHistory = class MultipleDocCollabHistory {
|
|
1150
1167
|
clearTimeout(this.timer);
|
1151
1168
|
const item = this.actionStack[this.index];
|
1152
1169
|
if (item) {
|
1153
|
-
for (const i of item) {
|
1170
|
+
for (const i of item.undoManagers) {
|
1154
1171
|
i.redo();
|
1155
1172
|
}
|
1173
|
+
this.collaborate.restoreCursorPosition(item.after);
|
1156
1174
|
}
|
1157
1175
|
this.index++;
|
1158
1176
|
this.forwardEvent.next();
|
@@ -1163,29 +1181,32 @@ let MultipleDocCollabHistory = class MultipleDocCollabHistory {
|
|
1163
1181
|
return;
|
1164
1182
|
}
|
1165
1183
|
clearTimeout(this.timer);
|
1166
|
-
let
|
1184
|
+
let historyStackItem;
|
1167
1185
|
if (this.stackItem) {
|
1168
|
-
|
1186
|
+
historyStackItem = this.stackItem;
|
1169
1187
|
this.stackItem = null;
|
1170
1188
|
}
|
1171
1189
|
else {
|
1172
1190
|
this.index--;
|
1173
|
-
|
1191
|
+
historyStackItem = this.actionStack[this.index];
|
1174
1192
|
}
|
1175
|
-
let len =
|
1193
|
+
let len = historyStackItem.undoManagers.length;
|
1176
1194
|
while (len > 0) {
|
1177
1195
|
len--;
|
1178
|
-
|
1196
|
+
historyStackItem.undoManagers[len].undo();
|
1179
1197
|
}
|
1180
|
-
if (
|
1198
|
+
if (historyStackItem) {
|
1199
|
+
const beforePosition = historyStackItem.before;
|
1200
|
+
this.collaborate.restoreCursorPosition(beforePosition);
|
1181
1201
|
this.backEvent.next();
|
1182
1202
|
this.changeEvent.next();
|
1183
1203
|
}
|
1184
1204
|
}
|
1185
1205
|
clear() {
|
1186
1206
|
this.actionStack = [];
|
1187
|
-
this.stackItem =
|
1207
|
+
this.stackItem = null;
|
1188
1208
|
this.index = 0;
|
1209
|
+
this.beforePosition = null;
|
1189
1210
|
clearTimeout(this.timer);
|
1190
1211
|
this.listenerCaches.forEach((undoManager) => {
|
1191
1212
|
undoManager.clear();
|
@@ -1194,6 +1215,7 @@ let MultipleDocCollabHistory = class MultipleDocCollabHistory {
|
|
1194
1215
|
}
|
1195
1216
|
destroy() {
|
1196
1217
|
this.clear();
|
1218
|
+
this.beforePosition = this.stackItem = null;
|
1197
1219
|
this.subscription.unsubscribe();
|
1198
1220
|
this.listenerCaches.forEach((undoManager) => {
|
1199
1221
|
undoManager.destroy();
|
@@ -1224,7 +1246,7 @@ let MultipleDocCollabHistory = class MultipleDocCollabHistory {
|
|
1224
1246
|
if (this.index != this.actionStack.length) {
|
1225
1247
|
const redoStack = this.actionStack.slice(this.index);
|
1226
1248
|
redoStack.forEach(item => {
|
1227
|
-
item.forEach(i => {
|
1249
|
+
item.undoManagers.forEach(i => {
|
1228
1250
|
i.clear(false, true);
|
1229
1251
|
});
|
1230
1252
|
});
|
@@ -1232,7 +1254,11 @@ let MultipleDocCollabHistory = class MultipleDocCollabHistory {
|
|
1232
1254
|
this.changeEvent.next();
|
1233
1255
|
}
|
1234
1256
|
if (this.stackItem === null) {
|
1235
|
-
this.stackItem =
|
1257
|
+
this.stackItem = {
|
1258
|
+
before: this.beforePosition,
|
1259
|
+
after: null,
|
1260
|
+
undoManagers: []
|
1261
|
+
};
|
1236
1262
|
this.timer = setTimeout(() => {
|
1237
1263
|
if (this.actionStack.length >= this.stackSize) {
|
1238
1264
|
this.actionStack.shift();
|
@@ -1240,13 +1266,15 @@ let MultipleDocCollabHistory = class MultipleDocCollabHistory {
|
|
1240
1266
|
else {
|
1241
1267
|
this.index++;
|
1242
1268
|
}
|
1269
|
+
// this.beforePosition = this.collaborate.getRelativeCursorLocation()
|
1270
|
+
this.stackItem.after = this.beforePosition;
|
1243
1271
|
this.actionStack.push(this.stackItem);
|
1244
1272
|
this.stackItem = null;
|
1245
1273
|
this.pushEvent.next();
|
1246
1274
|
this.changeEvent.next();
|
1247
1275
|
}, 500);
|
1248
1276
|
}
|
1249
|
-
this.stackItem.push(undoManager);
|
1277
|
+
this.stackItem.undoManagers.push(undoManager);
|
1250
1278
|
}
|
1251
1279
|
});
|
1252
1280
|
this.listenerCaches.add(undoManager);
|
@@ -1254,9 +1282,10 @@ let MultipleDocCollabHistory = class MultipleDocCollabHistory {
|
|
1254
1282
|
};
|
1255
1283
|
MultipleDocCollabHistory = __decorate([
|
1256
1284
|
Injectable(),
|
1257
|
-
__param(
|
1258
|
-
__param(
|
1285
|
+
__param(3, Inject(HISTORY_STACK_SIZE)),
|
1286
|
+
__param(4, Optional()),
|
1259
1287
|
__metadata("design:paramtypes", [Collaborate,
|
1288
|
+
Scheduler,
|
1260
1289
|
RootComponentRef, Number, CustomUndoManagerConfig])
|
1261
1290
|
], MultipleDocCollabHistory);
|
1262
1291
|
|
package/bundles/index.js
CHANGED
@@ -211,11 +211,66 @@ exports.Collaborate = class Collaborate {
|
|
211
211
|
this.initLocalSlotBySharedSlot(sharedSlot, localSlot);
|
212
212
|
}
|
213
213
|
else {
|
214
|
-
|
214
|
+
yDoc.transact(() => {
|
215
|
+
this.initSharedSlotByLocalSlot(sharedSlot, localSlot);
|
216
|
+
});
|
215
217
|
}
|
216
218
|
this.initSyncEvent(yDoc);
|
217
219
|
this.syncSlot(sharedSlot, localSlot);
|
218
220
|
}
|
221
|
+
getAbstractSelection(position) {
|
222
|
+
const anchorPosition = yjs.createAbsolutePositionFromRelativePosition(position.anchor.position, position.anchor.doc);
|
223
|
+
const focusPosition = yjs.createAbsolutePositionFromRelativePosition(position.focus.position, position.focus.doc);
|
224
|
+
if (anchorPosition && focusPosition) {
|
225
|
+
const focusSlot = this.slotMap.get(focusPosition.type);
|
226
|
+
const anchorSlot = this.slotMap.get(anchorPosition.type);
|
227
|
+
if (focusSlot && anchorSlot) {
|
228
|
+
return {
|
229
|
+
anchorSlot,
|
230
|
+
anchorOffset: anchorPosition.index,
|
231
|
+
focusSlot,
|
232
|
+
focusOffset: focusPosition.index
|
233
|
+
};
|
234
|
+
}
|
235
|
+
}
|
236
|
+
return null;
|
237
|
+
}
|
238
|
+
getRelativeCursorLocation() {
|
239
|
+
const { anchorSlot, anchorOffset, focusSlot, focusOffset } = this.selection;
|
240
|
+
if (anchorSlot) {
|
241
|
+
const anchorYText = this.slotMap.get(anchorSlot);
|
242
|
+
if (anchorYText) {
|
243
|
+
const anchorPosition = yjs.createRelativePositionFromTypeIndex(anchorYText, anchorOffset);
|
244
|
+
if (focusSlot) {
|
245
|
+
const focusYText = this.slotMap.get(focusSlot);
|
246
|
+
if (focusYText) {
|
247
|
+
const focusPosition = yjs.createRelativePositionFromTypeIndex(focusYText, focusOffset);
|
248
|
+
return {
|
249
|
+
focus: {
|
250
|
+
doc: focusYText.doc,
|
251
|
+
position: focusPosition
|
252
|
+
},
|
253
|
+
anchor: {
|
254
|
+
doc: anchorYText.doc,
|
255
|
+
position: anchorPosition
|
256
|
+
}
|
257
|
+
};
|
258
|
+
}
|
259
|
+
}
|
260
|
+
}
|
261
|
+
}
|
262
|
+
return null;
|
263
|
+
}
|
264
|
+
restoreCursorPosition(position) {
|
265
|
+
if (!position) {
|
266
|
+
this.selection.unSelect();
|
267
|
+
return;
|
268
|
+
}
|
269
|
+
const selection = this.getAbstractSelection(position);
|
270
|
+
if (selection) {
|
271
|
+
this.selection.setBaseAndExtent(selection.anchorSlot, selection.anchorOffset, selection.focusSlot, selection.focusOffset);
|
272
|
+
}
|
273
|
+
}
|
219
274
|
initSyncEvent(yDoc) {
|
220
275
|
this.subscriptions.push(this.scheduler.onDocChanged.pipe(stream.map(item => {
|
221
276
|
return item.filter(i => {
|
@@ -471,6 +526,7 @@ exports.Collaborate = class Collaborate {
|
|
471
526
|
yDoc: subDocument,
|
472
527
|
yType: content
|
473
528
|
});
|
529
|
+
this.initSyncEvent(subDocument);
|
474
530
|
localSlot.loader.markAsLoaded();
|
475
531
|
});
|
476
532
|
localSlot.__changeMarker__.destroyCallbacks.push(() => {
|
@@ -628,6 +684,7 @@ exports.Collaborate = class Collaborate {
|
|
628
684
|
yType: state,
|
629
685
|
yDoc: subDocument
|
630
686
|
});
|
687
|
+
this.initSyncEvent(subDocument);
|
631
688
|
component.loader.markAsLoaded();
|
632
689
|
});
|
633
690
|
return sharedComponent;
|
@@ -901,7 +958,7 @@ exports.CollabHistory = class CollabHistory {
|
|
901
958
|
this.manager = manager;
|
902
959
|
let beforePosition = null;
|
903
960
|
this.subscriptions.push(this.scheduler.onLocalChangeBefore.subscribe(() => {
|
904
|
-
beforePosition = this.getRelativeCursorLocation();
|
961
|
+
beforePosition = this.collaborate.getRelativeCursorLocation();
|
905
962
|
}), this.collaborate.onAddSubModel.subscribe(() => {
|
906
963
|
throw collabHistoryErrorFn('single document does not support submodels.');
|
907
964
|
}));
|
@@ -914,7 +971,7 @@ exports.CollabHistory = class CollabHistory {
|
|
914
971
|
this.historyItems.length = this.index;
|
915
972
|
this.historyItems.push({
|
916
973
|
before: beforePosition,
|
917
|
-
after: this.getRelativeCursorLocation()
|
974
|
+
after: this.collaborate.getRelativeCursorLocation()
|
918
975
|
});
|
919
976
|
this.index++;
|
920
977
|
}
|
@@ -935,14 +992,7 @@ exports.CollabHistory = class CollabHistory {
|
|
935
992
|
const index = ev.type === 'undo' ? this.index : this.index - 1;
|
936
993
|
const position = this.historyItems[index] || null;
|
937
994
|
const p = ev.type === 'undo' ? position === null || position === void 0 ? void 0 : position.before : position === null || position === void 0 ? void 0 : position.after;
|
938
|
-
|
939
|
-
const selection = this.getAbstractSelection(p);
|
940
|
-
if (selection) {
|
941
|
-
this.selection.setBaseAndExtent(selection.anchorSlot, selection.anchorOffset, selection.focusSlot, selection.focusOffset);
|
942
|
-
return;
|
943
|
-
}
|
944
|
-
}
|
945
|
-
this.selection.unSelect();
|
995
|
+
this.collaborate.restoreCursorPosition(p);
|
946
996
|
});
|
947
997
|
}
|
948
998
|
back() {
|
@@ -974,43 +1024,6 @@ exports.CollabHistory = class CollabHistory {
|
|
974
1024
|
this.subscriptions.forEach(i => i.unsubscribe());
|
975
1025
|
(_a = this.manager) === null || _a === void 0 ? void 0 : _a.destroy();
|
976
1026
|
}
|
977
|
-
getAbstractSelection(position) {
|
978
|
-
const anchorPosition = yjs.createAbsolutePositionFromRelativePosition(position.anchor, this.collaborate.yDoc);
|
979
|
-
const focusPosition = yjs.createAbsolutePositionFromRelativePosition(position.focus, this.collaborate.yDoc);
|
980
|
-
if (anchorPosition && focusPosition) {
|
981
|
-
const focusSlot = this.collaborate.slotMap.get(focusPosition.type);
|
982
|
-
const anchorSlot = this.collaborate.slotMap.get(anchorPosition.type);
|
983
|
-
if (focusSlot && anchorSlot) {
|
984
|
-
return {
|
985
|
-
anchorSlot,
|
986
|
-
anchorOffset: anchorPosition.index,
|
987
|
-
focusSlot,
|
988
|
-
focusOffset: focusPosition.index
|
989
|
-
};
|
990
|
-
}
|
991
|
-
}
|
992
|
-
return null;
|
993
|
-
}
|
994
|
-
getRelativeCursorLocation() {
|
995
|
-
const { anchorSlot, anchorOffset, focusSlot, focusOffset } = this.selection;
|
996
|
-
if (anchorSlot) {
|
997
|
-
const anchorYText = this.collaborate.slotMap.get(anchorSlot);
|
998
|
-
if (anchorYText) {
|
999
|
-
const anchorPosition = yjs.createRelativePositionFromTypeIndex(anchorYText, anchorOffset);
|
1000
|
-
if (focusSlot) {
|
1001
|
-
const focusYText = this.collaborate.slotMap.get(focusSlot);
|
1002
|
-
if (focusYText) {
|
1003
|
-
const focusPosition = yjs.createRelativePositionFromTypeIndex(focusYText, focusOffset);
|
1004
|
-
return {
|
1005
|
-
focus: focusPosition,
|
1006
|
-
anchor: anchorPosition
|
1007
|
-
};
|
1008
|
-
}
|
1009
|
-
}
|
1010
|
-
}
|
1011
|
-
}
|
1012
|
-
return null;
|
1013
|
-
}
|
1014
1027
|
};
|
1015
1028
|
exports.CollabHistory = __decorate([
|
1016
1029
|
core$1.Injectable(),
|
@@ -1107,8 +1120,9 @@ exports.MultipleDocCollabHistory = class MultipleDocCollabHistory {
|
|
1107
1120
|
get canForward() {
|
1108
1121
|
return this.actionStack.length > 0 && this.index < this.actionStack.length;
|
1109
1122
|
}
|
1110
|
-
constructor(collaborate, rootComponentRef, stackSize, undoManagerConfig) {
|
1123
|
+
constructor(collaborate, scheduler, rootComponentRef, stackSize, undoManagerConfig) {
|
1111
1124
|
this.collaborate = collaborate;
|
1125
|
+
this.scheduler = scheduler;
|
1112
1126
|
this.rootComponentRef = rootComponentRef;
|
1113
1127
|
this.stackSize = stackSize;
|
1114
1128
|
this.undoManagerConfig = undoManagerConfig;
|
@@ -1121,6 +1135,7 @@ exports.MultipleDocCollabHistory = class MultipleDocCollabHistory {
|
|
1121
1135
|
this.index = 0;
|
1122
1136
|
this.stackItem = null;
|
1123
1137
|
this.timer = null;
|
1138
|
+
this.beforePosition = null;
|
1124
1139
|
this.subscription = new stream.Subscription();
|
1125
1140
|
this.subDocs = new Set();
|
1126
1141
|
this.listenerCaches = new Set();
|
@@ -1143,6 +1158,8 @@ exports.MultipleDocCollabHistory = class MultipleDocCollabHistory {
|
|
1143
1158
|
if (this.isListen) {
|
1144
1159
|
this.listenItem(yType, yDoc);
|
1145
1160
|
}
|
1161
|
+
}), this.scheduler.onLocalChangeBefore.subscribe(() => {
|
1162
|
+
this.beforePosition = this.collaborate.getRelativeCursorLocation();
|
1146
1163
|
}));
|
1147
1164
|
}
|
1148
1165
|
forward() {
|
@@ -1152,9 +1169,10 @@ exports.MultipleDocCollabHistory = class MultipleDocCollabHistory {
|
|
1152
1169
|
clearTimeout(this.timer);
|
1153
1170
|
const item = this.actionStack[this.index];
|
1154
1171
|
if (item) {
|
1155
|
-
for (const i of item) {
|
1172
|
+
for (const i of item.undoManagers) {
|
1156
1173
|
i.redo();
|
1157
1174
|
}
|
1175
|
+
this.collaborate.restoreCursorPosition(item.after);
|
1158
1176
|
}
|
1159
1177
|
this.index++;
|
1160
1178
|
this.forwardEvent.next();
|
@@ -1165,29 +1183,32 @@ exports.MultipleDocCollabHistory = class MultipleDocCollabHistory {
|
|
1165
1183
|
return;
|
1166
1184
|
}
|
1167
1185
|
clearTimeout(this.timer);
|
1168
|
-
let
|
1186
|
+
let historyStackItem;
|
1169
1187
|
if (this.stackItem) {
|
1170
|
-
|
1188
|
+
historyStackItem = this.stackItem;
|
1171
1189
|
this.stackItem = null;
|
1172
1190
|
}
|
1173
1191
|
else {
|
1174
1192
|
this.index--;
|
1175
|
-
|
1193
|
+
historyStackItem = this.actionStack[this.index];
|
1176
1194
|
}
|
1177
|
-
let len =
|
1195
|
+
let len = historyStackItem.undoManagers.length;
|
1178
1196
|
while (len > 0) {
|
1179
1197
|
len--;
|
1180
|
-
|
1198
|
+
historyStackItem.undoManagers[len].undo();
|
1181
1199
|
}
|
1182
|
-
if (
|
1200
|
+
if (historyStackItem) {
|
1201
|
+
const beforePosition = historyStackItem.before;
|
1202
|
+
this.collaborate.restoreCursorPosition(beforePosition);
|
1183
1203
|
this.backEvent.next();
|
1184
1204
|
this.changeEvent.next();
|
1185
1205
|
}
|
1186
1206
|
}
|
1187
1207
|
clear() {
|
1188
1208
|
this.actionStack = [];
|
1189
|
-
this.stackItem =
|
1209
|
+
this.stackItem = null;
|
1190
1210
|
this.index = 0;
|
1211
|
+
this.beforePosition = null;
|
1191
1212
|
clearTimeout(this.timer);
|
1192
1213
|
this.listenerCaches.forEach((undoManager) => {
|
1193
1214
|
undoManager.clear();
|
@@ -1196,6 +1217,7 @@ exports.MultipleDocCollabHistory = class MultipleDocCollabHistory {
|
|
1196
1217
|
}
|
1197
1218
|
destroy() {
|
1198
1219
|
this.clear();
|
1220
|
+
this.beforePosition = this.stackItem = null;
|
1199
1221
|
this.subscription.unsubscribe();
|
1200
1222
|
this.listenerCaches.forEach((undoManager) => {
|
1201
1223
|
undoManager.destroy();
|
@@ -1226,7 +1248,7 @@ exports.MultipleDocCollabHistory = class MultipleDocCollabHistory {
|
|
1226
1248
|
if (this.index != this.actionStack.length) {
|
1227
1249
|
const redoStack = this.actionStack.slice(this.index);
|
1228
1250
|
redoStack.forEach(item => {
|
1229
|
-
item.forEach(i => {
|
1251
|
+
item.undoManagers.forEach(i => {
|
1230
1252
|
i.clear(false, true);
|
1231
1253
|
});
|
1232
1254
|
});
|
@@ -1234,7 +1256,11 @@ exports.MultipleDocCollabHistory = class MultipleDocCollabHistory {
|
|
1234
1256
|
this.changeEvent.next();
|
1235
1257
|
}
|
1236
1258
|
if (this.stackItem === null) {
|
1237
|
-
this.stackItem =
|
1259
|
+
this.stackItem = {
|
1260
|
+
before: this.beforePosition,
|
1261
|
+
after: null,
|
1262
|
+
undoManagers: []
|
1263
|
+
};
|
1238
1264
|
this.timer = setTimeout(() => {
|
1239
1265
|
if (this.actionStack.length >= this.stackSize) {
|
1240
1266
|
this.actionStack.shift();
|
@@ -1242,13 +1268,15 @@ exports.MultipleDocCollabHistory = class MultipleDocCollabHistory {
|
|
1242
1268
|
else {
|
1243
1269
|
this.index++;
|
1244
1270
|
}
|
1271
|
+
// this.beforePosition = this.collaborate.getRelativeCursorLocation()
|
1272
|
+
this.stackItem.after = this.beforePosition;
|
1245
1273
|
this.actionStack.push(this.stackItem);
|
1246
1274
|
this.stackItem = null;
|
1247
1275
|
this.pushEvent.next();
|
1248
1276
|
this.changeEvent.next();
|
1249
1277
|
}, 500);
|
1250
1278
|
}
|
1251
|
-
this.stackItem.push(undoManager);
|
1279
|
+
this.stackItem.undoManagers.push(undoManager);
|
1252
1280
|
}
|
1253
1281
|
});
|
1254
1282
|
this.listenerCaches.add(undoManager);
|
@@ -1256,9 +1284,10 @@ exports.MultipleDocCollabHistory = class MultipleDocCollabHistory {
|
|
1256
1284
|
};
|
1257
1285
|
exports.MultipleDocCollabHistory = __decorate([
|
1258
1286
|
core$1.Injectable(),
|
1259
|
-
__param(
|
1260
|
-
__param(
|
1287
|
+
__param(3, core$1.Inject(core.HISTORY_STACK_SIZE)),
|
1288
|
+
__param(4, core$1.Optional()),
|
1261
1289
|
__metadata("design:paramtypes", [exports.Collaborate,
|
1290
|
+
core.Scheduler,
|
1262
1291
|
core.RootComponentRef, Number, CustomUndoManagerConfig])
|
1263
1292
|
], exports.MultipleDocCollabHistory);
|
1264
1293
|
|
@@ -1,9 +1,10 @@
|
|
1
1
|
import { Observable } from '@tanbo/stream';
|
2
|
-
import { History, RootComponentRef } from '@textbus/core';
|
2
|
+
import { History, RootComponentRef, Scheduler } from '@textbus/core';
|
3
3
|
import { Collaborate } from './collaborate';
|
4
4
|
import { CustomUndoManagerConfig } from './collab-history';
|
5
5
|
export declare class MultipleDocCollabHistory implements History {
|
6
6
|
private collaborate;
|
7
|
+
private scheduler;
|
7
8
|
private rootComponentRef;
|
8
9
|
private stackSize;
|
9
10
|
private undoManagerConfig;
|
@@ -22,10 +23,11 @@ export declare class MultipleDocCollabHistory implements History {
|
|
22
23
|
private index;
|
23
24
|
private stackItem;
|
24
25
|
private timer;
|
26
|
+
private beforePosition;
|
25
27
|
private subscription;
|
26
28
|
private subDocs;
|
27
29
|
private listenerCaches;
|
28
|
-
constructor(collaborate: Collaborate, rootComponentRef: RootComponentRef, stackSize: number, undoManagerConfig: CustomUndoManagerConfig);
|
30
|
+
constructor(collaborate: Collaborate, scheduler: Scheduler, rootComponentRef: RootComponentRef, stackSize: number, undoManagerConfig: CustomUndoManagerConfig);
|
29
31
|
listen(): void;
|
30
32
|
forward(): void;
|
31
33
|
back(): void;
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@textbus/collaborate",
|
3
|
-
"version": "4.1.0
|
3
|
+
"version": "4.1.0",
|
4
4
|
"description": "Textbus is a rich text editor and framework that is highly customizable and extensible to achieve rich wysiwyg effects.",
|
5
5
|
"main": "./bundles/index.js",
|
6
6
|
"module": "./bundles/index.esm.js",
|
@@ -27,8 +27,8 @@
|
|
27
27
|
"dependencies": {
|
28
28
|
"@hocuspocus/provider": "^2.13.6",
|
29
29
|
"@tanbo/stream": "^1.2.5",
|
30
|
-
"@textbus/core": "^4.1.0
|
31
|
-
"@viewfly/core": "^1.0.
|
30
|
+
"@textbus/core": "^4.1.0",
|
31
|
+
"@viewfly/core": "^1.0.5",
|
32
32
|
"y-websocket": "^1.4.3",
|
33
33
|
"yjs": "^13.6.14"
|
34
34
|
},
|