@textbus/collaborate 4.1.0-alpha.0 → 4.1.0-alpha.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/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 +2 -2
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-alpha.
|
|
3
|
+
"version": "4.1.0-alpha.1",
|
|
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",
|
|
@@ -50,5 +50,5 @@
|
|
|
50
50
|
"bugs": {
|
|
51
51
|
"url": "https://github.com/textbus/textbus.git/issues"
|
|
52
52
|
},
|
|
53
|
-
"gitHead": "
|
|
53
|
+
"gitHead": "04567b43046abd508826c795a27531b37a7753e3"
|
|
54
54
|
}
|