@textbus/collaborate 2.0.0-alpha.44 → 2.0.0-alpha.48
Sign up to get free protection for your applications and to get access to all the features.
- package/bundles/collab/collaborate-cursor.d.ts +1 -0
- package/bundles/collab/collaborate-cursor.js +6 -6
- package/bundles/collab/collaborate-cursor.js.map +1 -1
- package/bundles/collab/remote-to-local.d.ts +6 -4
- package/bundles/collab/remote-to-local.js +31 -3
- package/bundles/collab/remote-to-local.js.map +1 -1
- package/bundles/collaborate.js +6 -4
- package/bundles/collaborate.js.map +1 -1
- package/package.json +4 -4
- package/src/collab/collaborate-cursor.ts +8 -7
- package/src/collab/remote-to-local.ts +33 -5
- package/src/collaborate.ts +6 -4
@@ -143,7 +143,7 @@ let CollaborateCursor = class CollaborateCursor {
|
|
143
143
|
});
|
144
144
|
}
|
145
145
|
}
|
146
|
-
const info = Object.assign(Object.assign({}, item), { rects: selectionRects });
|
146
|
+
const info = Object.assign(Object.assign({}, item), { rects: selectionRects, focusEnd: item.paths.focusEnd });
|
147
147
|
this.onRectsChange.next(info);
|
148
148
|
users.push(info);
|
149
149
|
}
|
@@ -154,17 +154,17 @@ let CollaborateCursor = class CollaborateCursor {
|
|
154
154
|
drawUserCursor(users) {
|
155
155
|
for (let i = 0; i < users.length; i++) {
|
156
156
|
const user = users[i];
|
157
|
-
const
|
157
|
+
const child = user.rects[user.focusEnd ? user.rects.length - 1 : 0];
|
158
158
|
const { cursor, userTip, anchor } = this.getUserCursor(i);
|
159
|
-
if (!
|
159
|
+
if (!child) {
|
160
160
|
cursor.style.display = 'none';
|
161
161
|
}
|
162
162
|
else {
|
163
163
|
Object.assign(cursor.style, {
|
164
|
-
left:
|
165
|
-
top:
|
164
|
+
left: child.x + (user.focusEnd ? child.width : 0) + 'px',
|
165
|
+
top: child.y + 'px',
|
166
166
|
width: '2px',
|
167
|
-
height:
|
167
|
+
height: child.height + 'px',
|
168
168
|
background: user.color,
|
169
169
|
display: 'block'
|
170
170
|
});
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"collaborate-cursor.js","sourceRoot":"","sources":["../../src/collab/collaborate-cursor.ts"],"names":[],"mappings":"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","sourcesContent":["import { Inject, Injectable } from '@tanbo/di'\nimport { createElement, EDITABLE_DOCUMENT, EDITOR_CONTAINER, SelectionBridge } from '@textbus/browser'\nimport { Selection, SelectionPaths } from '@textbus/core'\nimport { Subject } from '@tanbo/stream'\n\nexport interface RemoteSelection {\n color: string\n username: string\n paths: SelectionPaths\n}\n\nexport interface SelectionRect {\n x: number\n y: number\n width: number\n height: number\n}\n\nexport interface SelectionInfo {\n color: string\n username: string\n rects: SelectionRect[]\n}\n\nexport interface RemoteSelectionCursor {\n cursor: HTMLElement\n anchor: HTMLElement\n userTip: HTMLElement\n}\n\n@Injectable()\nexport class CollaborateCursor {\n private canvas = createElement('canvas', {\n styles: {\n position: 'absolute',\n opacity: 0.5,\n left: 0,\n top: 0,\n width: '100%',\n height: '100%',\n pointerEvents: 'none'\n }\n }) as HTMLCanvasElement\n private context = this.canvas.getContext('2d')!\n private tooltips = createElement('div', {\n styles: {\n position: 'absolute',\n left: 0,\n top: 0,\n width: '100%',\n height: '100%',\n pointerEvents: 'none',\n fontSize: '12px'\n }\n })\n\n private onRectsChange = new Subject<SelectionInfo>()\n\n constructor(@Inject(EDITOR_CONTAINER) private container: HTMLElement,\n @Inject(EDITABLE_DOCUMENT) private document: Document,\n private nativeSelection: SelectionBridge,\n private selection: Selection) {\n container.appendChild(this.canvas)\n container.appendChild(this.tooltips)\n this.onRectsChange.subscribe(info => {\n const color = info.color\n const rects = info.rects\n for (const rect of rects) {\n this.context.fillStyle = color\n this.context.beginPath()\n this.context.rect(rect.x, rect.y, rect.width, rect.height)\n this.context.fill()\n this.context.closePath()\n }\n })\n }\n\n draw(paths: RemoteSelection[]) {\n this.canvas.width = this.container.offsetWidth\n this.canvas.height = this.container.offsetHeight\n this.context.clearRect(0, 0, this.canvas.width, this.canvas.height)\n\n const users: SelectionInfo[] = []\n\n paths.filter(i => {\n return i.paths.start.length && i.paths.end.length\n }).forEach(item => {\n const startOffset = item.paths.start.pop()!\n const startSlot = this.selection.findSlotByPaths(item.paths.start)\n const endOffset = item.paths.end.pop()!\n const endSlot = this.selection.findSlotByPaths(item.paths.end)\n\n if (startSlot && endSlot) {\n const position = this.nativeSelection.getPositionByRange({\n startOffset,\n endOffset,\n startSlot,\n endSlot\n })\n if (position.start && position.end) {\n const nativeRange = this.document.createRange()\n nativeRange.setStart(position.start.node, position.start.offset)\n nativeRange.setEnd(position.end.node, position.end.offset)\n\n const rects = nativeRange.getClientRects()\n const selectionRects: SelectionRect[] = []\n for (let i = rects.length - 1; i >= 0; i--) {\n const rect = rects[i]\n selectionRects.push({\n x: rect.x,\n y: rect.y,\n width: rect.width,\n height: rect.height,\n })\n }\n\n if (rects.length === 0) {\n const rect = nativeRange.getBoundingClientRect()\n if (rect.x !== 0 || rect.y !== 0 || rect.width !== 0 || rect.height !== 0) {\n selectionRects.push({\n x: rect.x,\n y: rect.y,\n width: 1,\n height: rect.height,\n })\n }\n }\n const info: SelectionInfo = {\n ...item,\n rects: selectionRects\n }\n this.onRectsChange.next(info)\n\n users.push(info)\n }\n }\n })\n this.drawUserCursor(users)\n }\n\n private drawUserCursor(users: SelectionInfo[]) {\n for (let i = 0; i < users.length; i++) {\n const user = users[i]\n const last = user.rects[user.rects.length - 1]\n\n const {cursor, userTip, anchor} = this.getUserCursor(i)\n if (!last) {\n cursor.style.display = 'none'\n } else {\n Object.assign(cursor.style, {\n left: last.x + last.width + 'px',\n top: last.y + 'px',\n width: '2px',\n height: last.height + 'px',\n background: user.color,\n display: 'block'\n })\n anchor.style.background = user.color\n userTip.innerText = user.username\n userTip.style.background = user.color\n }\n }\n\n for (let i = users.length; i < this.tooltips.children.length; i++) {\n this.tooltips.removeChild(this.tooltips.children[i])\n }\n }\n\n private getUserCursor(index: number): RemoteSelectionCursor {\n let child: HTMLElement = this.tooltips.children[index] as HTMLElement\n if (child) {\n const anchor = child.children[0] as HTMLElement\n return {\n cursor: child,\n anchor,\n userTip: anchor.children[0] as HTMLElement\n }\n }\n const userTip = createElement('span', {\n styles: {\n position: 'absolute',\n display: 'none',\n left: '50%',\n transform: 'translateX(-50%)',\n marginBottom: '2px',\n bottom: '100%',\n whiteSpace: 'nowrap',\n color: '#fff',\n boxShadow: '0 1px 2px rgba(0,0,0,.1)',\n borderRadius: '3px',\n padding: '3px 5px',\n pointerEvents: 'none',\n }\n })\n\n const anchor = createElement('span', {\n styles: {\n position: 'absolute',\n top: '-2px',\n left: '-2px',\n width: '6px',\n height: '6px',\n pointerEvents: 'auto',\n pointer: 'cursor',\n },\n children: [userTip],\n on: {\n mouseenter() {\n anchor.style.transform = 'scale(1.2)'\n userTip.style.display = 'block'\n },\n mouseleave() {\n userTip.style.display = 'none'\n anchor.style.transform = ''\n }\n }\n })\n child = createElement('span', {\n styles: {\n position: 'absolute',\n },\n children: [\n anchor\n ]\n })\n this.tooltips.append(child)\n return {\n cursor: child,\n anchor,\n userTip\n }\n }\n}\n"]}
|
1
|
+
{"version":3,"file":"collaborate-cursor.js","sourceRoot":"","sources":["../../src/collab/collaborate-cursor.ts"],"names":[],"mappings":"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","sourcesContent":["import { Inject, Injectable } from '@tanbo/di'\nimport { createElement, EDITABLE_DOCUMENT, EDITOR_CONTAINER, SelectionBridge } from '@textbus/browser'\nimport { Selection, SelectionPaths } from '@textbus/core'\nimport { Subject } from '@tanbo/stream'\n\nexport interface RemoteSelection {\n color: string\n username: string\n paths: SelectionPaths\n}\n\nexport interface SelectionRect {\n x: number\n y: number\n width: number\n height: number\n}\n\nexport interface SelectionInfo {\n color: string\n username: string\n rects: SelectionRect[]\n focusEnd: boolean\n}\n\nexport interface RemoteSelectionCursor {\n cursor: HTMLElement\n anchor: HTMLElement\n userTip: HTMLElement\n}\n\n@Injectable()\nexport class CollaborateCursor {\n private canvas = createElement('canvas', {\n styles: {\n position: 'absolute',\n opacity: 0.5,\n left: 0,\n top: 0,\n width: '100%',\n height: '100%',\n pointerEvents: 'none'\n }\n }) as HTMLCanvasElement\n private context = this.canvas.getContext('2d')!\n private tooltips = createElement('div', {\n styles: {\n position: 'absolute',\n left: 0,\n top: 0,\n width: '100%',\n height: '100%',\n pointerEvents: 'none',\n fontSize: '12px'\n }\n })\n\n private onRectsChange = new Subject<SelectionInfo>()\n\n constructor(@Inject(EDITOR_CONTAINER) private container: HTMLElement,\n @Inject(EDITABLE_DOCUMENT) private document: Document,\n private nativeSelection: SelectionBridge,\n private selection: Selection) {\n container.appendChild(this.canvas)\n container.appendChild(this.tooltips)\n this.onRectsChange.subscribe(info => {\n const color = info.color\n const rects = info.rects\n for (const rect of rects) {\n this.context.fillStyle = color\n this.context.beginPath()\n this.context.rect(rect.x, rect.y, rect.width, rect.height)\n this.context.fill()\n this.context.closePath()\n }\n })\n }\n\n draw(paths: RemoteSelection[]) {\n this.canvas.width = this.container.offsetWidth\n this.canvas.height = this.container.offsetHeight\n this.context.clearRect(0, 0, this.canvas.width, this.canvas.height)\n\n const users: SelectionInfo[] = []\n\n paths.filter(i => {\n return i.paths.start.length && i.paths.end.length\n }).forEach(item => {\n const startOffset = item.paths.start.pop()!\n const startSlot = this.selection.findSlotByPaths(item.paths.start)\n const endOffset = item.paths.end.pop()!\n const endSlot = this.selection.findSlotByPaths(item.paths.end)\n\n if (startSlot && endSlot) {\n const position = this.nativeSelection.getPositionByRange({\n startOffset,\n endOffset,\n startSlot,\n endSlot\n })\n if (position.start && position.end) {\n const nativeRange = this.document.createRange()\n nativeRange.setStart(position.start.node, position.start.offset)\n nativeRange.setEnd(position.end.node, position.end.offset)\n\n const rects = nativeRange.getClientRects()\n const selectionRects: SelectionRect[] = []\n for (let i = rects.length - 1; i >= 0; i--) {\n const rect = rects[i]\n selectionRects.push({\n x: rect.x,\n y: rect.y,\n width: rect.width,\n height: rect.height,\n })\n }\n\n if (rects.length === 0) {\n const rect = nativeRange.getBoundingClientRect()\n if (rect.x !== 0 || rect.y !== 0 || rect.width !== 0 || rect.height !== 0) {\n selectionRects.push({\n x: rect.x,\n y: rect.y,\n width: 1,\n height: rect.height,\n })\n }\n }\n const info: SelectionInfo = {\n ...item,\n rects: selectionRects,\n focusEnd: item.paths.focusEnd\n }\n this.onRectsChange.next(info)\n\n users.push(info)\n }\n }\n })\n this.drawUserCursor(users)\n }\n\n private drawUserCursor(users: SelectionInfo[]) {\n for (let i = 0; i < users.length; i++) {\n const user = users[i]\n const child = user.rects[user.focusEnd ? user.rects.length - 1 : 0]\n const {cursor, userTip, anchor} = this.getUserCursor(i)\n if (!child) {\n cursor.style.display = 'none'\n } else {\n Object.assign(cursor.style, {\n left: child.x + (user.focusEnd ? child.width : 0) + 'px',\n top: child.y + 'px',\n width: '2px',\n height: child.height + 'px',\n background: user.color,\n display: 'block'\n })\n anchor.style.background = user.color\n userTip.innerText = user.username\n userTip.style.background = user.color\n }\n }\n\n for (let i = users.length; i < this.tooltips.children.length; i++) {\n this.tooltips.removeChild(this.tooltips.children[i])\n }\n }\n\n private getUserCursor(index: number): RemoteSelectionCursor {\n let child: HTMLElement = this.tooltips.children[index] as HTMLElement\n if (child) {\n const anchor = child.children[0] as HTMLElement\n return {\n cursor: child,\n anchor,\n userTip: anchor.children[0] as HTMLElement\n }\n }\n const userTip = createElement('span', {\n styles: {\n position: 'absolute',\n display: 'none',\n left: '50%',\n transform: 'translateX(-50%)',\n marginBottom: '2px',\n bottom: '100%',\n whiteSpace: 'nowrap',\n color: '#fff',\n boxShadow: '0 1px 2px rgba(0,0,0,.1)',\n borderRadius: '3px',\n padding: '3px 5px',\n pointerEvents: 'none',\n }\n })\n\n const anchor = createElement('span', {\n styles: {\n position: 'absolute',\n top: '-2px',\n left: '-2px',\n width: '6px',\n height: '6px',\n pointerEvents: 'auto',\n pointer: 'cursor',\n },\n children: [userTip],\n on: {\n mouseenter() {\n anchor.style.transform = 'scale(1.2)'\n userTip.style.display = 'block'\n },\n mouseleave() {\n userTip.style.display = 'none'\n anchor.style.transform = ''\n }\n }\n })\n child = createElement('span', {\n styles: {\n position: 'absolute',\n },\n children: [\n anchor\n ]\n })\n this.tooltips.append(child)\n return {\n cursor: child,\n anchor,\n userTip\n }\n }\n}\n"]}
|
@@ -1,10 +1,12 @@
|
|
1
|
-
import { YEvent } from 'yjs';
|
2
|
-
import { Registry,
|
1
|
+
import { Doc as YDoc, YEvent } from 'yjs';
|
2
|
+
import { ComponentInstance, Registry, Selection, Translator } from '@textbus/core';
|
3
3
|
export declare class RemoteToLocal {
|
4
|
+
private yDoc;
|
4
5
|
private translator;
|
6
|
+
private selection;
|
5
7
|
private registry;
|
6
|
-
constructor(translator: Translator, registry: Registry);
|
7
|
-
transform(events: YEvent[],
|
8
|
+
constructor(yDoc: YDoc, translator: Translator, selection: Selection, registry: Registry);
|
9
|
+
transform(events: YEvent[], rootComponent: ComponentInstance): void;
|
8
10
|
private applySharedComponentToComponent;
|
9
11
|
private applySharedSlotToSlot;
|
10
12
|
private createComponentBySharedComponent;
|
@@ -1,14 +1,26 @@
|
|
1
|
-
import { YArrayEvent, YMapEvent, YTextEvent } from 'yjs';
|
1
|
+
import { YArrayEvent, YMapEvent, YTextEvent, } from 'yjs';
|
2
2
|
import { makeError } from '@textbus/core';
|
3
3
|
const collaborateErrorFn = makeError('Collaborate');
|
4
4
|
export class RemoteToLocal {
|
5
|
-
constructor(translator, registry) {
|
5
|
+
constructor(yDoc, translator, selection, registry) {
|
6
|
+
Object.defineProperty(this, "yDoc", {
|
7
|
+
enumerable: true,
|
8
|
+
configurable: true,
|
9
|
+
writable: true,
|
10
|
+
value: yDoc
|
11
|
+
});
|
6
12
|
Object.defineProperty(this, "translator", {
|
7
13
|
enumerable: true,
|
8
14
|
configurable: true,
|
9
15
|
writable: true,
|
10
16
|
value: translator
|
11
17
|
});
|
18
|
+
Object.defineProperty(this, "selection", {
|
19
|
+
enumerable: true,
|
20
|
+
configurable: true,
|
21
|
+
writable: true,
|
22
|
+
value: selection
|
23
|
+
});
|
12
24
|
Object.defineProperty(this, "registry", {
|
13
25
|
enumerable: true,
|
14
26
|
configurable: true,
|
@@ -16,12 +28,16 @@ export class RemoteToLocal {
|
|
16
28
|
value: registry
|
17
29
|
});
|
18
30
|
}
|
19
|
-
transform(events,
|
31
|
+
transform(events, rootComponent) {
|
20
32
|
events.forEach(ev => {
|
21
33
|
const path = [];
|
22
34
|
for (let i = 0; i < ev.path.length; i += 2) {
|
23
35
|
path.push(ev.path.slice(i, i + 2));
|
24
36
|
}
|
37
|
+
const slot = rootComponent.slots.get(0);
|
38
|
+
if (!slot) {
|
39
|
+
throw collaborateErrorFn('cannot find child slot in root component!');
|
40
|
+
}
|
25
41
|
if (path.length) {
|
26
42
|
const componentIndex = path.shift()[0];
|
27
43
|
const component = slot.getContentAtIndex(componentIndex);
|
@@ -84,6 +100,7 @@ export class RemoteToLocal {
|
|
84
100
|
}
|
85
101
|
if (ev instanceof YTextEvent) {
|
86
102
|
slot.retain(0);
|
103
|
+
let offset = 0;
|
87
104
|
ev.delta.forEach(action => {
|
88
105
|
if (Reflect.has(action, 'retain')) {
|
89
106
|
if (action.attributes) {
|
@@ -98,15 +115,18 @@ export class RemoteToLocal {
|
|
98
115
|
slot.insert(action.insert, action.attributes ? Object.keys(action.attributes).map(key => {
|
99
116
|
return [this.registry.getFormatter(key), action.attributes[key]];
|
100
117
|
}) : []);
|
118
|
+
offset += action.insert.length;
|
101
119
|
}
|
102
120
|
else {
|
103
121
|
const component = this.createComponentBySharedComponent(action.insert);
|
104
122
|
slot.insert(component);
|
123
|
+
offset += 1;
|
105
124
|
}
|
106
125
|
}
|
107
126
|
else if (action.delete) {
|
108
127
|
slot.retain(slot.index);
|
109
128
|
slot.delete(action.delete);
|
129
|
+
offset -= action.delete;
|
110
130
|
}
|
111
131
|
else if (action.attributes) {
|
112
132
|
slot.updateState(draft => {
|
@@ -114,6 +134,14 @@ export class RemoteToLocal {
|
|
114
134
|
});
|
115
135
|
}
|
116
136
|
});
|
137
|
+
if (this.selection.isSelected) {
|
138
|
+
if (slot === this.selection.startSlot) {
|
139
|
+
this.selection.setStart(slot, this.selection.startOffset + offset);
|
140
|
+
}
|
141
|
+
if (slot === this.selection.endSlot) {
|
142
|
+
this.selection.setEnd(slot, this.selection.endOffset + offset);
|
143
|
+
}
|
144
|
+
}
|
117
145
|
}
|
118
146
|
else if (ev instanceof YMapEvent) {
|
119
147
|
ev.keysChanged.forEach(key => {
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"remote-to-local.js","sourceRoot":"","sources":["../../src/collab/remote-to-local.ts"],"names":[],"mappings":"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","sourcesContent":["import { Map as YMap, YArrayEvent, YEvent, YMapEvent, Text as YText, YTextEvent, Array as YArray } from 'yjs'\nimport { ComponentInstance, ComponentLiteral, makeError, Registry, Slot, Translator } from '@textbus/core'\n\ntype YPath = [number, string][]\nconst collaborateErrorFn = makeError('Collaborate')\n\nexport class RemoteToLocal {\n constructor(private translator: Translator,\n private registry: Registry) {\n }\n\n transform(events: YEvent[], slot: Slot) {\n events.forEach(ev => {\n const path: YPath = []\n\n for (let i = 0; i < ev.path.length; i += 2) {\n path.push(ev.path.slice(i, i + 2) as [number, string])\n }\n\n if (path.length) {\n const componentIndex = path.shift()![0] as number\n const component = slot.getContentAtIndex(componentIndex) as ComponentInstance\n this.applySharedComponentToComponent(ev, path, component)\n return\n }\n\n this.applySharedSlotToSlot(ev, path, slot)\n })\n }\n\n private applySharedComponentToComponent(ev: YEvent, path: YPath, component: ComponentInstance) {\n if (path.length) {\n const childPath = path.shift()!\n const slot = component.slots.get(childPath[0])!\n this.applySharedSlotToSlot(ev, path, slot)\n return\n }\n if (ev instanceof YMapEvent) {\n ev.keysChanged.forEach(key => {\n if (key === 'state') {\n const state = (ev.target as YMap<any>).get('state')\n component.updateState(draft => {\n Object.assign(draft, state)\n })\n }\n })\n } else if (ev instanceof YArrayEvent) {\n const slots = component.slots\n ev.delta.forEach(action => {\n if (Reflect.has(action, 'retain')) {\n slots.retain(action.retain!)\n } else if (action.insert) {\n (action.insert as Array<YMap<any>>).forEach(item => {\n slots.insert(this.createSlotBySharedSlot(item))\n })\n } else if (action.delete) {\n slots.retain(slots.index)\n slots.delete(action.delete)\n }\n })\n }\n }\n\n private applySharedSlotToSlot(ev: YEvent, path: YPath, slot: Slot) {\n if (path.length) {\n path.shift()\n const delta = (ev.target.parent as YText).toDelta()\n let componentIndex = 0\n for (let i = 0; i < delta.length; i++) {\n const action = delta[i]\n if (action.insert === ev.target) {\n break\n }\n componentIndex += typeof action.insert === 'string' ? action.insert.length : 1\n }\n const component = slot.getContentAtIndex(componentIndex) as ComponentInstance\n this.applySharedComponentToComponent(ev, path, component)\n return\n }\n\n if (ev instanceof YTextEvent) {\n slot.retain(0)\n ev.delta.forEach(action => {\n if (Reflect.has(action, 'retain')) {\n if (action.attributes) {\n slot.retain(action.retain!, Object.keys(action.attributes).map(key => {\n return [this.registry.getFormatter(key)!, action.attributes![key]]\n }))\n }\n slot.retain(action.retain!)\n } else if (action.insert) {\n if (typeof action.insert === 'string') {\n slot.insert(action.insert, action.attributes ? Object.keys(action.attributes).map(key => {\n return [this.registry.getFormatter(key)!, action.attributes![key]]\n }) : [])\n } else {\n const component = this.createComponentBySharedComponent(action.insert as YMap<any>)\n slot.insert(component)\n }\n } else if (action.delete) {\n slot.retain(slot.index)\n slot.delete(action.delete)\n } else if (action.attributes) {\n slot.updateState(draft => {\n Object.assign(draft, action.attributes)\n })\n }\n })\n } else if (ev instanceof YMapEvent) {\n ev.keysChanged.forEach(key => {\n if (key === 'state') {\n const state = (ev.target as YMap<any>).get('state')\n slot.updateState(draft => {\n Object.assign(draft, state)\n })\n }\n })\n }\n }\n\n private createComponentBySharedComponent(yMap: YMap<any>): ComponentInstance {\n const slots = yMap.get('slots') as YArray<YMap<any>>\n const componentLiteral: ComponentLiteral = {\n state: yMap.get('state'),\n name: yMap.get('name'),\n slots: slots.map(sharedSlot => {\n return this.createSlotBySharedSlot(sharedSlot).toJSON()\n })\n }\n return this.translator.createComponent(componentLiteral)!\n }\n\n private createSlotBySharedSlot(sharedSlot: YMap<any>): Slot {\n const content = sharedSlot.get('content') as YText\n const delta = content.toDelta()\n\n const slot = this.translator.createSlot({\n schema: sharedSlot.get('schema'),\n state: sharedSlot.get('state'),\n formats: {},\n content: []\n })\n\n for (const action of delta) {\n if (action.insert) {\n if (typeof action.insert === 'string') {\n slot.insert(action.insert, action.attributes ? Object.keys(action.attributes).map(key => {\n return [this.registry.getFormatter(key)!, action.attributes![key]]\n }) : [])\n } else {\n slot.insert(this.createComponentBySharedComponent(action.insert))\n }\n } else {\n throw collaborateErrorFn('Unexpected delta action.')\n }\n }\n return slot\n }\n}\n"]}
|
1
|
+
{"version":3,"file":"remote-to-local.js","sourceRoot":"","sources":["../../src/collab/remote-to-local.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Doc as YDoc,\n Map as YMap,\n YArrayEvent,\n YEvent,\n YMapEvent,\n Text as YText,\n YTextEvent,\n Array as YArray,\n} from 'yjs'\nimport { ComponentInstance, ComponentLiteral, makeError, Registry, Selection, Slot, Translator } from '@textbus/core'\n\ntype YPath = [number, string][]\nconst collaborateErrorFn = makeError('Collaborate')\n\nexport class RemoteToLocal {\n constructor(private yDoc: YDoc,\n private translator: Translator,\n private selection: Selection,\n private registry: Registry) {\n }\n\n transform(events: YEvent[], rootComponent: ComponentInstance) {\n events.forEach(ev => {\n const path: YPath = []\n\n for (let i = 0; i < ev.path.length; i += 2) {\n path.push(ev.path.slice(i, i + 2) as [number, string])\n }\n\n const slot = rootComponent.slots.get(0)\n\n if (!slot) {\n throw collaborateErrorFn('cannot find child slot in root component!')\n }\n\n if (path.length) {\n const componentIndex = path.shift()![0] as number\n const component = slot.getContentAtIndex(componentIndex) as ComponentInstance\n this.applySharedComponentToComponent(ev, path, component)\n return\n }\n\n this.applySharedSlotToSlot(ev, path, slot)\n })\n }\n\n private applySharedComponentToComponent(ev: YEvent, path: YPath, component: ComponentInstance) {\n if (path.length) {\n const childPath = path.shift()!\n const slot = component.slots.get(childPath[0])!\n this.applySharedSlotToSlot(ev, path, slot)\n return\n }\n if (ev instanceof YMapEvent) {\n ev.keysChanged.forEach(key => {\n if (key === 'state') {\n const state = (ev.target as YMap<any>).get('state')\n component.updateState(draft => {\n Object.assign(draft, state)\n })\n }\n })\n } else if (ev instanceof YArrayEvent) {\n const slots = component.slots\n ev.delta.forEach(action => {\n if (Reflect.has(action, 'retain')) {\n slots.retain(action.retain!)\n } else if (action.insert) {\n (action.insert as Array<YMap<any>>).forEach(item => {\n slots.insert(this.createSlotBySharedSlot(item))\n })\n } else if (action.delete) {\n slots.retain(slots.index)\n slots.delete(action.delete)\n }\n })\n }\n }\n\n private applySharedSlotToSlot(ev: YEvent, path: YPath, slot: Slot) {\n if (path.length) {\n path.shift()\n const delta = (ev.target.parent as YText).toDelta()\n let componentIndex = 0\n for (let i = 0; i < delta.length; i++) {\n const action = delta[i]\n if (action.insert === ev.target) {\n break\n }\n componentIndex += typeof action.insert === 'string' ? action.insert.length : 1\n }\n const component = slot.getContentAtIndex(componentIndex) as ComponentInstance\n this.applySharedComponentToComponent(ev, path, component)\n return\n }\n if (ev instanceof YTextEvent) {\n slot.retain(0)\n let offset = 0\n ev.delta.forEach(action => {\n if (Reflect.has(action, 'retain')) {\n if (action.attributes) {\n slot.retain(action.retain!, Object.keys(action.attributes).map(key => {\n return [this.registry.getFormatter(key)!, action.attributes![key]]\n }))\n }\n slot.retain(action.retain!)\n } else if (action.insert) {\n if (typeof action.insert === 'string') {\n slot.insert(action.insert, action.attributes ? Object.keys(action.attributes).map(key => {\n return [this.registry.getFormatter(key)!, action.attributes![key]]\n }) : [])\n offset += action.insert.length\n } else {\n const component = this.createComponentBySharedComponent(action.insert as YMap<any>)\n slot.insert(component)\n offset += 1\n }\n } else if (action.delete) {\n slot.retain(slot.index)\n slot.delete(action.delete)\n offset -= action.delete\n } else if (action.attributes) {\n slot.updateState(draft => {\n Object.assign(draft, action.attributes)\n })\n }\n })\n if (this.selection.isSelected) {\n if (slot === this.selection.startSlot) {\n this.selection.setStart(slot, this.selection.startOffset! + offset)\n }\n if (slot === this.selection.endSlot) {\n this.selection.setEnd(slot, this.selection.endOffset! + offset)\n }\n }\n } else if (ev instanceof YMapEvent) {\n ev.keysChanged.forEach(key => {\n if (key === 'state') {\n const state = (ev.target as YMap<any>).get('state')\n slot.updateState(draft => {\n Object.assign(draft, state)\n })\n }\n })\n }\n }\n\n private createComponentBySharedComponent(yMap: YMap<any>): ComponentInstance {\n const slots = yMap.get('slots') as YArray<YMap<any>>\n const componentLiteral: ComponentLiteral = {\n state: yMap.get('state'),\n name: yMap.get('name'),\n slots: slots.map(sharedSlot => {\n return this.createSlotBySharedSlot(sharedSlot).toJSON()\n })\n }\n return this.translator.createComponent(componentLiteral)!\n }\n\n private createSlotBySharedSlot(sharedSlot: YMap<any>): Slot {\n const content = sharedSlot.get('content') as YText\n const delta = content.toDelta()\n\n const slot = this.translator.createSlot({\n schema: sharedSlot.get('schema'),\n state: sharedSlot.get('state'),\n formats: {},\n content: []\n })\n\n for (const action of delta) {\n if (action.insert) {\n if (typeof action.insert === 'string') {\n slot.insert(action.insert, action.attributes ? Object.keys(action.attributes).map(key => {\n return [this.registry.getFormatter(key)!, action.attributes![key]]\n }) : [])\n } else {\n slot.insert(this.createComponentBySharedComponent(action.insert))\n }\n } else {\n throw collaborateErrorFn('Unexpected delta action.')\n }\n }\n return slot\n }\n}\n"]}
|
package/bundles/collaborate.js
CHANGED
@@ -104,7 +104,7 @@ let Collaborate = class Collaborate {
|
|
104
104
|
enumerable: true,
|
105
105
|
configurable: true,
|
106
106
|
writable: true,
|
107
|
-
value: new RemoteToLocal(this.translator, this.registry)
|
107
|
+
value: new RemoteToLocal(this.yDoc, this.translator, this.selection, this.registry)
|
108
108
|
});
|
109
109
|
Object.defineProperty(this, "backEvent", {
|
110
110
|
enumerable: true,
|
@@ -197,14 +197,16 @@ let Collaborate = class Collaborate {
|
|
197
197
|
}
|
198
198
|
listen2() {
|
199
199
|
const root = this.yDoc.getText('content');
|
200
|
-
const
|
201
|
-
this.manager = new UndoManager(root
|
200
|
+
const rootComponent = this.rootComponentRef.component;
|
201
|
+
this.manager = new UndoManager(root, {
|
202
|
+
trackedOrigins: new Set([this.yDoc])
|
203
|
+
});
|
202
204
|
root.observeDeep((events, transaction) => {
|
203
205
|
if (transaction.origin === this.yDoc) {
|
204
206
|
return;
|
205
207
|
}
|
206
208
|
this.updateFromSelf = false;
|
207
|
-
this.remoteToLocal.transform(events,
|
209
|
+
this.remoteToLocal.transform(events, rootComponent);
|
208
210
|
this.renderer.render();
|
209
211
|
this.selection.restore();
|
210
212
|
this.updateFromSelf = true;
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"collaborate.js","sourceRoot":"","sources":["../src/collaborate.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,EAAc,OAAO,EAAgB,GAAG,EAAE,MAAM,eAAe,CAAA;AAC5F,OAAO,EACL,gBAAgB,EAChB,OAAO,EAEP,UAAU,EACV,QAAQ,EACR,SAAS,EAEA,QAAQ,EAClB,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,GAAG,IAAI,IAAI,EAAE,WAAW,EAAE,MAAM,KAAK,CAAA;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AACxD,OAAO,EAAE,iBAAiB,EAAmB,MAAM,eAAe,CAAA;AAGlE,IAAa,WAAW,GAAxB,MAAa,WAAW;IA+BtB,YAAoB,gBAAkC,EAClC,iBAAoC,EACpC,UAAsB,EACtB,QAAkB,EAClB,QAAkB,EAClB,SAAoB,EACpB,OAAgB;;;;;mBANhB;;;;;;mBACA;;;;;;mBACA;;;;;;mBACA;;;;;;mBACA;;;;;;mBACA;;;;;;mBACA;;QApCpB;;;;;WAA6C;QAC7C;;;;mBAAO,IAAI,IAAI,EAAE;WAAA;QACjB;;;;;WAAwB;QACxB;;;;;WAA2B;QAC3B;;;;;WAAyB;QACzB;;;;;WAAwB;QAUxB;;;;mBAAwB,IAAI,aAAa,EAAE;WAAA;QAC3C;;;;mBAAwB,IAAI,aAAa,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC;WAAA;
|
1
|
+
{"version":3,"file":"collaborate.js","sourceRoot":"","sources":["../src/collaborate.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable } from '@tanbo/di'\nimport { debounceTime, filter, Observable, Subject, Subscription, tap } from '@tanbo/stream'\nimport {\n RootComponentRef,\n Starter,\n Operation,\n Translator,\n Registry,\n Selection,\n SelectionPaths,\n History, Renderer\n} from '@textbus/core'\nimport { Doc as YDoc, UndoManager } from 'yjs'\nimport { LocalToRemote } from './collab/local-to-remote'\nimport { RemoteToLocal } from './collab/remote-to-local'\nimport { CollaborateCursor, RemoteSelection } from './collab/_api'\n\n@Injectable()\nexport class Collaborate implements History {\n onSelectionChange: Observable<SelectionPaths>\n yDoc = new YDoc()\n onBack: Observable<void>\n onForward: Observable<void>\n onChange: Observable<any>\n onPush: Observable<void>\n\n get canBack() {\n return this.manager?.canUndo()\n }\n\n get canForward() {\n return this.manager?.canRedo()\n }\n\n private localToRemote = new LocalToRemote()\n private remoteToLocal = new RemoteToLocal(this.yDoc, this.translator, this.selection, this.registry)\n\n private backEvent = new Subject<void>()\n private forwardEvent = new Subject<void>()\n private changeEvent = new Subject<void>()\n private pushEvent = new Subject<void>()\n\n private manager!: UndoManager\n\n private subscriptions: Subscription[] = []\n private updateFromSelf = true\n\n private selectionChangeEvent = new Subject<SelectionPaths>()\n\n constructor(private rootComponentRef: RootComponentRef,\n private collaborateCursor: CollaborateCursor,\n private translator: Translator,\n private renderer: Renderer,\n private registry: Registry,\n private selection: Selection,\n private starter: Starter) {\n this.onSelectionChange = this.selectionChangeEvent.asObservable()\n this.onBack = this.backEvent.asObservable()\n this.onForward = this.forwardEvent.asObservable()\n this.onChange = this.changeEvent.asObservable()\n this.onPush = this.pushEvent.asObservable()\n }\n\n setup() {\n this.subscriptions.push(\n this.starter.onReady.subscribe(() => {\n this.listen2()\n }),\n this.selection.onChange.subscribe(() => {\n const paths = this.selection.getPaths()\n this.selectionChangeEvent.next(paths)\n })\n )\n }\n\n updateRemoteSelection(paths: RemoteSelection[]) {\n this.collaborateCursor.draw(paths)\n }\n\n listen() {\n //\n }\n\n back() {\n if (this.canBack) {\n this.manager.undo()\n }\n }\n\n forward() {\n if (this.canForward) {\n this.manager.redo()\n }\n }\n\n destroy() {\n this.subscriptions.forEach(i => i.unsubscribe())\n }\n\n private listen2() {\n const root = this.yDoc.getText('content')\n const rootComponent = this.rootComponentRef.component!\n this.manager = new UndoManager(root, {\n trackedOrigins: new Set<any>([this.yDoc])\n })\n root.observeDeep((events, transaction) => {\n if (transaction.origin === this.yDoc) {\n return\n }\n this.updateFromSelf = false\n\n this.remoteToLocal.transform(events, rootComponent)\n this.renderer.render()\n this.selection.restore()\n this.updateFromSelf = true\n })\n const operations: Operation[] = []\n this.subscriptions.push(\n this.rootComponentRef.component.changeMarker.onChange.pipe(\n filter(() => {\n return this.updateFromSelf\n }),\n tap(op => {\n operations.push(op)\n }),\n debounceTime(1)\n ).subscribe(() => {\n this.yDoc.transact(() => {\n operations.forEach(operation => {\n this.localToRemote.transform(operation, root)\n })\n operations.length = 0\n }, this.yDoc)\n this.renderer.render()\n this.selection.restore()\n })\n )\n }\n}\n"]}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@textbus/collaborate",
|
3
|
-
"version": "2.0.0-alpha.
|
3
|
+
"version": "2.0.0-alpha.48",
|
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/public-api.js",
|
6
6
|
"module": "./bundles/public-api.js",
|
@@ -27,8 +27,8 @@
|
|
27
27
|
"dependencies": {
|
28
28
|
"@tanbo/di": "^1.0.5",
|
29
29
|
"@tanbo/stream": "^0.0.12",
|
30
|
-
"@textbus/browser": "^2.0.0-alpha.
|
31
|
-
"@textbus/core": "^2.0.0-alpha.
|
30
|
+
"@textbus/browser": "^2.0.0-alpha.48",
|
31
|
+
"@textbus/core": "^2.0.0-alpha.48",
|
32
32
|
"reflect-metadata": "^0.1.13",
|
33
33
|
"y-protocols": "^1.0.5",
|
34
34
|
"yjs": "^13.5.27"
|
@@ -44,5 +44,5 @@
|
|
44
44
|
"bugs": {
|
45
45
|
"url": "https://github.com/textbus/textbus.git/issues"
|
46
46
|
},
|
47
|
-
"gitHead": "
|
47
|
+
"gitHead": "e9dae4b766b8ead398406487ae7e587cca8164ab"
|
48
48
|
}
|
@@ -20,6 +20,7 @@ export interface SelectionInfo {
|
|
20
20
|
color: string
|
21
21
|
username: string
|
22
22
|
rects: SelectionRect[]
|
23
|
+
focusEnd: boolean
|
23
24
|
}
|
24
25
|
|
25
26
|
export interface RemoteSelectionCursor {
|
@@ -127,7 +128,8 @@ export class CollaborateCursor {
|
|
127
128
|
}
|
128
129
|
const info: SelectionInfo = {
|
129
130
|
...item,
|
130
|
-
rects: selectionRects
|
131
|
+
rects: selectionRects,
|
132
|
+
focusEnd: item.paths.focusEnd
|
131
133
|
}
|
132
134
|
this.onRectsChange.next(info)
|
133
135
|
|
@@ -141,17 +143,16 @@ export class CollaborateCursor {
|
|
141
143
|
private drawUserCursor(users: SelectionInfo[]) {
|
142
144
|
for (let i = 0; i < users.length; i++) {
|
143
145
|
const user = users[i]
|
144
|
-
const
|
145
|
-
|
146
|
+
const child = user.rects[user.focusEnd ? user.rects.length - 1 : 0]
|
146
147
|
const {cursor, userTip, anchor} = this.getUserCursor(i)
|
147
|
-
if (!
|
148
|
+
if (!child) {
|
148
149
|
cursor.style.display = 'none'
|
149
150
|
} else {
|
150
151
|
Object.assign(cursor.style, {
|
151
|
-
left:
|
152
|
-
top:
|
152
|
+
left: child.x + (user.focusEnd ? child.width : 0) + 'px',
|
153
|
+
top: child.y + 'px',
|
153
154
|
width: '2px',
|
154
|
-
height:
|
155
|
+
height: child.height + 'px',
|
155
156
|
background: user.color,
|
156
157
|
display: 'block'
|
157
158
|
})
|
@@ -1,15 +1,26 @@
|
|
1
|
-
import {
|
2
|
-
|
1
|
+
import {
|
2
|
+
Doc as YDoc,
|
3
|
+
Map as YMap,
|
4
|
+
YArrayEvent,
|
5
|
+
YEvent,
|
6
|
+
YMapEvent,
|
7
|
+
Text as YText,
|
8
|
+
YTextEvent,
|
9
|
+
Array as YArray,
|
10
|
+
} from 'yjs'
|
11
|
+
import { ComponentInstance, ComponentLiteral, makeError, Registry, Selection, Slot, Translator } from '@textbus/core'
|
3
12
|
|
4
13
|
type YPath = [number, string][]
|
5
14
|
const collaborateErrorFn = makeError('Collaborate')
|
6
15
|
|
7
16
|
export class RemoteToLocal {
|
8
|
-
constructor(private
|
17
|
+
constructor(private yDoc: YDoc,
|
18
|
+
private translator: Translator,
|
19
|
+
private selection: Selection,
|
9
20
|
private registry: Registry) {
|
10
21
|
}
|
11
22
|
|
12
|
-
transform(events: YEvent[],
|
23
|
+
transform(events: YEvent[], rootComponent: ComponentInstance) {
|
13
24
|
events.forEach(ev => {
|
14
25
|
const path: YPath = []
|
15
26
|
|
@@ -17,6 +28,12 @@ export class RemoteToLocal {
|
|
17
28
|
path.push(ev.path.slice(i, i + 2) as [number, string])
|
18
29
|
}
|
19
30
|
|
31
|
+
const slot = rootComponent.slots.get(0)
|
32
|
+
|
33
|
+
if (!slot) {
|
34
|
+
throw collaborateErrorFn('cannot find child slot in root component!')
|
35
|
+
}
|
36
|
+
|
20
37
|
if (path.length) {
|
21
38
|
const componentIndex = path.shift()![0] as number
|
22
39
|
const component = slot.getContentAtIndex(componentIndex) as ComponentInstance
|
@@ -77,9 +94,9 @@ export class RemoteToLocal {
|
|
77
94
|
this.applySharedComponentToComponent(ev, path, component)
|
78
95
|
return
|
79
96
|
}
|
80
|
-
|
81
97
|
if (ev instanceof YTextEvent) {
|
82
98
|
slot.retain(0)
|
99
|
+
let offset = 0
|
83
100
|
ev.delta.forEach(action => {
|
84
101
|
if (Reflect.has(action, 'retain')) {
|
85
102
|
if (action.attributes) {
|
@@ -93,19 +110,30 @@ export class RemoteToLocal {
|
|
93
110
|
slot.insert(action.insert, action.attributes ? Object.keys(action.attributes).map(key => {
|
94
111
|
return [this.registry.getFormatter(key)!, action.attributes![key]]
|
95
112
|
}) : [])
|
113
|
+
offset += action.insert.length
|
96
114
|
} else {
|
97
115
|
const component = this.createComponentBySharedComponent(action.insert as YMap<any>)
|
98
116
|
slot.insert(component)
|
117
|
+
offset += 1
|
99
118
|
}
|
100
119
|
} else if (action.delete) {
|
101
120
|
slot.retain(slot.index)
|
102
121
|
slot.delete(action.delete)
|
122
|
+
offset -= action.delete
|
103
123
|
} else if (action.attributes) {
|
104
124
|
slot.updateState(draft => {
|
105
125
|
Object.assign(draft, action.attributes)
|
106
126
|
})
|
107
127
|
}
|
108
128
|
})
|
129
|
+
if (this.selection.isSelected) {
|
130
|
+
if (slot === this.selection.startSlot) {
|
131
|
+
this.selection.setStart(slot, this.selection.startOffset! + offset)
|
132
|
+
}
|
133
|
+
if (slot === this.selection.endSlot) {
|
134
|
+
this.selection.setEnd(slot, this.selection.endOffset! + offset)
|
135
|
+
}
|
136
|
+
}
|
109
137
|
} else if (ev instanceof YMapEvent) {
|
110
138
|
ev.keysChanged.forEach(key => {
|
111
139
|
if (key === 'state') {
|
package/src/collaborate.ts
CHANGED
@@ -33,7 +33,7 @@ export class Collaborate implements History {
|
|
33
33
|
}
|
34
34
|
|
35
35
|
private localToRemote = new LocalToRemote()
|
36
|
-
private remoteToLocal = new RemoteToLocal(this.translator, this.registry)
|
36
|
+
private remoteToLocal = new RemoteToLocal(this.yDoc, this.translator, this.selection, this.registry)
|
37
37
|
|
38
38
|
private backEvent = new Subject<void>()
|
39
39
|
private forwardEvent = new Subject<void>()
|
@@ -99,15 +99,17 @@ export class Collaborate implements History {
|
|
99
99
|
|
100
100
|
private listen2() {
|
101
101
|
const root = this.yDoc.getText('content')
|
102
|
-
const
|
103
|
-
this.manager = new UndoManager(root
|
102
|
+
const rootComponent = this.rootComponentRef.component!
|
103
|
+
this.manager = new UndoManager(root, {
|
104
|
+
trackedOrigins: new Set<any>([this.yDoc])
|
105
|
+
})
|
104
106
|
root.observeDeep((events, transaction) => {
|
105
107
|
if (transaction.origin === this.yDoc) {
|
106
108
|
return
|
107
109
|
}
|
108
110
|
this.updateFromSelf = false
|
109
111
|
|
110
|
-
this.remoteToLocal.transform(events,
|
112
|
+
this.remoteToLocal.transform(events, rootComponent)
|
111
113
|
this.renderer.render()
|
112
114
|
this.selection.restore()
|
113
115
|
this.updateFromSelf = true
|