@textbus/collaborate 3.0.0-alpha.18 → 3.0.0-alpha.20

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,7 +1,6 @@
1
1
  import { Observable, Subject, Subscription } from '@tanbo/stream';
2
2
  import { 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
- import { CollaborateCursor, RemoteSelection } from './collaborate-cursor';
5
4
  interface CursorPosition {
6
5
  anchor: RelativePosition;
7
6
  focus: RelativePosition;
@@ -22,13 +21,11 @@ interface UpdateItem {
22
21
  export declare class Collaborate implements History {
23
22
  protected stackSize: number;
24
23
  protected rootComponentRef: RootComponentRef;
25
- protected collaborateCursor: CollaborateCursor;
26
24
  protected controller: Controller;
27
25
  protected scheduler: Scheduler;
28
26
  protected factory: Factory;
29
27
  protected selection: Selection;
30
28
  protected starter: Starter;
31
- onSelectionChange: Observable<SelectionPaths>;
32
29
  yDoc: YDoc;
33
30
  onBack: Observable<void>;
34
31
  onForward: Observable<void>;
@@ -51,9 +48,8 @@ export declare class Collaborate implements History {
51
48
  protected contentMap: ContentMap;
52
49
  protected updateRemoteActions: Array<UpdateItem>;
53
50
  protected noRecord: {};
54
- constructor(stackSize: number, rootComponentRef: RootComponentRef, collaborateCursor: CollaborateCursor, controller: Controller, scheduler: Scheduler, factory: Factory, selection: Selection, starter: Starter);
51
+ constructor(stackSize: number, rootComponentRef: RootComponentRef, controller: Controller, scheduler: Scheduler, factory: Factory, selection: Selection, starter: Starter);
55
52
  listen(): void;
56
- updateRemoteSelection(paths: RemoteSelection[]): void;
57
53
  back(): void;
58
54
  forward(): void;
59
55
  clear(): void;
@@ -69,7 +65,7 @@ export declare class Collaborate implements History {
69
65
  protected runRemoteUpdate(tr: Transaction, fn: () => void): void;
70
66
  protected createSharedComponentByComponent(component: ComponentInstance): YMap<any>;
71
67
  protected createSharedSlotBySlot(slot: Slot): YMap<any>;
72
- protected createComponentBySharedComponent(yMap: YMap<any>, canInsertInlineComponent: boolean): ComponentInstance;
68
+ protected createComponentBySharedComponent(yMap: YMap<any>): ComponentInstance;
73
69
  protected createSlotBySharedSlot(sharedSlot: YMap<any>): Slot;
74
70
  protected cleanSubscriptionsBySlot(slot: Slot): void;
75
71
  protected cleanSubscriptionsByComponent(component: ComponentInstance): void;
@@ -1,8 +1,7 @@
1
- import { Scheduler, Selection, defineComponent, ContentType, VElement, makeError, HISTORY_STACK_SIZE, ChangeOrigin, Slot, RootComponentRef, Controller, Factory, Starter, History } from '@textbus/core';
2
- import { Injectable, Inject, Optional } from '@tanbo/di';
3
- import { Subject, Subscription, fromEvent, delay, map, filter } from '@tanbo/stream';
1
+ import { makeError, HISTORY_STACK_SIZE, ChangeOrigin, Slot, RootComponentRef, Controller, Scheduler, Factory, Selection, Starter, History } from '@textbus/core';
2
+ import { Injectable, Inject } from '@tanbo/di';
3
+ import { Subject, map, filter } from '@tanbo/stream';
4
4
  import { Doc, UndoManager, Array, createAbsolutePositionFromRelativePosition, createRelativePositionFromTypeIndex, Map, Text } from 'yjs';
5
- import { VIEW_CONTAINER, createElement, getLayoutRectByRange, SelectionBridge } from '@textbus/browser';
6
5
 
7
6
  /*! *****************************************************************************
8
7
  Copyright (c) Microsoft Corporation.
@@ -34,283 +33,6 @@ function __metadata(metadataKey, metadataValue) {
34
33
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
35
34
  }
36
35
 
37
- class CollaborateSelectionAwarenessDelegate {
38
- }
39
- let CollaborateCursor = class CollaborateCursor {
40
- constructor(container, awarenessDelegate, nativeSelection, scheduler, selection) {
41
- this.container = container;
42
- this.awarenessDelegate = awarenessDelegate;
43
- this.nativeSelection = nativeSelection;
44
- this.scheduler = scheduler;
45
- this.selection = selection;
46
- this.host = createElement('div', {
47
- styles: {
48
- position: 'absolute',
49
- left: 0,
50
- top: 0,
51
- width: '100%',
52
- height: '100%',
53
- pointerEvents: 'none',
54
- zIndex: 1
55
- }
56
- });
57
- this.canvasContainer = createElement('div', {
58
- styles: {
59
- position: 'absolute',
60
- left: 0,
61
- top: 0,
62
- width: '100%',
63
- height: '100%',
64
- overflow: 'hidden'
65
- }
66
- });
67
- this.canvas = createElement('canvas', {
68
- styles: {
69
- position: 'absolute',
70
- opacity: 0.5,
71
- left: 0,
72
- top: 0,
73
- width: '100%',
74
- height: document.documentElement.clientHeight + 'px',
75
- pointerEvents: 'none',
76
- }
77
- });
78
- this.context = this.canvas.getContext('2d');
79
- this.tooltips = createElement('div', {
80
- styles: {
81
- position: 'absolute',
82
- left: 0,
83
- top: 0,
84
- width: '100%',
85
- height: '100%',
86
- pointerEvents: 'none',
87
- fontSize: '12px',
88
- zIndex: 10
89
- }
90
- });
91
- this.onRectsChange = new Subject();
92
- this.subscription = new Subscription();
93
- this.currentSelection = [];
94
- this.canvasContainer.append(this.canvas);
95
- this.host.append(this.canvasContainer, this.tooltips);
96
- container.prepend(this.host);
97
- this.subscription.add(this.onRectsChange.subscribe(rects => {
98
- for (const rect of rects) {
99
- this.context.fillStyle = rect.color;
100
- this.context.beginPath();
101
- this.context.rect(rect.left, rect.top, rect.width, rect.height);
102
- this.context.fill();
103
- this.context.closePath();
104
- }
105
- }), fromEvent(window, 'resize').subscribe(() => {
106
- this.canvas.style.height = document.documentElement.clientHeight + 'px';
107
- this.refresh();
108
- }), this.scheduler.onDocChanged.subscribe(() => {
109
- this.refresh();
110
- }));
111
- }
112
- refresh() {
113
- this.draw(this.currentSelection);
114
- }
115
- destroy() {
116
- this.subscription.unsubscribe();
117
- }
118
- draw(paths) {
119
- this.currentSelection = paths;
120
- const containerRect = this.container.getBoundingClientRect();
121
- this.canvas.style.top = containerRect.top * -1 + 'px';
122
- this.canvas.width = this.canvas.offsetWidth;
123
- this.canvas.height = this.canvas.offsetHeight;
124
- this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
125
- const users = [];
126
- paths.filter(i => {
127
- return i.paths.anchor.length && i.paths.focus.length;
128
- }).forEach(item => {
129
- const anchorPaths = [...item.paths.anchor];
130
- const focusPaths = [...item.paths.focus];
131
- const anchorOffset = anchorPaths.pop();
132
- const anchorSlot = this.selection.findSlotByPaths(anchorPaths);
133
- const focusOffset = focusPaths.pop();
134
- const focusSlot = this.selection.findSlotByPaths(focusPaths);
135
- if (!anchorSlot || !focusSlot) {
136
- return;
137
- }
138
- const { focus, anchor } = this.nativeSelection.getPositionByRange({
139
- focusOffset,
140
- anchorOffset,
141
- focusSlot,
142
- anchorSlot
143
- });
144
- if (!focus || !anchor) {
145
- return;
146
- }
147
- const nativeRange = document.createRange();
148
- nativeRange.setStart(anchor.node, anchor.offset);
149
- nativeRange.setEnd(focus.node, focus.offset);
150
- if ((anchor.node !== focus.node || anchor.offset !== focus.offset) && nativeRange.collapsed) {
151
- nativeRange.setStart(focus.node, focus.offset);
152
- nativeRange.setEnd(anchor.node, anchor.offset);
153
- }
154
- let rects = false;
155
- if (this.awarenessDelegate) {
156
- rects = this.awarenessDelegate.getRects({
157
- focusOffset,
158
- anchorOffset,
159
- focusSlot,
160
- anchorSlot
161
- }, nativeRange);
162
- }
163
- if (!rects) {
164
- rects = nativeRange.getClientRects();
165
- }
166
- const selectionRects = [];
167
- for (let i = rects.length - 1; i >= 0; i--) {
168
- const rect = rects[i];
169
- selectionRects.push({
170
- id: item.id,
171
- color: item.color,
172
- username: item.username,
173
- left: rect.left - containerRect.left,
174
- top: rect.top,
175
- width: rect.width,
176
- height: rect.height,
177
- });
178
- }
179
- this.onRectsChange.next(selectionRects);
180
- const cursorRange = nativeRange.cloneRange();
181
- cursorRange.setStart(focus.node, focus.offset);
182
- cursorRange.collapse(true);
183
- const cursorRect = getLayoutRectByRange(cursorRange);
184
- const rect = {
185
- id: item.id,
186
- username: item.username,
187
- color: item.color,
188
- left: cursorRect.left - containerRect.left,
189
- top: cursorRect.top - containerRect.top,
190
- width: 2,
191
- height: cursorRect.height
192
- };
193
- if (rect.left < 0 || rect.top < 0 || rect.left > containerRect.width) {
194
- return;
195
- }
196
- users.push(rect);
197
- });
198
- this.drawUserCursor(users);
199
- }
200
- drawUserCursor(rects) {
201
- for (let i = 0; i < rects.length; i++) {
202
- const rect = rects[i];
203
- const { cursor, userTip, anchor } = this.getUserCursor(i);
204
- Object.assign(cursor.style, {
205
- left: rect.left + 'px',
206
- top: rect.top + 'px',
207
- width: rect.width + 'px',
208
- height: rect.height + 'px',
209
- background: rect.color,
210
- display: 'block'
211
- });
212
- anchor.style.background = rect.color;
213
- userTip.innerText = rect.username;
214
- userTip.style.background = rect.color;
215
- }
216
- for (let i = rects.length; i < this.tooltips.children.length; i++) {
217
- this.tooltips.removeChild(this.tooltips.children[i]);
218
- }
219
- }
220
- getUserCursor(index) {
221
- let child = this.tooltips.children[index];
222
- if (child) {
223
- const anchor = child.children[0];
224
- return {
225
- cursor: child,
226
- anchor,
227
- userTip: anchor.children[0]
228
- };
229
- }
230
- const userTip = createElement('span', {
231
- styles: {
232
- position: 'absolute',
233
- display: 'none',
234
- left: '50%',
235
- transform: 'translateX(-50%)',
236
- marginBottom: '2px',
237
- bottom: '100%',
238
- whiteSpace: 'nowrap',
239
- color: '#fff',
240
- boxShadow: '0 1px 2px rgba(0,0,0,.1)',
241
- borderRadius: '3px',
242
- padding: '3px 5px',
243
- pointerEvents: 'none',
244
- }
245
- });
246
- const anchor = createElement('span', {
247
- styles: {
248
- position: 'absolute',
249
- top: '-2px',
250
- left: '-2px',
251
- width: '6px',
252
- height: '6px',
253
- pointerEvents: 'auto',
254
- pointer: 'cursor',
255
- },
256
- children: [userTip],
257
- on: {
258
- mouseenter() {
259
- userTip.style.display = 'block';
260
- },
261
- mouseleave() {
262
- userTip.style.display = 'none';
263
- }
264
- }
265
- });
266
- child = createElement('span', {
267
- styles: {
268
- position: 'absolute',
269
- },
270
- children: [
271
- anchor
272
- ]
273
- });
274
- this.tooltips.append(child);
275
- return {
276
- cursor: child,
277
- anchor,
278
- userTip
279
- };
280
- }
281
- };
282
- CollaborateCursor = __decorate([
283
- Injectable(),
284
- __param(0, Inject(VIEW_CONTAINER)),
285
- __param(1, Optional()),
286
- __metadata("design:paramtypes", [HTMLElement,
287
- CollaborateSelectionAwarenessDelegate,
288
- SelectionBridge,
289
- Scheduler,
290
- Selection])
291
- ], CollaborateCursor);
292
-
293
- function createUnknownComponent(factoryName, canInsertInlineComponent) {
294
- const unknownComponent = defineComponent({
295
- type: canInsertInlineComponent ? ContentType.InlineComponent : ContentType.BlockComponent,
296
- name: 'UnknownComponent',
297
- setup() {
298
- console.error(`cannot find component factory \`${factoryName}\`.`);
299
- return {
300
- render() {
301
- return VElement.createElement('textbus-unknown-component', {
302
- style: {
303
- display: canInsertInlineComponent ? 'inline' : 'block',
304
- color: '#f00'
305
- }
306
- }, unknownComponent.name);
307
- }
308
- };
309
- }
310
- });
311
- return unknownComponent;
312
- }
313
-
314
36
  const collaborateErrorFn = makeError('Collaborate');
315
37
  class ContentMap {
316
38
  constructor() {
@@ -351,10 +73,9 @@ class ContentMap {
351
73
  }
352
74
  }
353
75
  let Collaborate = class Collaborate {
354
- constructor(stackSize, rootComponentRef, collaborateCursor, controller, scheduler, factory, selection, starter) {
76
+ constructor(stackSize, rootComponentRef, controller, scheduler, factory, selection, starter) {
355
77
  this.stackSize = stackSize;
356
78
  this.rootComponentRef = rootComponentRef;
357
- this.collaborateCursor = collaborateCursor;
358
79
  this.controller = controller;
359
80
  this.scheduler = scheduler;
360
81
  this.factory = factory;
@@ -376,7 +97,6 @@ let Collaborate = class Collaborate {
376
97
  this.contentMap = new ContentMap();
377
98
  this.updateRemoteActions = [];
378
99
  this.noRecord = {};
379
- this.onSelectionChange = this.selectionChangeEvent.asObservable().pipe(delay());
380
100
  this.onBack = this.backEvent.asObservable();
381
101
  this.onForward = this.forwardEvent.asObservable();
382
102
  this.onChange = this.changeEvent.asObservable();
@@ -455,9 +175,6 @@ let Collaborate = class Collaborate {
455
175
  }));
456
176
  this.syncRootComponent(root, rootComponent);
457
177
  }
458
- updateRemoteSelection(paths) {
459
- this.collaborateCursor.draw(paths);
460
- }
461
178
  back() {
462
179
  var _a;
463
180
  if (this.canBack) {
@@ -480,7 +197,6 @@ let Collaborate = class Collaborate {
480
197
  destroy() {
481
198
  var _a;
482
199
  this.subscriptions.forEach(i => i.unsubscribe());
483
- this.collaborateCursor.destroy();
484
200
  (_a = this.manager) === null || _a === void 0 ? void 0 : _a.destroy();
485
201
  }
486
202
  syncRootComponent(root, rootComponent) {
@@ -601,8 +317,7 @@ let Collaborate = class Collaborate {
601
317
  }
602
318
  else {
603
319
  const sharedComponent = action.insert;
604
- const canInsertInlineComponent = slot.schema.includes(ContentType.InlineComponent);
605
- const component = this.createComponentBySharedComponent(sharedComponent, canInsertInlineComponent);
320
+ const component = this.createComponentBySharedComponent(sharedComponent);
606
321
  this.syncComponentSlots(sharedComponent.get('slots'), component);
607
322
  this.syncComponentState(sharedComponent, component);
608
323
  slot.insert(component);
@@ -896,7 +611,7 @@ let Collaborate = class Collaborate {
896
611
  this.syncSlotState(sharedSlot, slot);
897
612
  return sharedSlot;
898
613
  }
899
- createComponentBySharedComponent(yMap, canInsertInlineComponent) {
614
+ createComponentBySharedComponent(yMap) {
900
615
  const sharedSlots = yMap.get('slots');
901
616
  const slots = [];
902
617
  sharedSlots.forEach(sharedSlot => {
@@ -921,7 +636,7 @@ let Collaborate = class Collaborate {
921
636
  });
922
637
  return instance;
923
638
  }
924
- return createUnknownComponent(name, canInsertInlineComponent).createInstance(this.starter);
639
+ throw collaborateErrorFn(`cannot find component factory \`${name}\`.`);
925
640
  }
926
641
  createSlotBySharedSlot(sharedSlot) {
927
642
  const content = sharedSlot.get('content');
@@ -948,8 +663,7 @@ let Collaborate = class Collaborate {
948
663
  }
949
664
  else {
950
665
  const sharedComponent = action.insert;
951
- const canInsertInlineComponent = slot.schema.includes(ContentType.InlineComponent);
952
- const component = this.createComponentBySharedComponent(sharedComponent, canInsertInlineComponent);
666
+ const component = this.createComponentBySharedComponent(sharedComponent);
953
667
  slot.insert(component, remoteFormatsToLocal(this.factory, action.attributes));
954
668
  this.syncComponentSlots(sharedComponent.get('slots'), component);
955
669
  this.syncComponentState(sharedComponent, component);
@@ -989,7 +703,6 @@ Collaborate = __decorate([
989
703
  Injectable(),
990
704
  __param(0, Inject(HISTORY_STACK_SIZE)),
991
705
  __metadata("design:paramtypes", [Number, RootComponentRef,
992
- CollaborateCursor,
993
706
  Controller,
994
707
  Scheduler,
995
708
  Factory,
@@ -1012,7 +725,6 @@ function remoteFormatsToLocal(factory, attrs) {
1012
725
  const collaborateModule = {
1013
726
  providers: [
1014
727
  Collaborate,
1015
- CollaborateCursor,
1016
728
  {
1017
729
  provide: History,
1018
730
  useClass: Collaborate
@@ -1020,4 +732,4 @@ const collaborateModule = {
1020
732
  ]
1021
733
  };
1022
734
 
1023
- export { Collaborate, CollaborateCursor, CollaborateSelectionAwarenessDelegate, collaborateModule };
735
+ export { Collaborate, collaborateModule };
package/bundles/index.js CHANGED
@@ -4,7 +4,6 @@ var core = require('@textbus/core');
4
4
  var di = require('@tanbo/di');
5
5
  var stream = require('@tanbo/stream');
6
6
  var yjs = require('yjs');
7
- var browser = require('@textbus/browser');
8
7
 
9
8
  /*! *****************************************************************************
10
9
  Copyright (c) Microsoft Corporation.
@@ -36,283 +35,6 @@ function __metadata(metadataKey, metadataValue) {
36
35
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
37
36
  }
38
37
 
39
- class CollaborateSelectionAwarenessDelegate {
40
- }
41
- exports.CollaborateCursor = class CollaborateCursor {
42
- constructor(container, awarenessDelegate, nativeSelection, scheduler, selection) {
43
- this.container = container;
44
- this.awarenessDelegate = awarenessDelegate;
45
- this.nativeSelection = nativeSelection;
46
- this.scheduler = scheduler;
47
- this.selection = selection;
48
- this.host = browser.createElement('div', {
49
- styles: {
50
- position: 'absolute',
51
- left: 0,
52
- top: 0,
53
- width: '100%',
54
- height: '100%',
55
- pointerEvents: 'none',
56
- zIndex: 1
57
- }
58
- });
59
- this.canvasContainer = browser.createElement('div', {
60
- styles: {
61
- position: 'absolute',
62
- left: 0,
63
- top: 0,
64
- width: '100%',
65
- height: '100%',
66
- overflow: 'hidden'
67
- }
68
- });
69
- this.canvas = browser.createElement('canvas', {
70
- styles: {
71
- position: 'absolute',
72
- opacity: 0.5,
73
- left: 0,
74
- top: 0,
75
- width: '100%',
76
- height: document.documentElement.clientHeight + 'px',
77
- pointerEvents: 'none',
78
- }
79
- });
80
- this.context = this.canvas.getContext('2d');
81
- this.tooltips = browser.createElement('div', {
82
- styles: {
83
- position: 'absolute',
84
- left: 0,
85
- top: 0,
86
- width: '100%',
87
- height: '100%',
88
- pointerEvents: 'none',
89
- fontSize: '12px',
90
- zIndex: 10
91
- }
92
- });
93
- this.onRectsChange = new stream.Subject();
94
- this.subscription = new stream.Subscription();
95
- this.currentSelection = [];
96
- this.canvasContainer.append(this.canvas);
97
- this.host.append(this.canvasContainer, this.tooltips);
98
- container.prepend(this.host);
99
- this.subscription.add(this.onRectsChange.subscribe(rects => {
100
- for (const rect of rects) {
101
- this.context.fillStyle = rect.color;
102
- this.context.beginPath();
103
- this.context.rect(rect.left, rect.top, rect.width, rect.height);
104
- this.context.fill();
105
- this.context.closePath();
106
- }
107
- }), stream.fromEvent(window, 'resize').subscribe(() => {
108
- this.canvas.style.height = document.documentElement.clientHeight + 'px';
109
- this.refresh();
110
- }), this.scheduler.onDocChanged.subscribe(() => {
111
- this.refresh();
112
- }));
113
- }
114
- refresh() {
115
- this.draw(this.currentSelection);
116
- }
117
- destroy() {
118
- this.subscription.unsubscribe();
119
- }
120
- draw(paths) {
121
- this.currentSelection = paths;
122
- const containerRect = this.container.getBoundingClientRect();
123
- this.canvas.style.top = containerRect.top * -1 + 'px';
124
- this.canvas.width = this.canvas.offsetWidth;
125
- this.canvas.height = this.canvas.offsetHeight;
126
- this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
127
- const users = [];
128
- paths.filter(i => {
129
- return i.paths.anchor.length && i.paths.focus.length;
130
- }).forEach(item => {
131
- const anchorPaths = [...item.paths.anchor];
132
- const focusPaths = [...item.paths.focus];
133
- const anchorOffset = anchorPaths.pop();
134
- const anchorSlot = this.selection.findSlotByPaths(anchorPaths);
135
- const focusOffset = focusPaths.pop();
136
- const focusSlot = this.selection.findSlotByPaths(focusPaths);
137
- if (!anchorSlot || !focusSlot) {
138
- return;
139
- }
140
- const { focus, anchor } = this.nativeSelection.getPositionByRange({
141
- focusOffset,
142
- anchorOffset,
143
- focusSlot,
144
- anchorSlot
145
- });
146
- if (!focus || !anchor) {
147
- return;
148
- }
149
- const nativeRange = document.createRange();
150
- nativeRange.setStart(anchor.node, anchor.offset);
151
- nativeRange.setEnd(focus.node, focus.offset);
152
- if ((anchor.node !== focus.node || anchor.offset !== focus.offset) && nativeRange.collapsed) {
153
- nativeRange.setStart(focus.node, focus.offset);
154
- nativeRange.setEnd(anchor.node, anchor.offset);
155
- }
156
- let rects = false;
157
- if (this.awarenessDelegate) {
158
- rects = this.awarenessDelegate.getRects({
159
- focusOffset,
160
- anchorOffset,
161
- focusSlot,
162
- anchorSlot
163
- }, nativeRange);
164
- }
165
- if (!rects) {
166
- rects = nativeRange.getClientRects();
167
- }
168
- const selectionRects = [];
169
- for (let i = rects.length - 1; i >= 0; i--) {
170
- const rect = rects[i];
171
- selectionRects.push({
172
- id: item.id,
173
- color: item.color,
174
- username: item.username,
175
- left: rect.left - containerRect.left,
176
- top: rect.top,
177
- width: rect.width,
178
- height: rect.height,
179
- });
180
- }
181
- this.onRectsChange.next(selectionRects);
182
- const cursorRange = nativeRange.cloneRange();
183
- cursorRange.setStart(focus.node, focus.offset);
184
- cursorRange.collapse(true);
185
- const cursorRect = browser.getLayoutRectByRange(cursorRange);
186
- const rect = {
187
- id: item.id,
188
- username: item.username,
189
- color: item.color,
190
- left: cursorRect.left - containerRect.left,
191
- top: cursorRect.top - containerRect.top,
192
- width: 2,
193
- height: cursorRect.height
194
- };
195
- if (rect.left < 0 || rect.top < 0 || rect.left > containerRect.width) {
196
- return;
197
- }
198
- users.push(rect);
199
- });
200
- this.drawUserCursor(users);
201
- }
202
- drawUserCursor(rects) {
203
- for (let i = 0; i < rects.length; i++) {
204
- const rect = rects[i];
205
- const { cursor, userTip, anchor } = this.getUserCursor(i);
206
- Object.assign(cursor.style, {
207
- left: rect.left + 'px',
208
- top: rect.top + 'px',
209
- width: rect.width + 'px',
210
- height: rect.height + 'px',
211
- background: rect.color,
212
- display: 'block'
213
- });
214
- anchor.style.background = rect.color;
215
- userTip.innerText = rect.username;
216
- userTip.style.background = rect.color;
217
- }
218
- for (let i = rects.length; i < this.tooltips.children.length; i++) {
219
- this.tooltips.removeChild(this.tooltips.children[i]);
220
- }
221
- }
222
- getUserCursor(index) {
223
- let child = this.tooltips.children[index];
224
- if (child) {
225
- const anchor = child.children[0];
226
- return {
227
- cursor: child,
228
- anchor,
229
- userTip: anchor.children[0]
230
- };
231
- }
232
- const userTip = browser.createElement('span', {
233
- styles: {
234
- position: 'absolute',
235
- display: 'none',
236
- left: '50%',
237
- transform: 'translateX(-50%)',
238
- marginBottom: '2px',
239
- bottom: '100%',
240
- whiteSpace: 'nowrap',
241
- color: '#fff',
242
- boxShadow: '0 1px 2px rgba(0,0,0,.1)',
243
- borderRadius: '3px',
244
- padding: '3px 5px',
245
- pointerEvents: 'none',
246
- }
247
- });
248
- const anchor = browser.createElement('span', {
249
- styles: {
250
- position: 'absolute',
251
- top: '-2px',
252
- left: '-2px',
253
- width: '6px',
254
- height: '6px',
255
- pointerEvents: 'auto',
256
- pointer: 'cursor',
257
- },
258
- children: [userTip],
259
- on: {
260
- mouseenter() {
261
- userTip.style.display = 'block';
262
- },
263
- mouseleave() {
264
- userTip.style.display = 'none';
265
- }
266
- }
267
- });
268
- child = browser.createElement('span', {
269
- styles: {
270
- position: 'absolute',
271
- },
272
- children: [
273
- anchor
274
- ]
275
- });
276
- this.tooltips.append(child);
277
- return {
278
- cursor: child,
279
- anchor,
280
- userTip
281
- };
282
- }
283
- };
284
- exports.CollaborateCursor = __decorate([
285
- di.Injectable(),
286
- __param(0, di.Inject(browser.VIEW_CONTAINER)),
287
- __param(1, di.Optional()),
288
- __metadata("design:paramtypes", [HTMLElement,
289
- CollaborateSelectionAwarenessDelegate,
290
- browser.SelectionBridge,
291
- core.Scheduler,
292
- core.Selection])
293
- ], exports.CollaborateCursor);
294
-
295
- function createUnknownComponent(factoryName, canInsertInlineComponent) {
296
- const unknownComponent = core.defineComponent({
297
- type: canInsertInlineComponent ? core.ContentType.InlineComponent : core.ContentType.BlockComponent,
298
- name: 'UnknownComponent',
299
- setup() {
300
- console.error(`cannot find component factory \`${factoryName}\`.`);
301
- return {
302
- render() {
303
- return core.VElement.createElement('textbus-unknown-component', {
304
- style: {
305
- display: canInsertInlineComponent ? 'inline' : 'block',
306
- color: '#f00'
307
- }
308
- }, unknownComponent.name);
309
- }
310
- };
311
- }
312
- });
313
- return unknownComponent;
314
- }
315
-
316
38
  const collaborateErrorFn = core.makeError('Collaborate');
317
39
  class ContentMap {
318
40
  constructor() {
@@ -353,10 +75,9 @@ class ContentMap {
353
75
  }
354
76
  }
355
77
  exports.Collaborate = class Collaborate {
356
- constructor(stackSize, rootComponentRef, collaborateCursor, controller, scheduler, factory, selection, starter) {
78
+ constructor(stackSize, rootComponentRef, controller, scheduler, factory, selection, starter) {
357
79
  this.stackSize = stackSize;
358
80
  this.rootComponentRef = rootComponentRef;
359
- this.collaborateCursor = collaborateCursor;
360
81
  this.controller = controller;
361
82
  this.scheduler = scheduler;
362
83
  this.factory = factory;
@@ -378,7 +99,6 @@ exports.Collaborate = class Collaborate {
378
99
  this.contentMap = new ContentMap();
379
100
  this.updateRemoteActions = [];
380
101
  this.noRecord = {};
381
- this.onSelectionChange = this.selectionChangeEvent.asObservable().pipe(stream.delay());
382
102
  this.onBack = this.backEvent.asObservable();
383
103
  this.onForward = this.forwardEvent.asObservable();
384
104
  this.onChange = this.changeEvent.asObservable();
@@ -457,9 +177,6 @@ exports.Collaborate = class Collaborate {
457
177
  }));
458
178
  this.syncRootComponent(root, rootComponent);
459
179
  }
460
- updateRemoteSelection(paths) {
461
- this.collaborateCursor.draw(paths);
462
- }
463
180
  back() {
464
181
  var _a;
465
182
  if (this.canBack) {
@@ -482,7 +199,6 @@ exports.Collaborate = class Collaborate {
482
199
  destroy() {
483
200
  var _a;
484
201
  this.subscriptions.forEach(i => i.unsubscribe());
485
- this.collaborateCursor.destroy();
486
202
  (_a = this.manager) === null || _a === void 0 ? void 0 : _a.destroy();
487
203
  }
488
204
  syncRootComponent(root, rootComponent) {
@@ -603,8 +319,7 @@ exports.Collaborate = class Collaborate {
603
319
  }
604
320
  else {
605
321
  const sharedComponent = action.insert;
606
- const canInsertInlineComponent = slot.schema.includes(core.ContentType.InlineComponent);
607
- const component = this.createComponentBySharedComponent(sharedComponent, canInsertInlineComponent);
322
+ const component = this.createComponentBySharedComponent(sharedComponent);
608
323
  this.syncComponentSlots(sharedComponent.get('slots'), component);
609
324
  this.syncComponentState(sharedComponent, component);
610
325
  slot.insert(component);
@@ -898,7 +613,7 @@ exports.Collaborate = class Collaborate {
898
613
  this.syncSlotState(sharedSlot, slot);
899
614
  return sharedSlot;
900
615
  }
901
- createComponentBySharedComponent(yMap, canInsertInlineComponent) {
616
+ createComponentBySharedComponent(yMap) {
902
617
  const sharedSlots = yMap.get('slots');
903
618
  const slots = [];
904
619
  sharedSlots.forEach(sharedSlot => {
@@ -923,7 +638,7 @@ exports.Collaborate = class Collaborate {
923
638
  });
924
639
  return instance;
925
640
  }
926
- return createUnknownComponent(name, canInsertInlineComponent).createInstance(this.starter);
641
+ throw collaborateErrorFn(`cannot find component factory \`${name}\`.`);
927
642
  }
928
643
  createSlotBySharedSlot(sharedSlot) {
929
644
  const content = sharedSlot.get('content');
@@ -950,8 +665,7 @@ exports.Collaborate = class Collaborate {
950
665
  }
951
666
  else {
952
667
  const sharedComponent = action.insert;
953
- const canInsertInlineComponent = slot.schema.includes(core.ContentType.InlineComponent);
954
- const component = this.createComponentBySharedComponent(sharedComponent, canInsertInlineComponent);
668
+ const component = this.createComponentBySharedComponent(sharedComponent);
955
669
  slot.insert(component, remoteFormatsToLocal(this.factory, action.attributes));
956
670
  this.syncComponentSlots(sharedComponent.get('slots'), component);
957
671
  this.syncComponentState(sharedComponent, component);
@@ -991,7 +705,6 @@ exports.Collaborate = __decorate([
991
705
  di.Injectable(),
992
706
  __param(0, di.Inject(core.HISTORY_STACK_SIZE)),
993
707
  __metadata("design:paramtypes", [Number, core.RootComponentRef,
994
- exports.CollaborateCursor,
995
708
  core.Controller,
996
709
  core.Scheduler,
997
710
  core.Factory,
@@ -1014,7 +727,6 @@ function remoteFormatsToLocal(factory, attrs) {
1014
727
  const collaborateModule = {
1015
728
  providers: [
1016
729
  exports.Collaborate,
1017
- exports.CollaborateCursor,
1018
730
  {
1019
731
  provide: core.History,
1020
732
  useClass: exports.Collaborate
@@ -1022,5 +734,4 @@ const collaborateModule = {
1022
734
  ]
1023
735
  };
1024
736
 
1025
- exports.CollaborateSelectionAwarenessDelegate = CollaborateSelectionAwarenessDelegate;
1026
737
  exports.collaborateModule = collaborateModule;
@@ -1,4 +1,3 @@
1
1
  import { Module } from '@textbus/core';
2
2
  export * from './collaborate';
3
- export * from './collaborate-cursor';
4
3
  export declare const collaborateModule: Module;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@textbus/collaborate",
3
- "version": "3.0.0-alpha.18",
3
+ "version": "3.0.0-alpha.20",
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,7 @@
27
27
  "dependencies": {
28
28
  "@tanbo/di": "^1.1.3",
29
29
  "@tanbo/stream": "^1.1.8",
30
- "@textbus/browser": "^3.0.0-alpha.18",
31
- "@textbus/core": "^3.0.0-alpha.18",
30
+ "@textbus/core": "^3.0.0-alpha.20",
32
31
  "reflect-metadata": "^0.1.13",
33
32
  "y-protocols": "^1.0.5",
34
33
  "yjs": "^13.5.39"
@@ -36,6 +35,7 @@
36
35
  "devDependencies": {
37
36
  "@rollup/plugin-commonjs": "^23.0.2",
38
37
  "@rollup/plugin-typescript": "^9.0.2",
38
+ "rimraf": "^3.0.2",
39
39
  "rollup": "^3.2.5"
40
40
  },
41
41
  "author": {
@@ -49,5 +49,5 @@
49
49
  "bugs": {
50
50
  "url": "https://github.com/textbus/textbus.git/issues"
51
51
  },
52
- "gitHead": "ad67f6d53c60b69f39cb8671be1d81aff7554058"
52
+ "gitHead": "3a7c389012d8a9a71584435100467b311105a0f7"
53
53
  }
@@ -1,42 +0,0 @@
1
- import { SelectionBridge } from '@textbus/browser';
2
- import { Selection, SelectionPaths, AbstractSelection, Scheduler, Rect } from '@textbus/core';
3
- export interface RemoteSelection {
4
- id: string;
5
- color: string;
6
- username: string;
7
- paths: SelectionPaths;
8
- }
9
- export interface SelectionRect extends Rect {
10
- color: string;
11
- username: string;
12
- id: string;
13
- }
14
- export interface RemoteSelectionCursor {
15
- cursor: HTMLElement;
16
- anchor: HTMLElement;
17
- userTip: HTMLElement;
18
- }
19
- export declare abstract class CollaborateSelectionAwarenessDelegate {
20
- abstract getRects(abstractSelection: AbstractSelection, nativeRange: Range): false | Rect[];
21
- }
22
- export declare class CollaborateCursor {
23
- private container;
24
- private awarenessDelegate;
25
- private nativeSelection;
26
- private scheduler;
27
- private selection;
28
- private host;
29
- private canvasContainer;
30
- private canvas;
31
- private context;
32
- private tooltips;
33
- private onRectsChange;
34
- private subscription;
35
- private currentSelection;
36
- constructor(container: HTMLElement, awarenessDelegate: CollaborateSelectionAwarenessDelegate, nativeSelection: SelectionBridge, scheduler: Scheduler, selection: Selection);
37
- refresh(): void;
38
- destroy(): void;
39
- draw(paths: RemoteSelection[]): void;
40
- protected drawUserCursor(rects: SelectionRect[]): void;
41
- private getUserCursor;
42
- }
@@ -1 +0,0 @@
1
- export declare function createUnknownComponent(factoryName: string, canInsertInlineComponent: boolean): any;