@textbus/collaborate 2.5.9 → 2.5.11

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, History, Registry, RootComponentRef, Scheduler, Selection, SelectionPaths, Slot, Starter, Translator } from '@textbus/core';
2
+ import { AbstractSelection, ComponentInstance, Controller, History, Registry, RootComponentRef, Scheduler, Selection, SelectionPaths, Slot, Starter, Translator } 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
  import { CollaborateCursor, RemoteSelection } from './collaborate-cursor';
5
5
  interface CursorPosition {
@@ -54,6 +54,8 @@ export declare class Collaborate implements History {
54
54
  protected contentMap: ContentMap;
55
55
  protected updateRemoteActions: Array<UpdateItem>;
56
56
  protected noRecord: {};
57
+ protected historyItems: Array<CursorPosition | null>;
58
+ protected index: number;
57
59
  constructor(stackSize: number, rootComponentRef: RootComponentRef, collaborateCursor: CollaborateCursor, controller: Controller, scheduler: Scheduler, translator: Translator, registry: Registry, selection: Selection, starter: Starter);
58
60
  listen(): void;
59
61
  updateRemoteSelection(paths: RemoteSelection[]): void;
@@ -62,7 +64,7 @@ export declare class Collaborate implements History {
62
64
  clear(): void;
63
65
  destroy(): void;
64
66
  protected syncRootComponent(root: YMap<any>, rootComponent: ComponentInstance): void;
65
- protected restoreCursorLocation(position: CursorPosition): void;
67
+ protected getAbstractSelection(position: CursorPosition): AbstractSelection | null;
66
68
  protected getRelativeCursorLocation(): CursorPosition | null;
67
69
  protected syncContent(content: YText, slot: Slot): void;
68
70
  protected syncSlot(remoteSlot: YMap<any>, slot: Slot): void;
@@ -371,6 +371,8 @@ let Collaborate = class Collaborate {
371
371
  this.contentMap = new ContentMap();
372
372
  this.updateRemoteActions = [];
373
373
  this.noRecord = {};
374
+ this.historyItems = [];
375
+ this.index = 0;
374
376
  this.onSelectionChange = this.selectionChangeEvent.asObservable().pipe(delay());
375
377
  this.onBack = this.backEvent.asObservable();
376
378
  this.onForward = this.forwardEvent.asObservable();
@@ -389,25 +391,43 @@ let Collaborate = class Collaborate {
389
391
  listen() {
390
392
  const root = this.yDoc.getMap('RootComponent');
391
393
  const rootComponent = this.rootComponentRef.component;
392
- this.manager = new UndoManager(root, {
394
+ const manager = new UndoManager(root, {
393
395
  trackedOrigins: new Set([this.yDoc])
394
396
  });
395
- const cursorKey = 'cursor-position';
396
- this.manager.on('stack-item-added', event => {
397
- event.stackItem.meta.set(cursorKey, this.getRelativeCursorLocation());
398
- if (this.manager.undoStack.length > this.stackSize) {
399
- this.manager.undoStack.shift();
397
+ this.manager = manager;
398
+ manager.on('stack-item-added', event => {
399
+ if (event.type === 'undo') {
400
+ if (event.origin === manager) {
401
+ this.index++;
402
+ }
403
+ else {
404
+ this.historyItems.length = this.index;
405
+ this.historyItems.push(this.getRelativeCursorLocation());
406
+ this.index++;
407
+ }
408
+ }
409
+ else {
410
+ this.index--;
411
+ }
412
+ if (manager.undoStack.length > this.stackSize) {
413
+ this.historyItems.shift();
414
+ manager.undoStack.shift();
400
415
  }
401
416
  if (event.origin === this.yDoc) {
402
417
  this.pushEvent.next();
403
418
  }
404
419
  this.changeEvent.next();
405
420
  });
406
- this.manager.on('stack-item-popped', event => {
407
- const position = event.stackItem.meta.get(cursorKey);
421
+ manager.on('stack-item-popped', () => {
422
+ const position = this.historyItems[this.index - 1];
408
423
  if (position) {
409
- this.restoreCursorLocation(position);
424
+ const selection = this.getAbstractSelection(position);
425
+ if (selection) {
426
+ this.selection.setBaseAndExtent(selection.anchorSlot, selection.anchorOffset, selection.focusSlot, selection.focusOffset);
427
+ return;
428
+ }
410
429
  }
430
+ this.selection.unSelect();
411
431
  });
412
432
  this.subscriptions.push(this.selection.onChange.subscribe(() => {
413
433
  const paths = this.selection.getPaths();
@@ -471,11 +491,15 @@ let Collaborate = class Collaborate {
471
491
  }
472
492
  clear() {
473
493
  var _a;
494
+ this.index = 0;
495
+ this.historyItems = [];
474
496
  (_a = this.manager) === null || _a === void 0 ? void 0 : _a.clear();
475
497
  this.changeEvent.next();
476
498
  }
477
499
  destroy() {
478
500
  var _a;
501
+ this.index = 0;
502
+ this.historyItems = [];
479
503
  this.subscriptions.forEach(i => i.unsubscribe());
480
504
  this.collaborateCursor.destroy();
481
505
  (_a = this.manager) === null || _a === void 0 ? void 0 : _a.destroy();
@@ -519,18 +543,22 @@ let Collaborate = class Collaborate {
519
543
  this.syncComponent(root, rootComponent);
520
544
  this.syncSlots(slots, rootComponent);
521
545
  }
522
- restoreCursorLocation(position) {
546
+ getAbstractSelection(position) {
523
547
  const anchorPosition = createAbsolutePositionFromRelativePosition(position.anchor, this.yDoc);
524
548
  const focusPosition = createAbsolutePositionFromRelativePosition(position.focus, this.yDoc);
525
549
  if (anchorPosition && focusPosition) {
526
550
  const focusSlot = this.contentMap.get(focusPosition.type);
527
551
  const anchorSlot = this.contentMap.get(anchorPosition.type);
528
552
  if (focusSlot && anchorSlot) {
529
- this.selection.setBaseAndExtent(anchorSlot, anchorPosition.index, focusSlot, focusPosition.index);
530
- return;
553
+ return {
554
+ anchorSlot,
555
+ anchorOffset: anchorPosition.index,
556
+ focusSlot,
557
+ focusOffset: focusPosition.index
558
+ };
531
559
  }
532
560
  }
533
- this.selection.unSelect();
561
+ return null;
534
562
  }
535
563
  getRelativeCursorLocation() {
536
564
  const { anchorSlot, anchorOffset, focusSlot, focusOffset } = this.selection;
@@ -991,7 +1019,7 @@ const collaborateModule = {
991
1019
  CollaborateCursor,
992
1020
  {
993
1021
  provide: History,
994
- useClass: Collaborate
1022
+ useExisting: Collaborate
995
1023
  }
996
1024
  ]
997
1025
  };
package/bundles/index.js CHANGED
@@ -373,6 +373,8 @@ exports.Collaborate = class Collaborate {
373
373
  this.contentMap = new ContentMap();
374
374
  this.updateRemoteActions = [];
375
375
  this.noRecord = {};
376
+ this.historyItems = [];
377
+ this.index = 0;
376
378
  this.onSelectionChange = this.selectionChangeEvent.asObservable().pipe(stream.delay());
377
379
  this.onBack = this.backEvent.asObservable();
378
380
  this.onForward = this.forwardEvent.asObservable();
@@ -391,25 +393,43 @@ exports.Collaborate = class Collaborate {
391
393
  listen() {
392
394
  const root = this.yDoc.getMap('RootComponent');
393
395
  const rootComponent = this.rootComponentRef.component;
394
- this.manager = new yjs.UndoManager(root, {
396
+ const manager = new yjs.UndoManager(root, {
395
397
  trackedOrigins: new Set([this.yDoc])
396
398
  });
397
- const cursorKey = 'cursor-position';
398
- this.manager.on('stack-item-added', event => {
399
- event.stackItem.meta.set(cursorKey, this.getRelativeCursorLocation());
400
- if (this.manager.undoStack.length > this.stackSize) {
401
- this.manager.undoStack.shift();
399
+ this.manager = manager;
400
+ manager.on('stack-item-added', event => {
401
+ if (event.type === 'undo') {
402
+ if (event.origin === manager) {
403
+ this.index++;
404
+ }
405
+ else {
406
+ this.historyItems.length = this.index;
407
+ this.historyItems.push(this.getRelativeCursorLocation());
408
+ this.index++;
409
+ }
410
+ }
411
+ else {
412
+ this.index--;
413
+ }
414
+ if (manager.undoStack.length > this.stackSize) {
415
+ this.historyItems.shift();
416
+ manager.undoStack.shift();
402
417
  }
403
418
  if (event.origin === this.yDoc) {
404
419
  this.pushEvent.next();
405
420
  }
406
421
  this.changeEvent.next();
407
422
  });
408
- this.manager.on('stack-item-popped', event => {
409
- const position = event.stackItem.meta.get(cursorKey);
423
+ manager.on('stack-item-popped', () => {
424
+ const position = this.historyItems[this.index - 1];
410
425
  if (position) {
411
- this.restoreCursorLocation(position);
426
+ const selection = this.getAbstractSelection(position);
427
+ if (selection) {
428
+ this.selection.setBaseAndExtent(selection.anchorSlot, selection.anchorOffset, selection.focusSlot, selection.focusOffset);
429
+ return;
430
+ }
412
431
  }
432
+ this.selection.unSelect();
413
433
  });
414
434
  this.subscriptions.push(this.selection.onChange.subscribe(() => {
415
435
  const paths = this.selection.getPaths();
@@ -473,11 +493,15 @@ exports.Collaborate = class Collaborate {
473
493
  }
474
494
  clear() {
475
495
  var _a;
496
+ this.index = 0;
497
+ this.historyItems = [];
476
498
  (_a = this.manager) === null || _a === void 0 ? void 0 : _a.clear();
477
499
  this.changeEvent.next();
478
500
  }
479
501
  destroy() {
480
502
  var _a;
503
+ this.index = 0;
504
+ this.historyItems = [];
481
505
  this.subscriptions.forEach(i => i.unsubscribe());
482
506
  this.collaborateCursor.destroy();
483
507
  (_a = this.manager) === null || _a === void 0 ? void 0 : _a.destroy();
@@ -521,18 +545,22 @@ exports.Collaborate = class Collaborate {
521
545
  this.syncComponent(root, rootComponent);
522
546
  this.syncSlots(slots, rootComponent);
523
547
  }
524
- restoreCursorLocation(position) {
548
+ getAbstractSelection(position) {
525
549
  const anchorPosition = yjs.createAbsolutePositionFromRelativePosition(position.anchor, this.yDoc);
526
550
  const focusPosition = yjs.createAbsolutePositionFromRelativePosition(position.focus, this.yDoc);
527
551
  if (anchorPosition && focusPosition) {
528
552
  const focusSlot = this.contentMap.get(focusPosition.type);
529
553
  const anchorSlot = this.contentMap.get(anchorPosition.type);
530
554
  if (focusSlot && anchorSlot) {
531
- this.selection.setBaseAndExtent(anchorSlot, anchorPosition.index, focusSlot, focusPosition.index);
532
- return;
555
+ return {
556
+ anchorSlot,
557
+ anchorOffset: anchorPosition.index,
558
+ focusSlot,
559
+ focusOffset: focusPosition.index
560
+ };
533
561
  }
534
562
  }
535
- this.selection.unSelect();
563
+ return null;
536
564
  }
537
565
  getRelativeCursorLocation() {
538
566
  const { anchorSlot, anchorOffset, focusSlot, focusOffset } = this.selection;
@@ -993,7 +1021,7 @@ const collaborateModule = {
993
1021
  exports.CollaborateCursor,
994
1022
  {
995
1023
  provide: core.History,
996
- useClass: exports.Collaborate
1024
+ useExisting: exports.Collaborate
997
1025
  }
998
1026
  ]
999
1027
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@textbus/collaborate",
3
- "version": "2.5.9",
3
+ "version": "2.5.11",
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
  "@tanbo/di": "^1.1.4",
29
29
  "@tanbo/stream": "^1.1.8",
30
- "@textbus/browser": "^2.5.9",
31
- "@textbus/core": "^2.5.9",
30
+ "@textbus/browser": "^2.5.11",
31
+ "@textbus/core": "^2.5.11",
32
32
  "reflect-metadata": "^0.1.13",
33
33
  "y-protocols": "^1.0.5",
34
34
  "yjs": "^13.5.39"
@@ -51,5 +51,5 @@
51
51
  "bugs": {
52
52
  "url": "https://github.com/textbus/textbus.git/issues"
53
53
  },
54
- "gitHead": "02dc4cd87f33a9bbfc52a1fc44b2d598de413663"
54
+ "gitHead": "4a79138c9784079d92500a41ca728afc7a438e3e"
55
55
  }