@textbus/collaborate 2.0.0-alpha.43 → 2.0.0-alpha.47
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundles/collab/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":"AAAA,OAAO,EAGL,WAAW,EAEX,SAAS,EAET,UAAU,GAEX,MAAM,KAAK,CAAA;AACZ,OAAO,EAAuC,SAAS,EAAyC,MAAM,eAAe,CAAA;AAGrH,MAAM,kBAAkB,GAAG,SAAS,CAAC,aAAa,CAAC,CAAA;AAEnD,MAAM,OAAO,aAAa;IACxB,YAAoB,IAAU,EACV,UAAsB,EACtB,SAAoB,EACpB,QAAkB;;;;;mBAHlB;;;;;;mBACA;;;;;;mBACA;;;;;;mBACA;;IACpB,CAAC;IAED,SAAS,CAAC,MAAgB,EAAE,aAAgC;QAC1D,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE;YAClB,MAAM,IAAI,GAAU,EAAE,CAAA;YAEtB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE;gBAC1C,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAqB,CAAC,CAAA;aACvD;YAED,MAAM,IAAI,GAAG,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;YAEvC,IAAI,CAAC,IAAI,EAAE;gBACT,MAAM,kBAAkB,CAAC,2CAA2C,CAAC,CAAA;aACtE;YAED,IAAI,IAAI,CAAC,MAAM,EAAE;gBACf,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,EAAG,CAAC,CAAC,CAAW,CAAA;gBACjD,MAAM,SAAS,GAAG,IAAI,CAAC,iBAAiB,CAAC,cAAc,CAAsB,CAAA;gBAC7E,IAAI,CAAC,+BAA+B,CAAC,EAAE,EAAE,IAAI,EAAE,SAAS,CAAC,CAAA;gBACzD,OAAM;aACP;YAED,IAAI,CAAC,qBAAqB,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;QAC5C,CAAC,CAAC,CAAA;IACJ,CAAC;IAEO,+BAA+B,CAAC,EAAU,EAAE,IAAW,EAAE,SAA4B;QAC3F,IAAI,IAAI,CAAC,MAAM,EAAE;YACf,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,EAAG,CAAA;YAC/B,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAE,CAAA;YAC/C,IAAI,CAAC,qBAAqB,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;YAC1C,OAAM;SACP;QACD,IAAI,EAAE,YAAY,SAAS,EAAE;YAC3B,EAAE,CAAC,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;gBAC3B,IAAI,GAAG,KAAK,OAAO,EAAE;oBACnB,MAAM,KAAK,GAAI,EAAE,CAAC,MAAoB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;oBACnD,SAAS,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE;wBAC5B,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;oBAC7B,CAAC,CAAC,CAAA;iBACH;YACH,CAAC,CAAC,CAAA;SACH;aAAM,IAAI,EAAE,YAAY,WAAW,EAAE;YACpC,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAA;YAC7B,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;gBACxB,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE;oBACjC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,MAAO,CAAC,CAAA;iBAC7B;qBAAM,IAAI,MAAM,CAAC,MAAM,EAAE;oBACvB,MAAM,CAAC,MAA2B,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;wBACjD,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,CAAC,CAAA;oBACjD,CAAC,CAAC,CAAA;iBACH;qBAAM,IAAI,MAAM,CAAC,MAAM,EAAE;oBACxB,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;oBACzB,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;iBAC5B;YACH,CAAC,CAAC,CAAA;SACH;IACH,CAAC;IAEO,qBAAqB,CAAC,EAAU,EAAE,IAAW,EAAE,IAAU;QAC/D,IAAI,IAAI,CAAC,MAAM,EAAE;YACf,IAAI,CAAC,KAAK,EAAE,CAAA;YACZ,MAAM,KAAK,GAAI,EAAE,CAAC,MAAM,CAAC,MAAgB,CAAC,OAAO,EAAE,CAAA;YACnD,IAAI,cAAc,GAAG,CAAC,CAAA;YACtB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;gBACrC,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;gBACvB,IAAI,MAAM,CAAC,MAAM,KAAK,EAAE,CAAC,MAAM,EAAE;oBAC/B,MAAK;iBACN;gBACD,cAAc,IAAI,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;aAC/E;YACD,MAAM,SAAS,GAAG,IAAI,CAAC,iBAAiB,CAAC,cAAc,CAAsB,CAAA;YAC7E,IAAI,CAAC,+BAA+B,CAAC,EAAE,EAAE,IAAI,EAAE,SAAS,CAAC,CAAA;YACzD,OAAM;SACP;QACD,IAAI,EAAE,YAAY,UAAU,EAAE;YAC5B,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;YACd,IAAI,MAAM,GAAG,CAAC,CAAA;YACd,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;gBACxB,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE;oBACjC,IAAI,MAAM,CAAC,UAAU,EAAE;wBACrB,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAO,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;4BACnE,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,GAAG,CAAE,EAAE,MAAM,CAAC,UAAW,CAAC,GAAG,CAAC,CAAC,CAAA;wBACpE,CAAC,CAAC,CAAC,CAAA;qBACJ;oBACD,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAO,CAAC,CAAA;iBAC5B;qBAAM,IAAI,MAAM,CAAC,MAAM,EAAE;oBACxB,IAAI,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,EAAE;wBACrC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;4BACtF,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,GAAG,CAAE,EAAE,MAAM,CAAC,UAAW,CAAC,GAAG,CAAC,CAAC,CAAA;wBACpE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;wBACR,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,CAAA;qBAC/B;yBAAM;wBACL,MAAM,SAAS,GAAG,IAAI,CAAC,gCAAgC,CAAC,MAAM,CAAC,MAAmB,CAAC,CAAA;wBACnF,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;wBACtB,MAAM,IAAI,CAAC,CAAA;qBACZ;iBACF;qBAAM,IAAI,MAAM,CAAC,MAAM,EAAE;oBACxB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;oBACvB,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;oBAC1B,MAAM,IAAI,MAAM,CAAC,MAAM,CAAA;iBACxB;qBAAM,IAAI,MAAM,CAAC,UAAU,EAAE;oBAC5B,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE;wBACvB,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,UAAU,CAAC,CAAA;oBACzC,CAAC,CAAC,CAAA;iBACH;YACH,CAAC,CAAC,CAAA;YACF,IAAI,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE;gBAC7B,IAAI,IAAI,KAAK,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE;oBACrC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,WAAY,GAAG,MAAM,CAAC,CAAA;iBACpE;gBACD,IAAI,IAAI,KAAK,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE;oBACnC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,SAAU,GAAG,MAAM,CAAC,CAAA;iBAChE;aACF;SACF;aAAM,IAAI,EAAE,YAAY,SAAS,EAAE;YAClC,EAAE,CAAC,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;gBAC3B,IAAI,GAAG,KAAK,OAAO,EAAE;oBACnB,MAAM,KAAK,GAAI,EAAE,CAAC,MAAoB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;oBACnD,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE;wBACvB,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;oBAC7B,CAAC,CAAC,CAAA;iBACH;YACH,CAAC,CAAC,CAAA;SACH;IACH,CAAC;IAEO,gCAAgC,CAAC,IAAe;QACtD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAsB,CAAA;QACpD,MAAM,gBAAgB,GAAqB;YACzC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC;YACxB,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC;YACtB,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE;gBAC5B,OAAO,IAAI,CAAC,sBAAsB,CAAC,UAAU,CAAC,CAAC,MAAM,EAAE,CAAA;YACzD,CAAC,CAAC;SACH,CAAA;QACD,OAAO,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC,gBAAgB,CAAE,CAAA;IAC3D,CAAC;IAEO,sBAAsB,CAAC,UAAqB;QAClD,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,CAAC,SAAS,CAAU,CAAA;QAClD,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,EAAE,CAAA;QAE/B,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;YACtC,MAAM,EAAE,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC;YAChC,KAAK,EAAE,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC;YAC9B,OAAO,EAAE,EAAE;YACX,OAAO,EAAE,EAAE;SACZ,CAAC,CAAA;QAEF,KAAK,MAAM,MAAM,IAAI,KAAK,EAAE;YAC1B,IAAI,MAAM,CAAC,MAAM,EAAE;gBACjB,IAAI,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,EAAE;oBACrC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;wBACtF,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,GAAG,CAAE,EAAE,MAAM,CAAC,UAAW,CAAC,GAAG,CAAC,CAAC,CAAA;oBACpE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;iBACT;qBAAM;oBACL,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,gCAAgC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAA;iBAClE;aACF;iBAAM;gBACL,MAAM,kBAAkB,CAAC,0BAA0B,CAAC,CAAA;aACrD;SACF;QACD,OAAO,IAAI,CAAA;IACb,CAAC;CACF","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":";;;;;;;;;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,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,QAAQ,CAAC;WAAA;QAEpG;;;;mBAAoB,IAAI,OAAO,EAAQ;WAAA;QACvC;;;;mBAAuB,IAAI,OAAO,EAAQ;WAAA;QAC1C;;;;mBAAsB,IAAI,OAAO,EAAQ;WAAA;QACzC;;;;mBAAoB,IAAI,OAAO,EAAQ;WAAA;QAEvC;;;;;WAA6B;QAE7B;;;;mBAAwC,EAAE;WAAA;QAC1C;;;;mBAAyB,IAAI;WAAA;QAE7B;;;;mBAA+B,IAAI,OAAO,EAAkB;WAAA;QAS1D,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,oBAAoB,CAAC,YAAY,EAAE,CAAA;QACjE,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,CAAA;QAC3C,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,CAAA;QACjD,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,YAAY,EAAE,CAAA;QAC/C,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,CAAA;IAC7C,CAAC;IAnCD,IAAI,OAAO;;QACT,OAAO,MAAA,IAAI,CAAC,OAAO,0CAAE,OAAO,EAAE,CAAA;IAChC,CAAC;IAED,IAAI,UAAU;;QACZ,OAAO,MAAA,IAAI,CAAC,OAAO,0CAAE,OAAO,EAAE,CAAA;IAChC,CAAC;IA+BD,KAAK;QACH,IAAI,CAAC,aAAa,CAAC,IAAI,CACrB,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,EAAE;YAClC,IAAI,CAAC,OAAO,EAAE,CAAA;QAChB,CAAC,CAAC,EACF,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC,GAAG,EAAE;YACrC,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAA;YACvC,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACvC,CAAC,CAAC,CACH,CAAA;IACH,CAAC;IAED,qBAAqB,CAAC,KAAwB;QAC5C,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IACpC,CAAC;IAED,MAAM;QACJ,EAAE;IACJ,CAAC;IAED,IAAI;QACF,IAAI,IAAI,CAAC,OAAO,EAAE;YAChB,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAA;SACpB;IACH,CAAC;IAED,OAAO;QACL,IAAI,IAAI,CAAC,UAAU,EAAE;YACnB,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAA;SACpB;IACH,CAAC;IAED,OAAO;QACL,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAA;IAClD,CAAC;IAEO,OAAO;QACb,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;QACzC,MAAM,aAAa,GAAG,IAAI,CAAC,gBAAgB,CAAC,SAAU,CAAA;QACtD,IAAI,CAAC,OAAO,GAAG,IAAI,WAAW,CAAC,IAAI,EAAE;YACnC,cAAc,EAAE,IAAI,GAAG,CAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;SAC1C,CAAC,CAAA;QACF,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,EAAE,WAAW,EAAE,EAAE;YACvC,IAAI,WAAW,CAAC,MAAM,KAAK,IAAI,CAAC,IAAI,EAAE;gBACpC,OAAM;aACP;YACD,IAAI,CAAC,cAAc,GAAG,KAAK,CAAA;YAE3B,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,MAAM,EAAE,aAAa,CAAC,CAAA;YACnD,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAA;YACtB,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAA;YACxB,IAAI,CAAC,cAAc,GAAG,IAAI,CAAA;QAC5B,CAAC,CAAC,CAAA;QACF,MAAM,UAAU,GAAgB,EAAE,CAAA;QAClC,IAAI,CAAC,aAAa,CAAC,IAAI,CACrB,IAAI,CAAC,gBAAgB,CAAC,SAAS,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,CACxD,MAAM,CAAC,GAAG,EAAE;YACV,OAAO,IAAI,CAAC,cAAc,CAAA;QAC5B,CAAC,CAAC,EACF,GAAG,CAAC,EAAE,CAAC,EAAE;YACP,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QACrB,CAAC,CAAC,EACF,YAAY,CAAC,CAAC,CAAC,CAChB,CAAC,SAAS,CAAC,GAAG,EAAE;YACf,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE;gBACtB,UAAU,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE;oBAC7B,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,SAAS,EAAE,IAAI,CAAC,CAAA;gBAC/C,CAAC,CAAC,CAAA;gBACF,UAAU,CAAC,MAAM,GAAG,CAAC,CAAA;YACvB,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAA;YACb,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAA;YACtB,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAA;QAC1B,CAAC,CAAC,CACH,CAAA;IACH,CAAC;CACF,CAAA;AAxHY,WAAW;IADvB,UAAU,EAAE;qCAgC2B,gBAAgB;QACf,iBAAiB;QACxB,UAAU;QACZ,QAAQ;QACR,QAAQ;QACP,SAAS;QACX,OAAO;GArCzB,WAAW,CAwHvB;SAxHY,WAAW","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.47",
|
|
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.47",
|
|
31
|
+
"@textbus/core": "^2.0.0-alpha.47",
|
|
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": "b9eabad68b1af458b3269201672d6ee1f6304540"
|
|
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
|