@seafile/sdoc-editor 0.1.48 → 0.1.49
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/dist/basic-sdk/assets/css/layout.css +4 -0
- package/dist/basic-sdk/assets/css/sdoc-editor-plugins.css +9 -0
- package/dist/basic-sdk/cursor/decorate-cursors.js +32 -0
- package/dist/basic-sdk/cursor/helper.js +39 -0
- package/dist/basic-sdk/decorates/index.js +25 -0
- package/dist/basic-sdk/editor.js +8 -2
- package/dist/basic-sdk/editor2.js +107 -0
- package/dist/basic-sdk/extension/index.js +2 -2
- package/dist/basic-sdk/extension/plugins/text-style/caret.js +49 -0
- package/dist/basic-sdk/extension/plugins/text-style/render-elem.js +11 -1
- package/dist/basic-sdk/index.js +1 -1
- package/dist/basic-sdk/socket/helpers.js +16 -4
- package/dist/basic-sdk/socket/socket-client.js +7 -4
- package/dist/basic-sdk/socket/socket-manager.js +12 -3
- package/dist/basic-sdk/socket/with-socket-io.js +6 -3
- package/dist/pages/simple-editor.js +2 -1
- package/package.json +3 -1
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
2
|
+
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
|
3
|
+
import { Text, Path, Range } from '@seafile/slate';
|
|
4
|
+
export var decorateCursors = function decorateCursors(nodeEntry, storageCursors) {
|
|
5
|
+
var ranges = [];
|
|
6
|
+
var _nodeEntry = _slicedToArray(nodeEntry, 2),
|
|
7
|
+
node = _nodeEntry[0],
|
|
8
|
+
path = _nodeEntry[1];
|
|
9
|
+
var cursors = Object.values(storageCursors || {});
|
|
10
|
+
if (Text.isText(node) && (cursors === null || cursors === void 0 ? void 0 : cursors.length)) {
|
|
11
|
+
cursors.forEach(function (cursor) {
|
|
12
|
+
if (Range.includes(cursor, path)) {
|
|
13
|
+
var focus = cursor.focus,
|
|
14
|
+
anchor = cursor.anchor;
|
|
15
|
+
var isFocusNode = Path.equals(focus.path, path);
|
|
16
|
+
var isAnchorNode = Path.equals(anchor.path, path);
|
|
17
|
+
ranges.push(_objectSpread(_objectSpread({}, cursor), {}, {
|
|
18
|
+
isCaret: isFocusNode,
|
|
19
|
+
anchor: {
|
|
20
|
+
path: path,
|
|
21
|
+
offset: isAnchorNode ? anchor.offset : node.text.length
|
|
22
|
+
},
|
|
23
|
+
focus: {
|
|
24
|
+
path: path,
|
|
25
|
+
offset: isFocusNode ? focus.offset : 0
|
|
26
|
+
}
|
|
27
|
+
}));
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
return ranges;
|
|
32
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
2
|
+
import randomColor from 'randomcolor';
|
|
3
|
+
|
|
4
|
+
// selection: { anchor, focus }
|
|
5
|
+
// cursor: { anchor, focus }
|
|
6
|
+
|
|
7
|
+
export var setCursor = function setCursor(editor, operations, user, selection, cursorData) {
|
|
8
|
+
var clientId = user.username;
|
|
9
|
+
var cursorOps = operations.filter(function (operation) {
|
|
10
|
+
return operation.type === 'set_selection';
|
|
11
|
+
});
|
|
12
|
+
if (!editor.cursors) editor.cursors = {};
|
|
13
|
+
var oldCursor = editor.cursors[clientId] ? editor.cursors[clientId] : {};
|
|
14
|
+
var lastCursorOp = cursorOps[cursorOps.length - 1];
|
|
15
|
+
if (selection) {
|
|
16
|
+
var newCursor = lastCursorOp && lastCursorOp.newProperties || {};
|
|
17
|
+
var newCursorData = _objectSpread(_objectSpread(_objectSpread(_objectSpread({}, oldCursor), newCursor), selection), cursorData);
|
|
18
|
+
editor.cursors[clientId] = newCursorData;
|
|
19
|
+
} else {
|
|
20
|
+
delete editor.cursors[clientId];
|
|
21
|
+
}
|
|
22
|
+
return editor;
|
|
23
|
+
};
|
|
24
|
+
export var deleteCursor = function deleteCursor(editor, username) {
|
|
25
|
+
delete editor.cursors[username];
|
|
26
|
+
};
|
|
27
|
+
export var generateCursorData = function generateCursorData(config) {
|
|
28
|
+
var user = config.user;
|
|
29
|
+
var options = {
|
|
30
|
+
luminosity: 'dark',
|
|
31
|
+
format: 'rgba',
|
|
32
|
+
alpha: 1
|
|
33
|
+
};
|
|
34
|
+
var color = randomColor(options);
|
|
35
|
+
return {
|
|
36
|
+
name: user.name,
|
|
37
|
+
color: color
|
|
38
|
+
};
|
|
39
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
|
|
2
|
+
import { useCallback } from 'react';
|
|
3
|
+
import { decorateCursors } from '../cursor/decorate-cursors';
|
|
4
|
+
export var useDecorate = function useDecorate(editor) {
|
|
5
|
+
var cursors = editor.cursors;
|
|
6
|
+
var decorate = useCallback(function (nodeEntry) {
|
|
7
|
+
var ranges = [];
|
|
8
|
+
var addRanges = function addRanges(newRanges) {
|
|
9
|
+
if (newRanges.length) {
|
|
10
|
+
ranges = [].concat(_toConsumableArray(ranges), _toConsumableArray(newRanges));
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
console.log('eeee');
|
|
14
|
+
// useCursor
|
|
15
|
+
addRanges(decorateCursors(nodeEntry, cursors));
|
|
16
|
+
|
|
17
|
+
// others decorate
|
|
18
|
+
// ...
|
|
19
|
+
|
|
20
|
+
return ranges;
|
|
21
|
+
}, [cursors]);
|
|
22
|
+
return {
|
|
23
|
+
decorate: decorate
|
|
24
|
+
};
|
|
25
|
+
};
|
package/dist/basic-sdk/editor.js
CHANGED
|
@@ -13,6 +13,7 @@ import withNodeId from './node-id';
|
|
|
13
13
|
import SDocOutline from './outline';
|
|
14
14
|
import EventProxy from './utils/event-handler';
|
|
15
15
|
import { focusEditor } from './extension/core';
|
|
16
|
+
import { uiDecorate } from './decorates';
|
|
16
17
|
import './assets/css/layout.css';
|
|
17
18
|
import './assets/css/sdoc-editor-plugins.css';
|
|
18
19
|
var SDocEditor = /*#__PURE__*/function (_React$Component) {
|
|
@@ -45,7 +46,9 @@ var SDocEditor = /*#__PURE__*/function (_React$Component) {
|
|
|
45
46
|
});
|
|
46
47
|
}
|
|
47
48
|
};
|
|
48
|
-
var
|
|
49
|
+
var _props$document = props.document,
|
|
50
|
+
children = _props$document.children,
|
|
51
|
+
cursors = _props$document.cursors;
|
|
49
52
|
_this.state = {
|
|
50
53
|
slateValue: children,
|
|
51
54
|
isLoading: true
|
|
@@ -60,6 +63,7 @@ var SDocEditor = /*#__PURE__*/function (_React$Component) {
|
|
|
60
63
|
config: config
|
|
61
64
|
});
|
|
62
65
|
}
|
|
66
|
+
_this.editor.cursors = cursors;
|
|
63
67
|
_this.eventProxy = new EventProxy(_this.editor);
|
|
64
68
|
_this.renderElement = function (props) {
|
|
65
69
|
return renderElement(props, _this.editor);
|
|
@@ -67,6 +71,7 @@ var SDocEditor = /*#__PURE__*/function (_React$Component) {
|
|
|
67
71
|
_this.renderLeaf = function (props) {
|
|
68
72
|
return renderLeaf(props, _this.editor);
|
|
69
73
|
};
|
|
74
|
+
_this.decorate = uiDecorate(_this.editor);
|
|
70
75
|
return _this;
|
|
71
76
|
}
|
|
72
77
|
_createClass(SDocEditor, [{
|
|
@@ -110,7 +115,8 @@ var SDocEditor = /*#__PURE__*/function (_React$Component) {
|
|
|
110
115
|
renderElement: this.renderElement,
|
|
111
116
|
renderLeaf: this.renderLeaf,
|
|
112
117
|
onKeyDown: this.eventProxy.onKeyDown,
|
|
113
|
-
onDOMBeforeInput: this.onDOMBeforeInput
|
|
118
|
+
onDOMBeforeInput: this.onDOMBeforeInput,
|
|
119
|
+
decorate: this.decorate
|
|
114
120
|
}))))));
|
|
115
121
|
}
|
|
116
122
|
}]);
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
|
|
2
|
+
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
|
3
|
+
var _this = this;
|
|
4
|
+
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
|
5
|
+
import { Node } from '@seafile/slate';
|
|
6
|
+
import { Editable, Slate, ReactEditor } from '@seafile/slate-react';
|
|
7
|
+
import { Editor } from '@seafile/slate';
|
|
8
|
+
import { useUpdate } from 'ahooks';
|
|
9
|
+
import editor2, { renderLeaf, renderElement, Toolbar } from './extension';
|
|
10
|
+
import { withSocketIO } from './socket';
|
|
11
|
+
import withNodeId from './node-id';
|
|
12
|
+
import SDocOutline from './outline';
|
|
13
|
+
import EventProxy from './utils/event-handler';
|
|
14
|
+
import { focusEditor } from './extension/core';
|
|
15
|
+
import './assets/css/layout.css';
|
|
16
|
+
import './assets/css/sdoc-editor-plugins.css';
|
|
17
|
+
import { useDecorate } from './decorates';
|
|
18
|
+
var SDocEditor = function SDocEditor(_ref) {
|
|
19
|
+
var document = _ref.document,
|
|
20
|
+
config = _ref.config;
|
|
21
|
+
var _useState = useState(document.children),
|
|
22
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
23
|
+
slateValue = _useState2[0],
|
|
24
|
+
setSlateValue = _useState2[1];
|
|
25
|
+
|
|
26
|
+
// init editor
|
|
27
|
+
var editor = useMemo(function () {
|
|
28
|
+
var newEditor = withNodeId(withSocketIO(editor2, {
|
|
29
|
+
document: document,
|
|
30
|
+
config: config
|
|
31
|
+
}));
|
|
32
|
+
var cursors = document.cursors;
|
|
33
|
+
newEditor.cursors = cursors || {};
|
|
34
|
+
return newEditor;
|
|
35
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
36
|
+
}, []);
|
|
37
|
+
var eventProxy = useMemo(function () {
|
|
38
|
+
return new EventProxy(editor);
|
|
39
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
40
|
+
}, []);
|
|
41
|
+
|
|
42
|
+
// useMount: init socket connection
|
|
43
|
+
useEffect(function () {
|
|
44
|
+
editor.openConnection();
|
|
45
|
+
return function () {
|
|
46
|
+
editor.closeConnection();
|
|
47
|
+
};
|
|
48
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
49
|
+
}, []);
|
|
50
|
+
|
|
51
|
+
// useMount: focus editor
|
|
52
|
+
useEffect(function () {
|
|
53
|
+
if (Node.string(editor) === '') {
|
|
54
|
+
var firstNodePath = ReactEditor.findPath(editor, editor.children[0]);
|
|
55
|
+
focusEditor(_this.editor, firstNodePath);
|
|
56
|
+
}
|
|
57
|
+
}, []);
|
|
58
|
+
var _renderElement = useCallback(function (props) {
|
|
59
|
+
return renderElement(props, editor);
|
|
60
|
+
}, []);
|
|
61
|
+
var _renderLeaf = useCallback(function (props) {
|
|
62
|
+
return renderLeaf(props, editor);
|
|
63
|
+
}, []);
|
|
64
|
+
var onChange = useCallback(function (slateValue) {
|
|
65
|
+
setSlateValue(_toConsumableArray(slateValue));
|
|
66
|
+
}, []);
|
|
67
|
+
var update = useUpdate();
|
|
68
|
+
var onDOMBeforeInput = useCallback(function (e) {
|
|
69
|
+
if (e.data && e.data !== '') {
|
|
70
|
+
var _node$;
|
|
71
|
+
var node = Editor.parent(editor, editor.selection);
|
|
72
|
+
editor.onDOMBeforeInputId = (_node$ = node[0]) === null || _node$ === void 0 ? void 0 : _node$.id;
|
|
73
|
+
update();
|
|
74
|
+
} else {
|
|
75
|
+
editor.onDOMBeforeInputId = null;
|
|
76
|
+
update();
|
|
77
|
+
}
|
|
78
|
+
}, []);
|
|
79
|
+
var _useDecorate = useDecorate(editor),
|
|
80
|
+
decorate = _useDecorate.decorate;
|
|
81
|
+
console.log('dadadihuaile');
|
|
82
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
83
|
+
className: "sdoc-editor-container"
|
|
84
|
+
}, /*#__PURE__*/React.createElement(Toolbar, {
|
|
85
|
+
editor: editor
|
|
86
|
+
}), /*#__PURE__*/React.createElement("div", {
|
|
87
|
+
className: "sdoc-editor-content"
|
|
88
|
+
}, /*#__PURE__*/React.createElement(SDocOutline, {
|
|
89
|
+
doc: slateValue,
|
|
90
|
+
docUuid: config.docUuid
|
|
91
|
+
}), /*#__PURE__*/React.createElement("div", {
|
|
92
|
+
className: "flex-fill o-auto"
|
|
93
|
+
}, /*#__PURE__*/React.createElement(Slate, {
|
|
94
|
+
editor: editor,
|
|
95
|
+
value: slateValue,
|
|
96
|
+
onChange: onChange
|
|
97
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
98
|
+
className: "article"
|
|
99
|
+
}, /*#__PURE__*/React.createElement(Editable, {
|
|
100
|
+
renderElement: _renderElement,
|
|
101
|
+
renderLeaf: _renderLeaf,
|
|
102
|
+
onKeyDown: eventProxy.onKeyDown,
|
|
103
|
+
onDOMBeforeInput: onDOMBeforeInput,
|
|
104
|
+
decorate: decorate
|
|
105
|
+
}))))));
|
|
106
|
+
};
|
|
107
|
+
export default SDocEditor;
|
|
@@ -6,12 +6,12 @@ import renderElement from './render/render-element';
|
|
|
6
6
|
import renderLeaf from './render/render-leaf';
|
|
7
7
|
import Toolbar from './toolbar';
|
|
8
8
|
var baseEditor = withHistory(withReact(createEditor()));
|
|
9
|
-
var
|
|
9
|
+
var editor2 = Plugins.reduce(function (editor, pluginItem) {
|
|
10
10
|
var withPlugin = pluginItem.editorPlugin;
|
|
11
11
|
if (withPlugin) {
|
|
12
12
|
return withPlugin(editor);
|
|
13
13
|
}
|
|
14
14
|
return editor;
|
|
15
15
|
}, baseEditor);
|
|
16
|
-
export default
|
|
16
|
+
export default editor2;
|
|
17
17
|
export { renderLeaf, renderElement, Toolbar };
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
var cursorStyleBase = {
|
|
4
|
+
position: 'absolute',
|
|
5
|
+
top: -2,
|
|
6
|
+
pointerEvents: 'none',
|
|
7
|
+
userSelect: 'none',
|
|
8
|
+
transform: 'translateY(-100%)',
|
|
9
|
+
fontSize: 10,
|
|
10
|
+
color: 'white',
|
|
11
|
+
background: 'palevioletred',
|
|
12
|
+
whiteSpace: 'nowrap'
|
|
13
|
+
};
|
|
14
|
+
var caretStyleBase = {
|
|
15
|
+
position: 'absolute',
|
|
16
|
+
// pointerEvents: 'none',
|
|
17
|
+
userSelect: 'none',
|
|
18
|
+
height: '1.2em',
|
|
19
|
+
width: 2,
|
|
20
|
+
background: 'palevioletred'
|
|
21
|
+
};
|
|
22
|
+
var Caret = function Caret(_ref) {
|
|
23
|
+
var color = _ref.color,
|
|
24
|
+
name = _ref.name;
|
|
25
|
+
var cursorStyles = _objectSpread(_objectSpread({}, cursorStyleBase), {}, {
|
|
26
|
+
background: color,
|
|
27
|
+
left: '0%',
|
|
28
|
+
cursor: 'default'
|
|
29
|
+
});
|
|
30
|
+
var caretStyles = _objectSpread(_objectSpread({}, caretStyleBase), {}, {
|
|
31
|
+
background: color,
|
|
32
|
+
left: '0%'
|
|
33
|
+
});
|
|
34
|
+
caretStyles['top'] = 1;
|
|
35
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("span", {
|
|
36
|
+
className: "caret-item",
|
|
37
|
+
contentEditable: false,
|
|
38
|
+
style: caretStyles
|
|
39
|
+
}, /*#__PURE__*/React.createElement("span", {
|
|
40
|
+
style: {
|
|
41
|
+
position: 'relative'
|
|
42
|
+
}
|
|
43
|
+
}, /*#__PURE__*/React.createElement("span", {
|
|
44
|
+
className: "caret-name",
|
|
45
|
+
contentEditable: false,
|
|
46
|
+
style: cursorStyles
|
|
47
|
+
}, name))));
|
|
48
|
+
};
|
|
49
|
+
export default Caret;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import Caret from './caret';
|
|
2
3
|
var renderText = function renderText(props, editor) {
|
|
3
4
|
var attributes = props.attributes,
|
|
4
5
|
children = props.children,
|
|
@@ -38,8 +39,17 @@ var renderText = function renderText(props, editor) {
|
|
|
38
39
|
className: "token ".concat(leaf.type)
|
|
39
40
|
}, markedChildren);
|
|
40
41
|
}
|
|
42
|
+
var style = {
|
|
43
|
+
position: 'relative'
|
|
44
|
+
};
|
|
45
|
+
if (leaf.isCaret) {
|
|
46
|
+
style['display'] = 'inline-block';
|
|
47
|
+
style['minWidth'] = '2px';
|
|
48
|
+
}
|
|
41
49
|
return /*#__PURE__*/React.createElement("span", Object.assign({
|
|
42
50
|
"data-id": leaf.id
|
|
43
|
-
}, attributes
|
|
51
|
+
}, attributes, {
|
|
52
|
+
style: style
|
|
53
|
+
}), leaf.isCaret ? /*#__PURE__*/React.createElement(Caret, leaf) : null, markedChildren);
|
|
44
54
|
};
|
|
45
55
|
export default renderText;
|
package/dist/basic-sdk/index.js
CHANGED
|
@@ -3,6 +3,8 @@ import deepCopy from 'deep-copy';
|
|
|
3
3
|
import { Editor, Operation } from '@seafile/slate';
|
|
4
4
|
import { getNode } from '../extension/core';
|
|
5
5
|
import * as OPERATION from '../node-id/constants';
|
|
6
|
+
import { setCursor } from '../cursor/helper';
|
|
7
|
+
import context from '../../context';
|
|
6
8
|
export var getNodePathById = function getNodePathById(rootNode, nodeId) {
|
|
7
9
|
var path = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
|
|
8
10
|
if (rootNode.id === nodeId) return path;
|
|
@@ -250,11 +252,21 @@ export var reExecRevertOperationList = function reExecRevertOperationList(editor
|
|
|
250
252
|
_loop2();
|
|
251
253
|
}
|
|
252
254
|
};
|
|
253
|
-
export var syncRemoteOperations = function syncRemoteOperations(editor, remoteOperations) {
|
|
255
|
+
export var syncRemoteOperations = function syncRemoteOperations(editor, remoteOperations, user, selection, cursorData) {
|
|
254
256
|
if (remoteOperations.length === 0) return;
|
|
255
257
|
Editor.withoutNormalizing(editor, function () {
|
|
256
|
-
remoteOperations.
|
|
257
|
-
|
|
258
|
-
|
|
258
|
+
for (var i = 0; i < remoteOperations.length; i++) {
|
|
259
|
+
var op = remoteOperations[i];
|
|
260
|
+
if (op.type === 'set_selection') {
|
|
261
|
+
continue;
|
|
262
|
+
}
|
|
263
|
+
editor.apply(op);
|
|
264
|
+
}
|
|
265
|
+
var currentUser = editor.user;
|
|
266
|
+
if (user && user.username !== currentUser.username) {
|
|
267
|
+
setCursor(editor, remoteOperations, user, selection, cursorData);
|
|
268
|
+
// sync cursor position
|
|
269
|
+
editor.onChange();
|
|
270
|
+
}
|
|
259
271
|
});
|
|
260
272
|
};
|
|
@@ -11,10 +11,12 @@ var SocketClient = /*#__PURE__*/_createClass(function SocketClient(config) {
|
|
|
11
11
|
var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
12
12
|
var _this$config = _this.config,
|
|
13
13
|
docUuid = _this$config.docUuid,
|
|
14
|
-
user = _this$config.user
|
|
14
|
+
user = _this$config.user,
|
|
15
|
+
cursorData = _this$config.cursorData;
|
|
15
16
|
return _objectSpread({
|
|
16
17
|
doc_uuid: docUuid,
|
|
17
|
-
user: user
|
|
18
|
+
user: user,
|
|
19
|
+
cursor_data: cursorData
|
|
18
20
|
}, params);
|
|
19
21
|
};
|
|
20
22
|
this.onConnected = function () {
|
|
@@ -76,13 +78,14 @@ var SocketClient = /*#__PURE__*/_createClass(function SocketClient(config) {
|
|
|
76
78
|
var socketManager = SocketManager.getInstance();
|
|
77
79
|
socketManager.dispatchConnectState('leave-room', username);
|
|
78
80
|
};
|
|
79
|
-
this.sendOperations = function (operations, version, callback) {
|
|
81
|
+
this.sendOperations = function (operations, version, selection, callback) {
|
|
80
82
|
debug('=========== send operations ==========');
|
|
81
83
|
debug('%O', operations);
|
|
82
84
|
debug('======================================');
|
|
83
85
|
_this.socket.emit('update-document', _this.getParams({
|
|
84
86
|
operations: operations,
|
|
85
|
-
version: version
|
|
87
|
+
version: version,
|
|
88
|
+
selection: selection
|
|
86
89
|
}), function (result) {
|
|
87
90
|
callback && callback(result);
|
|
88
91
|
});
|
|
@@ -4,6 +4,7 @@ import EventBus from '../utils/event-bus';
|
|
|
4
4
|
import { syncRemoteOperations, reExecRevertOperationList, revertOperationList } from './helpers';
|
|
5
5
|
import SocketClient from './socket-client';
|
|
6
6
|
import debug from '../utils/debug';
|
|
7
|
+
import { deleteCursor } from '../cursor/helper';
|
|
7
8
|
var SocketManager = /*#__PURE__*/_createClass(function SocketManager(editor, document, config) {
|
|
8
9
|
var _this = this;
|
|
9
10
|
_classCallCheck(this, SocketManager);
|
|
@@ -28,7 +29,8 @@ var SocketManager = /*#__PURE__*/_createClass(function SocketManager(editor, doc
|
|
|
28
29
|
_this.dispatchConnectState('is-saving');
|
|
29
30
|
var version = _this.document.version;
|
|
30
31
|
var operations = _this.pendingOperationList.shift();
|
|
31
|
-
|
|
32
|
+
var selection = _this.editor.selection;
|
|
33
|
+
_this.socketClient.sendOperations(operations, version, selection, _this.sendOperationsCallback);
|
|
32
34
|
};
|
|
33
35
|
this.sendOperationsCallback = function (result) {
|
|
34
36
|
if (result && result.success) {
|
|
@@ -83,10 +85,13 @@ var SocketManager = /*#__PURE__*/_createClass(function SocketManager(editor, doc
|
|
|
83
85
|
}
|
|
84
86
|
|
|
85
87
|
// 2. execute operations
|
|
86
|
-
var operations = params.operations
|
|
88
|
+
var operations = params.operations,
|
|
89
|
+
user = params.user,
|
|
90
|
+
selection = params.selection,
|
|
91
|
+
cursorData = params.cursor_data;
|
|
87
92
|
// 2.1 Update content & version
|
|
88
93
|
debug('execute remote operations: %O', operations);
|
|
89
|
-
syncRemoteOperations(_this.editor, operations);
|
|
94
|
+
syncRemoteOperations(_this.editor, operations, user, selection, cursorData);
|
|
90
95
|
|
|
91
96
|
// 2.2 Update document
|
|
92
97
|
_this.document.version = serverVersion;
|
|
@@ -157,6 +162,10 @@ var SocketManager = /*#__PURE__*/_createClass(function SocketManager(editor, doc
|
|
|
157
162
|
});
|
|
158
163
|
};
|
|
159
164
|
this.dispatchConnectState = function (type, message) {
|
|
165
|
+
if (type === 'leave-room') {
|
|
166
|
+
deleteCursor(_this.editor, message);
|
|
167
|
+
_this.editor.onChange();
|
|
168
|
+
}
|
|
160
169
|
_this.eventBus.dispatch(type, message);
|
|
161
170
|
};
|
|
162
171
|
this.closeSocketConnect = function () {
|
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
var _this = this;
|
|
2
|
+
import { generateCursorData } from '../cursor/helper';
|
|
2
3
|
import SocketManager from './socket-manager';
|
|
3
4
|
var withSocketIO = function withSocketIO(editor, options) {
|
|
4
5
|
var onChange = editor.onChange;
|
|
5
6
|
var newEditor = editor;
|
|
6
7
|
var socketManager = null;
|
|
8
|
+
var user = options.config.user;
|
|
9
|
+
newEditor.user = user;
|
|
7
10
|
newEditor.openConnection = function () {
|
|
8
11
|
var document = options.document,
|
|
9
12
|
config = options.config;
|
|
13
|
+
var cursorData = generateCursorData(options.config);
|
|
14
|
+
config['cursorData'] = cursorData;
|
|
10
15
|
socketManager = SocketManager.getInstance(newEditor, document, config);
|
|
11
16
|
};
|
|
12
17
|
newEditor.closeConnection = function () {
|
|
@@ -14,9 +19,7 @@ var withSocketIO = function withSocketIO(editor, options) {
|
|
|
14
19
|
};
|
|
15
20
|
newEditor.onChange = function () {
|
|
16
21
|
var operations = newEditor.operations;
|
|
17
|
-
operations = operations.filter(
|
|
18
|
-
return item.type !== 'set_selection';
|
|
19
|
-
});
|
|
22
|
+
// operations = operations.filter(item => item.type !== 'set_selection');
|
|
20
23
|
if (!newEditor.isRemote && operations.length > 0) {
|
|
21
24
|
var _socketManager = SocketManager.getInstance();
|
|
22
25
|
_socketManager.addOperations && _socketManager.addOperations(operations);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@seafile/sdoc-editor",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.49",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "This is a sdoc editor",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -10,10 +10,12 @@
|
|
|
10
10
|
"@seafile/slate-history": "0.86.2",
|
|
11
11
|
"@seafile/slate-hyperscript": "0.81.7",
|
|
12
12
|
"@seafile/slate-react": "0.92.2",
|
|
13
|
+
"ahooks": "3.7.7",
|
|
13
14
|
"classnames": "2.3.2",
|
|
14
15
|
"deep-copy": "1.4.2",
|
|
15
16
|
"is-hotkey": "0.2.0",
|
|
16
17
|
"is-url": "^1.2.4",
|
|
18
|
+
"randomcolor": "0.6.2",
|
|
17
19
|
"react-cookies": "0.1.1",
|
|
18
20
|
"reactstrap": "8.9.0",
|
|
19
21
|
"slugid": "3.2.0",
|