@seafile/sdoc-editor 0.1.50 → 0.1.52
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/cursor/helper.js +4 -9
- package/dist/basic-sdk/editor.js +15 -31
- package/dist/basic-sdk/extension/plugins/header/render-elem.js +3 -2
- package/dist/basic-sdk/extension/render/render-element.js +9 -18
- package/dist/basic-sdk/socket/helpers.js +10 -7
- package/dist/basic-sdk/socket/socket-client.js +14 -4
- package/dist/basic-sdk/socket/socket-manager.js +13 -6
- package/dist/basic-sdk/socket/with-socket-io.js +11 -1
- package/package.json +2 -2
|
@@ -4,17 +4,12 @@ import randomColor from 'randomcolor';
|
|
|
4
4
|
// selection: { anchor, focus }
|
|
5
5
|
// cursor: { anchor, focus }
|
|
6
6
|
|
|
7
|
-
export var setCursor = function setCursor(editor,
|
|
7
|
+
export var setCursor = function setCursor(editor, user, location, cursorData) {
|
|
8
8
|
var clientId = user.username;
|
|
9
|
-
var cursorOps = operations.filter(function (operation) {
|
|
10
|
-
return operation.type === 'set_selection';
|
|
11
|
-
});
|
|
12
9
|
if (!editor.cursors) editor.cursors = {};
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
var newCursor = lastCursorOp && lastCursorOp.newProperties || {};
|
|
17
|
-
var newCursorData = _objectSpread(_objectSpread(_objectSpread(_objectSpread({}, oldCursor), newCursor), selection), cursorData);
|
|
10
|
+
if (location) {
|
|
11
|
+
var oldCursor = editor.cursors[clientId] ? editor.cursors[clientId] : {};
|
|
12
|
+
var newCursorData = _objectSpread(_objectSpread(_objectSpread({}, oldCursor), location), cursorData);
|
|
18
13
|
editor.cursors[clientId] = newCursorData;
|
|
19
14
|
} else {
|
|
20
15
|
delete editor.cursors[clientId];
|
package/dist/basic-sdk/editor.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
|
2
|
-
import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
|
|
3
2
|
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
|
4
|
-
import { Node
|
|
3
|
+
import { Node } from '@seafile/slate';
|
|
5
4
|
import { Editable, Slate, ReactEditor } from '@seafile/slate-react';
|
|
6
5
|
import defaultEditor, { renderLeaf, renderElement, Toolbar, ContextMenu } from './extension';
|
|
7
6
|
import { focusEditor } from './extension/core';
|
|
@@ -26,6 +25,20 @@ var SDocEditor = function SDocEditor(_ref) {
|
|
|
26
25
|
return newEditor;
|
|
27
26
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
28
27
|
}, []);
|
|
28
|
+
var _useState = useState(document.children),
|
|
29
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
30
|
+
slateValue = _useState2[0],
|
|
31
|
+
setSlateValue = _useState2[1];
|
|
32
|
+
var _useState3 = useState(false),
|
|
33
|
+
_useState4 = _slicedToArray(_useState3, 2),
|
|
34
|
+
isShowContextMenu = _useState4[0],
|
|
35
|
+
setContextMenu = _useState4[1];
|
|
36
|
+
var _useState5 = useState({}),
|
|
37
|
+
_useState6 = _slicedToArray(_useState5, 2),
|
|
38
|
+
menuPosition = _useState6[0],
|
|
39
|
+
setMenuPosition = _useState6[1];
|
|
40
|
+
var _useCursors = useCursors(editor),
|
|
41
|
+
cursors = _useCursors.cursors;
|
|
29
42
|
|
|
30
43
|
// init eventHandler
|
|
31
44
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
@@ -50,28 +63,6 @@ var SDocEditor = function SDocEditor(_ref) {
|
|
|
50
63
|
}
|
|
51
64
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
52
65
|
}, []);
|
|
53
|
-
|
|
54
|
-
// handle placeholder
|
|
55
|
-
var onDOMBeforeInput = useCallback(function (e) {
|
|
56
|
-
if (e.data && e.data !== '') {
|
|
57
|
-
var _node$;
|
|
58
|
-
var node = Editor.parent(editor, editor.selection);
|
|
59
|
-
editor.onDOMBeforeInputId = (_node$ = node[0]) === null || _node$ === void 0 ? void 0 : _node$.id;
|
|
60
|
-
setSlateValue(_toConsumableArray(slateValue));
|
|
61
|
-
} else {
|
|
62
|
-
editor.onDOMBeforeInputId = null;
|
|
63
|
-
setSlateValue(_toConsumableArray(slateValue));
|
|
64
|
-
}
|
|
65
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
66
|
-
}, []);
|
|
67
|
-
var _useState = useState(false),
|
|
68
|
-
_useState2 = _slicedToArray(_useState, 2),
|
|
69
|
-
isShowContextMenu = _useState2[0],
|
|
70
|
-
setContextMenu = _useState2[1];
|
|
71
|
-
var _useState3 = useState({}),
|
|
72
|
-
_useState4 = _slicedToArray(_useState3, 2),
|
|
73
|
-
menuPosition = _useState4[0],
|
|
74
|
-
setMenuPosition = _useState4[1];
|
|
75
66
|
var onContextMenu = useCallback(function (event) {
|
|
76
67
|
if (editor.isAllInTable()) {
|
|
77
68
|
event.preventDefault();
|
|
@@ -84,17 +75,11 @@ var SDocEditor = function SDocEditor(_ref) {
|
|
|
84
75
|
}
|
|
85
76
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
86
77
|
}, []);
|
|
87
|
-
var _useState5 = useState(document.children),
|
|
88
|
-
_useState6 = _slicedToArray(_useState5, 2),
|
|
89
|
-
slateValue = _useState6[0],
|
|
90
|
-
setSlateValue = _useState6[1];
|
|
91
78
|
var onChange = useCallback(function (slateValue) {
|
|
92
79
|
setSlateValue(slateValue);
|
|
93
80
|
setContextMenu(false);
|
|
94
81
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
95
82
|
}, []);
|
|
96
|
-
var _useCursors = useCursors(editor),
|
|
97
|
-
cursors = _useCursors.cursors;
|
|
98
83
|
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
|
|
99
84
|
className: "sdoc-editor-container"
|
|
100
85
|
}, /*#__PURE__*/React.createElement(Toolbar, {
|
|
@@ -116,7 +101,6 @@ var SDocEditor = function SDocEditor(_ref) {
|
|
|
116
101
|
renderElement: renderElement,
|
|
117
102
|
renderLeaf: renderLeaf,
|
|
118
103
|
onKeyDown: eventProxy.onKeyDown,
|
|
119
|
-
onDOMBeforeInput: onDOMBeforeInput,
|
|
120
104
|
cursors: cursors,
|
|
121
105
|
onContextMenu: onContextMenu
|
|
122
106
|
})))))), isShowContextMenu && /*#__PURE__*/React.createElement(ContextMenu, {
|
|
@@ -4,13 +4,14 @@ import { Placeholder } from '../../core';
|
|
|
4
4
|
var renderHeader = function renderHeader(props, editor) {
|
|
5
5
|
var element = props.element,
|
|
6
6
|
attributes = props.attributes,
|
|
7
|
-
children = props.children
|
|
7
|
+
children = props.children,
|
|
8
|
+
isComposing = props.isComposing;
|
|
8
9
|
var type = element.type;
|
|
9
10
|
var level = type.split('header')[1];
|
|
10
11
|
var Tag = "h".concat(level);
|
|
11
12
|
var isShowPlaceHolder = false;
|
|
12
13
|
var firstChild = editor.children[0];
|
|
13
|
-
if (firstChild.id === element.id && Node.string(element) === '' &&
|
|
14
|
+
if (firstChild.id === element.id && Node.string(element) === '' && !isComposing) {
|
|
14
15
|
isShowPlaceHolder = true;
|
|
15
16
|
}
|
|
16
17
|
return /*#__PURE__*/React.createElement(Tag, Object.assign({
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
|
2
2
|
import React from 'react';
|
|
3
|
-
import { Node
|
|
3
|
+
import { Node } from '@seafile/slate';
|
|
4
4
|
import { useSlateStatic } from '@seafile/slate-react';
|
|
5
5
|
import { BLOCKQUOTE, LINK, CHECK_LIST_ITEM, HEADER1, HEADER2, HEADER3, HEADER4, HEADER5, HEADER6, LIST_ITEM, LIST_LIC, ORDERED_LIST, PARAGRAPH, UNORDERED_LIST, CODE_BLOCK, IMAGE, ELEMENT_TYPE } from '../constants';
|
|
6
6
|
import { BlockquotePlugin, LinkPlugin, CheckListPlugin, HeaderPlugin, ListPlugin, CodeBlockPlugin, ImagePlugin, TablePlugin } from '../plugins';
|
|
7
|
-
import { Placeholder
|
|
7
|
+
import { Placeholder } from '../core';
|
|
8
8
|
var CustomElement = function CustomElement(props) {
|
|
9
9
|
var editor = useSlateStatic();
|
|
10
10
|
var attributes = props.attributes,
|
|
@@ -14,22 +14,13 @@ var CustomElement = function CustomElement(props) {
|
|
|
14
14
|
case PARAGRAPH:
|
|
15
15
|
{
|
|
16
16
|
var isShowPlaceHolder = false;
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
if (firstParagraphNode) {
|
|
25
|
-
var _firstParagraphNode = _slicedToArray(firstParagraphNode, 2),
|
|
26
|
-
node = _firstParagraphNode[0],
|
|
27
|
-
path = _firstParagraphNode[1];
|
|
28
|
-
var nextNode = Editor.next(editor, {
|
|
29
|
-
at: path
|
|
30
|
-
});
|
|
31
|
-
isShowPlaceHolder = (node === null || node === void 0 ? void 0 : node.id) === (element === null || element === void 0 ? void 0 : element.id) && Node.string(element) === '' && !nextNode && (editor === null || editor === void 0 ? void 0 : editor.onDOMBeforeInputId) !== (element === null || element === void 0 ? void 0 : element.id);
|
|
32
|
-
}
|
|
17
|
+
var isComposing = props.isComposing;
|
|
18
|
+
if (editor.children.length === 1) {
|
|
19
|
+
isShowPlaceHolder = Node.string(element) === '' && !isComposing;
|
|
20
|
+
}
|
|
21
|
+
if (editor.children.length === 2 && editor.children[0].type.startsWith('header')) {
|
|
22
|
+
var node = editor.children[1];
|
|
23
|
+
isShowPlaceHolder = Node.string(element) === '' && (node === null || node === void 0 ? void 0 : node.id) === (element === null || element === void 0 ? void 0 : element.id) && !isComposing;
|
|
33
24
|
}
|
|
34
25
|
return /*#__PURE__*/React.createElement("p", Object.assign({
|
|
35
26
|
"data-id": element.id
|
|
@@ -251,7 +251,7 @@ export var reExecRevertOperationList = function reExecRevertOperationList(editor
|
|
|
251
251
|
_loop2();
|
|
252
252
|
}
|
|
253
253
|
};
|
|
254
|
-
export var syncRemoteOperations = function syncRemoteOperations(editor, remoteOperations
|
|
254
|
+
export var syncRemoteOperations = function syncRemoteOperations(editor, remoteOperations) {
|
|
255
255
|
if (remoteOperations.length === 0) return;
|
|
256
256
|
Editor.withoutNormalizing(editor, function () {
|
|
257
257
|
for (var i = 0; i < remoteOperations.length; i++) {
|
|
@@ -261,11 +261,14 @@ export var syncRemoteOperations = function syncRemoteOperations(editor, remoteOp
|
|
|
261
261
|
}
|
|
262
262
|
editor.apply(op);
|
|
263
263
|
}
|
|
264
|
-
var currentUser = editor.user;
|
|
265
|
-
if (user && user.username !== currentUser.username) {
|
|
266
|
-
setCursor(editor, remoteOperations, user, selection, cursorData);
|
|
267
|
-
// sync cursor position
|
|
268
|
-
editor.onCursor && editor.onCursor(editor.cursors);
|
|
269
|
-
}
|
|
270
264
|
});
|
|
265
|
+
};
|
|
266
|
+
export var syncRemoteCursorLocation = function syncRemoteCursorLocation(editor, user, location, cursorData) {
|
|
267
|
+
var currentUser = editor.user;
|
|
268
|
+
if (user && user.username !== currentUser.username) {
|
|
269
|
+
setCursor(editor, user, location, cursorData);
|
|
270
|
+
|
|
271
|
+
// sync cursor position
|
|
272
|
+
editor.onCursor && editor.onCursor(editor.cursors);
|
|
273
|
+
}
|
|
271
274
|
};
|
|
@@ -11,12 +11,10 @@ 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
|
|
15
|
-
cursorData = _this$config.cursorData;
|
|
14
|
+
user = _this$config.user;
|
|
16
15
|
return _objectSpread({
|
|
17
16
|
doc_uuid: docUuid,
|
|
18
|
-
user: user
|
|
19
|
-
cursor_data: cursorData
|
|
17
|
+
user: user
|
|
20
18
|
}, params);
|
|
21
19
|
};
|
|
22
20
|
this.onConnected = function () {
|
|
@@ -114,6 +112,17 @@ var SocketClient = /*#__PURE__*/_createClass(function SocketClient(config) {
|
|
|
114
112
|
}
|
|
115
113
|
});
|
|
116
114
|
};
|
|
115
|
+
this.sendCursorLocation = function (location) {
|
|
116
|
+
var cursor_data = _this.config.cursorData;
|
|
117
|
+
_this.socket.emit('update-cursor', _this.getParams({
|
|
118
|
+
location: location,
|
|
119
|
+
cursor_data: cursor_data
|
|
120
|
+
}));
|
|
121
|
+
};
|
|
122
|
+
this.receiveCursorLocation = function (params) {
|
|
123
|
+
var socketManager = SocketManager.getInstance();
|
|
124
|
+
socketManager.receiveCursorLocation(params);
|
|
125
|
+
};
|
|
117
126
|
this.disconnectWithServer = function () {
|
|
118
127
|
_this.socket.disconnect();
|
|
119
128
|
};
|
|
@@ -131,6 +140,7 @@ var SocketClient = /*#__PURE__*/_createClass(function SocketClient(config) {
|
|
|
131
140
|
this.socket.on('join-room', this.onJoinRoom);
|
|
132
141
|
this.socket.on('leave-room', this.onLeaveRoom);
|
|
133
142
|
this.socket.on('update-document', this.receiveOperations);
|
|
143
|
+
this.socket.on('update-cursor', this.receiveCursorLocation);
|
|
134
144
|
this.socket.io.on('reconnect', this.onReconnect);
|
|
135
145
|
this.socket.io.on('reconnect_attempt', this.onReconnectAttempt);
|
|
136
146
|
this.socket.io.on('reconnect_error', this.onReconnectError);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import _createClass from "@babel/runtime/helpers/esm/createClass";
|
|
2
2
|
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
|
|
3
3
|
import EventBus from '../utils/event-bus';
|
|
4
|
-
import { syncRemoteOperations, reExecRevertOperationList, revertOperationList } from './helpers';
|
|
4
|
+
import { syncRemoteOperations, reExecRevertOperationList, revertOperationList, syncRemoteCursorLocation } from './helpers';
|
|
5
5
|
import SocketClient from './socket-client';
|
|
6
6
|
import debug from '../utils/debug';
|
|
7
7
|
import { deleteCursor } from '../cursor/helper';
|
|
@@ -85,13 +85,10 @@ var SocketManager = /*#__PURE__*/_createClass(function SocketManager(editor, doc
|
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
// 2. execute operations
|
|
88
|
-
var operations = params.operations
|
|
89
|
-
user = params.user,
|
|
90
|
-
selection = params.selection,
|
|
91
|
-
cursorData = params.cursor_data;
|
|
88
|
+
var operations = params.operations;
|
|
92
89
|
// 2.1 Update content & version
|
|
93
90
|
debug('execute remote operations: %O', operations);
|
|
94
|
-
syncRemoteOperations(_this.editor, operations
|
|
91
|
+
syncRemoteOperations(_this.editor, operations);
|
|
95
92
|
|
|
96
93
|
// 2.2 Update document
|
|
97
94
|
_this.document.version = serverVersion;
|
|
@@ -161,6 +158,16 @@ var SocketManager = /*#__PURE__*/_createClass(function SocketManager(editor, doc
|
|
|
161
158
|
_this.editor.isRemote = false;
|
|
162
159
|
});
|
|
163
160
|
};
|
|
161
|
+
this.sendCursorLocation = function (location) {
|
|
162
|
+
_this.socketClient.sendCursorLocation(location);
|
|
163
|
+
};
|
|
164
|
+
this.receiveCursorLocation = function (params) {
|
|
165
|
+
var user = params.user,
|
|
166
|
+
location = params.location,
|
|
167
|
+
cursorData = params.cursor_data;
|
|
168
|
+
syncRemoteCursorLocation(_this.editor, user, location, cursorData);
|
|
169
|
+
return;
|
|
170
|
+
};
|
|
164
171
|
this.dispatchConnectState = function (type, message) {
|
|
165
172
|
if (type === 'leave-room') {
|
|
166
173
|
deleteCursor(_this.editor, message);
|
|
@@ -20,8 +20,18 @@ var withSocketIO = function withSocketIO(editor, options) {
|
|
|
20
20
|
newEditor.onChange = function () {
|
|
21
21
|
var operations = newEditor.operations;
|
|
22
22
|
if (!newEditor.isRemote && operations.length > 0) {
|
|
23
|
+
var isAllSetSelection = operations.every(function (operation) {
|
|
24
|
+
return operation.type === 'set_selection';
|
|
25
|
+
});
|
|
23
26
|
var _socketManager = SocketManager.getInstance();
|
|
24
|
-
|
|
27
|
+
if (!isAllSetSelection) {
|
|
28
|
+
// get update content value operations
|
|
29
|
+
var updateOperations = operations.filter(function (operation) {
|
|
30
|
+
return operation.type !== 'set_selection';
|
|
31
|
+
});
|
|
32
|
+
_socketManager.addOperations && _socketManager.addOperations(updateOperations);
|
|
33
|
+
}
|
|
34
|
+
_socketManager.sendCursorLocation(editor.selection);
|
|
25
35
|
}
|
|
26
36
|
onChange();
|
|
27
37
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@seafile/sdoc-editor",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.52",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "This is a sdoc editor",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"@seafile/slate": "0.91.8",
|
|
10
10
|
"@seafile/slate-history": "0.86.2",
|
|
11
11
|
"@seafile/slate-hyperscript": "0.81.7",
|
|
12
|
-
"@seafile/slate-react": "0.92.
|
|
12
|
+
"@seafile/slate-react": "0.92.6",
|
|
13
13
|
"ahooks": "3.7.7",
|
|
14
14
|
"classnames": "2.3.2",
|
|
15
15
|
"deep-copy": "1.4.2",
|