@textbus/collaborate 3.0.0-alpha.30 → 3.0.0-alpha.31

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.
@@ -1,5 +1,5 @@
1
1
  import { Observable, Subject, Subscription } from '@tanbo/stream';
2
- import { ComponentInstance, Controller, Factory, History, RootComponentRef, Scheduler, Selection, SelectionPaths, Slot, Starter } from '@textbus/core';
2
+ import { AbstractSelection, ComponentInstance, Controller, Factory, History, RootComponentRef, Scheduler, Selection, SelectionPaths, Slot, Starter } from '@textbus/core';
3
3
  import { Array as YArray, Doc as YDoc, Map as YMap, RelativePosition, Text as YText, Transaction, UndoManager } from 'yjs';
4
4
  interface CursorPosition {
5
5
  anchor: RelativePosition;
@@ -50,6 +50,8 @@ export declare class Collaborate implements History {
50
50
  protected contentMap: ContentMap;
51
51
  protected updateRemoteActions: Array<UpdateItem>;
52
52
  protected noRecord: {};
53
+ protected historyItems: Array<CursorPosition | null>;
54
+ protected index: number;
53
55
  constructor(stackSize: number, rootComponentRef: RootComponentRef, controller: Controller, scheduler: Scheduler, factory: Factory, selection: Selection, starter: Starter);
54
56
  listen(): void;
55
57
  back(): void;
@@ -57,7 +59,7 @@ export declare class Collaborate implements History {
57
59
  clear(): void;
58
60
  destroy(): void;
59
61
  protected syncRootComponent(root: YMap<any>, rootComponent: ComponentInstance): void;
60
- protected restoreCursorLocation(position: CursorPosition): void;
62
+ protected getAbstractSelection(position: CursorPosition): AbstractSelection | null;
61
63
  protected getRelativeCursorLocation(): CursorPosition | null;
62
64
  protected syncSlotContent(content: YText, slot: Slot): void;
63
65
  protected syncSlotState(remoteSlot: YMap<any>, slot: Slot): void;
@@ -98,6 +98,8 @@ let Collaborate = class Collaborate {
98
98
  this.contentMap = new ContentMap();
99
99
  this.updateRemoteActions = [];
100
100
  this.noRecord = {};
101
+ this.historyItems = [];
102
+ this.index = 0;
101
103
  this.onBack = this.backEvent.asObservable();
102
104
  this.onForward = this.forwardEvent.asObservable();
103
105
  this.onChange = this.changeEvent.asObservable();
@@ -115,25 +117,43 @@ let Collaborate = class Collaborate {
115
117
  listen() {
116
118
  const root = this.yDoc.getMap('RootComponent');
117
119
  const rootComponent = this.rootComponentRef.component;
118
- this.manager = new UndoManager(root, {
120
+ const manager = new UndoManager(root, {
119
121
  trackedOrigins: new Set([this.yDoc])
120
122
  });
121
- const cursorKey = 'cursor-position';
122
- this.manager.on('stack-item-added', event => {
123
- event.stackItem.meta.set(cursorKey, this.getRelativeCursorLocation());
124
- if (this.manager.undoStack.length > this.stackSize) {
125
- this.manager.undoStack.shift();
123
+ this.manager = manager;
124
+ manager.on('stack-item-added', event => {
125
+ if (event.type === 'undo') {
126
+ if (event.origin === manager) {
127
+ this.index++;
128
+ }
129
+ else {
130
+ this.historyItems.length = this.index;
131
+ this.historyItems.push(this.getRelativeCursorLocation());
132
+ this.index++;
133
+ }
134
+ }
135
+ else {
136
+ this.index--;
137
+ }
138
+ if (manager.undoStack.length > this.stackSize) {
139
+ this.historyItems.shift();
140
+ manager.undoStack.shift();
126
141
  }
127
142
  if (event.origin === this.yDoc) {
128
143
  this.pushEvent.next();
129
144
  }
130
145
  this.changeEvent.next();
131
146
  });
132
- this.manager.on('stack-item-popped', event => {
133
- const position = event.stackItem.meta.get(cursorKey);
147
+ manager.on('stack-item-popped', () => {
148
+ const position = this.historyItems[this.index - 1];
134
149
  if (position) {
135
- this.restoreCursorLocation(position);
150
+ const selection = this.getAbstractSelection(position);
151
+ if (selection) {
152
+ this.selection.setBaseAndExtent(selection.anchorSlot, selection.anchorOffset, selection.focusSlot, selection.focusOffset);
153
+ return;
154
+ }
136
155
  }
156
+ this.selection.unSelect();
137
157
  });
138
158
  this.subscriptions.push(this.selection.onChange.subscribe(() => {
139
159
  const paths = this.selection.getPaths();
@@ -194,11 +214,15 @@ let Collaborate = class Collaborate {
194
214
  }
195
215
  clear() {
196
216
  var _a;
217
+ this.index = 0;
218
+ this.historyItems = [];
197
219
  (_a = this.manager) === null || _a === void 0 ? void 0 : _a.clear();
198
220
  this.changeEvent.next();
199
221
  }
200
222
  destroy() {
201
223
  var _a;
224
+ this.index = 0;
225
+ this.historyItems = [];
202
226
  this.subscriptions.forEach(i => i.unsubscribe());
203
227
  (_a = this.manager) === null || _a === void 0 ? void 0 : _a.destroy();
204
228
  }
@@ -241,18 +265,22 @@ let Collaborate = class Collaborate {
241
265
  this.syncComponentState(root, rootComponent);
242
266
  this.syncComponentSlots(slots, rootComponent);
243
267
  }
244
- restoreCursorLocation(position) {
268
+ getAbstractSelection(position) {
245
269
  const anchorPosition = createAbsolutePositionFromRelativePosition(position.anchor, this.yDoc);
246
270
  const focusPosition = createAbsolutePositionFromRelativePosition(position.focus, this.yDoc);
247
271
  if (anchorPosition && focusPosition) {
248
272
  const focusSlot = this.contentMap.get(focusPosition.type);
249
273
  const anchorSlot = this.contentMap.get(anchorPosition.type);
250
274
  if (focusSlot && anchorSlot) {
251
- this.selection.setBaseAndExtent(anchorSlot, anchorPosition.index, focusSlot, focusPosition.index);
252
- return;
275
+ return {
276
+ anchorSlot,
277
+ anchorOffset: anchorPosition.index,
278
+ focusSlot,
279
+ focusOffset: focusPosition.index
280
+ };
253
281
  }
254
282
  }
255
- this.selection.unSelect();
283
+ return null;
256
284
  }
257
285
  getRelativeCursorLocation() {
258
286
  const { anchorSlot, anchorOffset, focusSlot, focusOffset } = this.selection;
package/bundles/index.js CHANGED
@@ -100,6 +100,8 @@ exports.Collaborate = class Collaborate {
100
100
  this.contentMap = new ContentMap();
101
101
  this.updateRemoteActions = [];
102
102
  this.noRecord = {};
103
+ this.historyItems = [];
104
+ this.index = 0;
103
105
  this.onBack = this.backEvent.asObservable();
104
106
  this.onForward = this.forwardEvent.asObservable();
105
107
  this.onChange = this.changeEvent.asObservable();
@@ -117,25 +119,43 @@ exports.Collaborate = class Collaborate {
117
119
  listen() {
118
120
  const root = this.yDoc.getMap('RootComponent');
119
121
  const rootComponent = this.rootComponentRef.component;
120
- this.manager = new yjs.UndoManager(root, {
122
+ const manager = new yjs.UndoManager(root, {
121
123
  trackedOrigins: new Set([this.yDoc])
122
124
  });
123
- const cursorKey = 'cursor-position';
124
- this.manager.on('stack-item-added', event => {
125
- event.stackItem.meta.set(cursorKey, this.getRelativeCursorLocation());
126
- if (this.manager.undoStack.length > this.stackSize) {
127
- this.manager.undoStack.shift();
125
+ this.manager = manager;
126
+ manager.on('stack-item-added', event => {
127
+ if (event.type === 'undo') {
128
+ if (event.origin === manager) {
129
+ this.index++;
130
+ }
131
+ else {
132
+ this.historyItems.length = this.index;
133
+ this.historyItems.push(this.getRelativeCursorLocation());
134
+ this.index++;
135
+ }
136
+ }
137
+ else {
138
+ this.index--;
139
+ }
140
+ if (manager.undoStack.length > this.stackSize) {
141
+ this.historyItems.shift();
142
+ manager.undoStack.shift();
128
143
  }
129
144
  if (event.origin === this.yDoc) {
130
145
  this.pushEvent.next();
131
146
  }
132
147
  this.changeEvent.next();
133
148
  });
134
- this.manager.on('stack-item-popped', event => {
135
- const position = event.stackItem.meta.get(cursorKey);
149
+ manager.on('stack-item-popped', () => {
150
+ const position = this.historyItems[this.index - 1];
136
151
  if (position) {
137
- this.restoreCursorLocation(position);
152
+ const selection = this.getAbstractSelection(position);
153
+ if (selection) {
154
+ this.selection.setBaseAndExtent(selection.anchorSlot, selection.anchorOffset, selection.focusSlot, selection.focusOffset);
155
+ return;
156
+ }
138
157
  }
158
+ this.selection.unSelect();
139
159
  });
140
160
  this.subscriptions.push(this.selection.onChange.subscribe(() => {
141
161
  const paths = this.selection.getPaths();
@@ -196,11 +216,15 @@ exports.Collaborate = class Collaborate {
196
216
  }
197
217
  clear() {
198
218
  var _a;
219
+ this.index = 0;
220
+ this.historyItems = [];
199
221
  (_a = this.manager) === null || _a === void 0 ? void 0 : _a.clear();
200
222
  this.changeEvent.next();
201
223
  }
202
224
  destroy() {
203
225
  var _a;
226
+ this.index = 0;
227
+ this.historyItems = [];
204
228
  this.subscriptions.forEach(i => i.unsubscribe());
205
229
  (_a = this.manager) === null || _a === void 0 ? void 0 : _a.destroy();
206
230
  }
@@ -243,18 +267,22 @@ exports.Collaborate = class Collaborate {
243
267
  this.syncComponentState(root, rootComponent);
244
268
  this.syncComponentSlots(slots, rootComponent);
245
269
  }
246
- restoreCursorLocation(position) {
270
+ getAbstractSelection(position) {
247
271
  const anchorPosition = yjs.createAbsolutePositionFromRelativePosition(position.anchor, this.yDoc);
248
272
  const focusPosition = yjs.createAbsolutePositionFromRelativePosition(position.focus, this.yDoc);
249
273
  if (anchorPosition && focusPosition) {
250
274
  const focusSlot = this.contentMap.get(focusPosition.type);
251
275
  const anchorSlot = this.contentMap.get(anchorPosition.type);
252
276
  if (focusSlot && anchorSlot) {
253
- this.selection.setBaseAndExtent(anchorSlot, anchorPosition.index, focusSlot, focusPosition.index);
254
- return;
277
+ return {
278
+ anchorSlot,
279
+ anchorOffset: anchorPosition.index,
280
+ focusSlot,
281
+ focusOffset: focusPosition.index
282
+ };
255
283
  }
256
284
  }
257
- this.selection.unSelect();
285
+ return null;
258
286
  }
259
287
  getRelativeCursorLocation() {
260
288
  const { anchorSlot, anchorOffset, focusSlot, focusOffset } = this.selection;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@textbus/collaborate",
3
- "version": "3.0.0-alpha.30",
3
+ "version": "3.0.0-alpha.31",
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,7 +27,7 @@
27
27
  "dependencies": {
28
28
  "@tanbo/di": "^1.1.4",
29
29
  "@tanbo/stream": "^1.1.8",
30
- "@textbus/core": "^3.0.0-alpha.30",
30
+ "@textbus/core": "^3.0.0-alpha.31",
31
31
  "reflect-metadata": "^0.1.13",
32
32
  "y-protocols": "^1.0.5",
33
33
  "yjs": "^13.5.39"
@@ -50,5 +50,5 @@
50
50
  "bugs": {
51
51
  "url": "https://github.com/textbus/textbus.git/issues"
52
52
  },
53
- "gitHead": "5e6ca16bf169e611d816d58b9a98118073a41e47"
53
+ "gitHead": "341e11b65b5c82b1f4815f33831b2dfa5d49e1bc"
54
54
  }