@seafile/sdoc-editor 0.1.47 → 0.1.48
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 +0 -4
- package/dist/basic-sdk/editor.js +11 -16
- package/dist/basic-sdk/extension/plugins/text-style/render-elem.js +1 -6
- package/dist/basic-sdk/outline.js +3 -1
- package/dist/basic-sdk/socket/helpers.js +4 -16
- package/dist/basic-sdk/socket/socket-client.js +4 -7
- package/dist/basic-sdk/socket/socket-manager.js +3 -12
- package/dist/basic-sdk/socket/with-socket-io.js +3 -4
- package/dist/components/doc-operations/style.css +1 -0
- package/dist/pages/simple-editor.js +1 -2
- package/package.json +1 -2
- package/dist/basic-sdk/cursor/decorate.js +0 -35
- package/dist/basic-sdk/cursor/helper.js +0 -43
- package/dist/basic-sdk/extension/plugins/text-style/caret.js +0 -47
package/dist/basic-sdk/editor.js
CHANGED
|
@@ -7,13 +7,12 @@ import React from 'react';
|
|
|
7
7
|
import { Node } from '@seafile/slate';
|
|
8
8
|
import { Editable, Slate, ReactEditor } from '@seafile/slate-react';
|
|
9
9
|
import { Editor } from '@seafile/slate';
|
|
10
|
-
import editor, { renderLeaf
|
|
10
|
+
import editor, { renderLeaf, renderElement, Toolbar } from './extension';
|
|
11
11
|
import { withSocketIO } from './socket';
|
|
12
12
|
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 { getDecorate } from './cursor/decorate';
|
|
17
16
|
import './assets/css/layout.css';
|
|
18
17
|
import './assets/css/sdoc-editor-plugins.css';
|
|
19
18
|
var SDocEditor = /*#__PURE__*/function (_React$Component) {
|
|
@@ -46,9 +45,7 @@ var SDocEditor = /*#__PURE__*/function (_React$Component) {
|
|
|
46
45
|
});
|
|
47
46
|
}
|
|
48
47
|
};
|
|
49
|
-
var
|
|
50
|
-
children = _props$document.children,
|
|
51
|
-
cursors = _props$document.cursors;
|
|
48
|
+
var children = props.document.children;
|
|
52
49
|
_this.state = {
|
|
53
50
|
slateValue: children,
|
|
54
51
|
isLoading: true
|
|
@@ -63,8 +60,13 @@ var SDocEditor = /*#__PURE__*/function (_React$Component) {
|
|
|
63
60
|
config: config
|
|
64
61
|
});
|
|
65
62
|
}
|
|
66
|
-
_this.editor.cursors = cursors;
|
|
67
63
|
_this.eventProxy = new EventProxy(_this.editor);
|
|
64
|
+
_this.renderElement = function (props) {
|
|
65
|
+
return renderElement(props, _this.editor);
|
|
66
|
+
};
|
|
67
|
+
_this.renderLeaf = function (props) {
|
|
68
|
+
return renderLeaf(props, _this.editor);
|
|
69
|
+
};
|
|
68
70
|
return _this;
|
|
69
71
|
}
|
|
70
72
|
_createClass(SDocEditor, [{
|
|
@@ -84,11 +86,9 @@ var SDocEditor = /*#__PURE__*/function (_React$Component) {
|
|
|
84
86
|
}, {
|
|
85
87
|
key: "render",
|
|
86
88
|
value: function render() {
|
|
87
|
-
var _this2 = this;
|
|
88
89
|
var slateValue = this.state.slateValue;
|
|
89
90
|
var config = this.props.config;
|
|
90
91
|
var docUuid = config.docUuid;
|
|
91
|
-
var decorate = getDecorate(this.editor);
|
|
92
92
|
return /*#__PURE__*/React.createElement("div", {
|
|
93
93
|
className: "sdoc-editor-container"
|
|
94
94
|
}, /*#__PURE__*/React.createElement(Toolbar, {
|
|
@@ -107,15 +107,10 @@ var SDocEditor = /*#__PURE__*/function (_React$Component) {
|
|
|
107
107
|
}, /*#__PURE__*/React.createElement("div", {
|
|
108
108
|
className: "article"
|
|
109
109
|
}, /*#__PURE__*/React.createElement(Editable, {
|
|
110
|
-
renderElement:
|
|
111
|
-
|
|
112
|
-
},
|
|
113
|
-
renderLeaf: function renderLeaf(props) {
|
|
114
|
-
return _renderLeaf(props, _this2.editor);
|
|
115
|
-
},
|
|
110
|
+
renderElement: this.renderElement,
|
|
111
|
+
renderLeaf: this.renderLeaf,
|
|
116
112
|
onKeyDown: this.eventProxy.onKeyDown,
|
|
117
|
-
onDOMBeforeInput: this.onDOMBeforeInput
|
|
118
|
-
decorate: decorate
|
|
113
|
+
onDOMBeforeInput: this.onDOMBeforeInput
|
|
119
114
|
}))))));
|
|
120
115
|
}
|
|
121
116
|
}]);
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import Caret from './caret';
|
|
3
2
|
var renderText = function renderText(props, editor) {
|
|
4
3
|
var attributes = props.attributes,
|
|
5
4
|
children = props.children,
|
|
@@ -41,10 +40,6 @@ var renderText = function renderText(props, editor) {
|
|
|
41
40
|
}
|
|
42
41
|
return /*#__PURE__*/React.createElement("span", Object.assign({
|
|
43
42
|
"data-id": leaf.id
|
|
44
|
-
}, attributes,
|
|
45
|
-
style: {
|
|
46
|
-
position: 'relative'
|
|
47
|
-
}
|
|
48
|
-
}), leaf.isCaret ? /*#__PURE__*/React.createElement(Caret, leaf) : null, markedChildren);
|
|
43
|
+
}, attributes), markedChildren);
|
|
49
44
|
};
|
|
50
45
|
export default renderText;
|
|
@@ -115,7 +115,9 @@ var OutlineItem = /*#__PURE__*/function (_React$PureComponent2) {
|
|
|
115
115
|
onClick: this.onItemClick,
|
|
116
116
|
onMouseOver: this.onMouseOver,
|
|
117
117
|
onMouseOut: this.onMouseOut
|
|
118
|
-
}, children
|
|
118
|
+
}, children.map(function (child) {
|
|
119
|
+
return child.text;
|
|
120
|
+
}).join(''));
|
|
119
121
|
}
|
|
120
122
|
}]);
|
|
121
123
|
return OutlineItem;
|
|
@@ -3,8 +3,6 @@ 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';
|
|
8
6
|
export var getNodePathById = function getNodePathById(rootNode, nodeId) {
|
|
9
7
|
var path = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
|
|
10
8
|
if (rootNode.id === nodeId) return path;
|
|
@@ -252,21 +250,11 @@ export var reExecRevertOperationList = function reExecRevertOperationList(editor
|
|
|
252
250
|
_loop2();
|
|
253
251
|
}
|
|
254
252
|
};
|
|
255
|
-
export var syncRemoteOperations = function syncRemoteOperations(editor, remoteOperations
|
|
253
|
+
export var syncRemoteOperations = function syncRemoteOperations(editor, remoteOperations) {
|
|
256
254
|
if (remoteOperations.length === 0) return;
|
|
257
255
|
Editor.withoutNormalizing(editor, function () {
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
continue;
|
|
262
|
-
}
|
|
263
|
-
editor.apply(op);
|
|
264
|
-
}
|
|
265
|
-
var username = context.getSetting('username');
|
|
266
|
-
if (user && user.username !== username) {
|
|
267
|
-
setCursor(editor, remoteOperations, user, selection, cursorData);
|
|
268
|
-
// sync cursor position
|
|
269
|
-
editor.onChange();
|
|
270
|
-
}
|
|
256
|
+
remoteOperations.forEach(function (item) {
|
|
257
|
+
editor.apply(item);
|
|
258
|
+
});
|
|
271
259
|
});
|
|
272
260
|
};
|
|
@@ -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 () {
|
|
@@ -78,14 +76,13 @@ var SocketClient = /*#__PURE__*/_createClass(function SocketClient(config) {
|
|
|
78
76
|
var socketManager = SocketManager.getInstance();
|
|
79
77
|
socketManager.dispatchConnectState('leave-room', username);
|
|
80
78
|
};
|
|
81
|
-
this.sendOperations = function (operations, version,
|
|
79
|
+
this.sendOperations = function (operations, version, callback) {
|
|
82
80
|
debug('=========== send operations ==========');
|
|
83
81
|
debug('%O', operations);
|
|
84
82
|
debug('======================================');
|
|
85
83
|
_this.socket.emit('update-document', _this.getParams({
|
|
86
84
|
operations: operations,
|
|
87
|
-
version: version
|
|
88
|
-
selection: selection
|
|
85
|
+
version: version
|
|
89
86
|
}), function (result) {
|
|
90
87
|
callback && callback(result);
|
|
91
88
|
});
|
|
@@ -4,7 +4,6 @@ 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';
|
|
8
7
|
var SocketManager = /*#__PURE__*/_createClass(function SocketManager(editor, document, config) {
|
|
9
8
|
var _this = this;
|
|
10
9
|
_classCallCheck(this, SocketManager);
|
|
@@ -29,8 +28,7 @@ var SocketManager = /*#__PURE__*/_createClass(function SocketManager(editor, doc
|
|
|
29
28
|
_this.dispatchConnectState('is-saving');
|
|
30
29
|
var version = _this.document.version;
|
|
31
30
|
var operations = _this.pendingOperationList.shift();
|
|
32
|
-
|
|
33
|
-
_this.socketClient.sendOperations(operations, version, selection, _this.sendOperationsCallback);
|
|
31
|
+
_this.socketClient.sendOperations(operations, version, _this.sendOperationsCallback);
|
|
34
32
|
};
|
|
35
33
|
this.sendOperationsCallback = function (result) {
|
|
36
34
|
if (result && result.success) {
|
|
@@ -85,13 +83,10 @@ var SocketManager = /*#__PURE__*/_createClass(function SocketManager(editor, doc
|
|
|
85
83
|
}
|
|
86
84
|
|
|
87
85
|
// 2. execute operations
|
|
88
|
-
var operations = params.operations
|
|
89
|
-
user = params.user,
|
|
90
|
-
selection = params.selection,
|
|
91
|
-
cursorData = params.cursor_data;
|
|
86
|
+
var operations = params.operations;
|
|
92
87
|
// 2.1 Update content & version
|
|
93
88
|
debug('execute remote operations: %O', operations);
|
|
94
|
-
syncRemoteOperations(_this.editor, operations
|
|
89
|
+
syncRemoteOperations(_this.editor, operations);
|
|
95
90
|
|
|
96
91
|
// 2.2 Update document
|
|
97
92
|
_this.document.version = serverVersion;
|
|
@@ -162,10 +157,6 @@ var SocketManager = /*#__PURE__*/_createClass(function SocketManager(editor, doc
|
|
|
162
157
|
});
|
|
163
158
|
};
|
|
164
159
|
this.dispatchConnectState = function (type, message) {
|
|
165
|
-
if (type === 'leave-room') {
|
|
166
|
-
deleteCursor(_this.editor, message);
|
|
167
|
-
_this.editor.onChange();
|
|
168
|
-
}
|
|
169
160
|
_this.eventBus.dispatch(type, message);
|
|
170
161
|
};
|
|
171
162
|
this.closeSocketConnect = function () {
|
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
var _this = this;
|
|
2
|
-
import { generateCursorData } from '../cursor/helper';
|
|
3
2
|
import SocketManager from './socket-manager';
|
|
4
3
|
var withSocketIO = function withSocketIO(editor, options) {
|
|
5
4
|
var onChange = editor.onChange;
|
|
6
5
|
var newEditor = editor;
|
|
7
|
-
var cursorData = generateCursorData(options.config);
|
|
8
6
|
var socketManager = null;
|
|
9
7
|
newEditor.openConnection = function () {
|
|
10
8
|
var document = options.document,
|
|
11
9
|
config = options.config;
|
|
12
|
-
config['cursorData'] = cursorData;
|
|
13
10
|
socketManager = SocketManager.getInstance(newEditor, document, config);
|
|
14
11
|
};
|
|
15
12
|
newEditor.closeConnection = function () {
|
|
@@ -17,7 +14,9 @@ var withSocketIO = function withSocketIO(editor, options) {
|
|
|
17
14
|
};
|
|
18
15
|
newEditor.onChange = function () {
|
|
19
16
|
var operations = newEditor.operations;
|
|
20
|
-
|
|
17
|
+
operations = operations.filter(function (item) {
|
|
18
|
+
return item.type !== 'set_selection';
|
|
19
|
+
});
|
|
21
20
|
if (!newEditor.isRemote && operations.length > 0) {
|
|
22
21
|
var _socketManager = SocketManager.getInstance();
|
|
23
22
|
_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.48",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "This is a sdoc editor",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -14,7 +14,6 @@
|
|
|
14
14
|
"deep-copy": "1.4.2",
|
|
15
15
|
"is-hotkey": "0.2.0",
|
|
16
16
|
"is-url": "^1.2.4",
|
|
17
|
-
"randomcolor": "0.6.2",
|
|
18
17
|
"react-cookies": "0.1.1",
|
|
19
18
|
"reactstrap": "8.9.0",
|
|
20
19
|
"slugid": "3.2.0",
|
|
@@ -1,35 +0,0 @@
|
|
|
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 getDecorate = function getDecorate(editor) {
|
|
5
|
-
return function (nodeEntry) {
|
|
6
|
-
var ranges = [];
|
|
7
|
-
var _nodeEntry = _slicedToArray(nodeEntry, 2),
|
|
8
|
-
node = _nodeEntry[0],
|
|
9
|
-
path = _nodeEntry[1];
|
|
10
|
-
var cursors = Object.values(editor.cursors || {});
|
|
11
|
-
if (Text.isText(node) && (cursors === null || cursors === void 0 ? void 0 : cursors.length)) {
|
|
12
|
-
cursors.forEach(function (cursor) {
|
|
13
|
-
if (Range.includes(cursor, path)) {
|
|
14
|
-
var focus = cursor.focus,
|
|
15
|
-
anchor = cursor.anchor,
|
|
16
|
-
isForward = cursor.isForward;
|
|
17
|
-
var isFocusNode = Path.equals(focus.path, path);
|
|
18
|
-
var isAnchorNode = Path.equals(anchor.path, path);
|
|
19
|
-
ranges.push(_objectSpread(_objectSpread({}, cursor), {}, {
|
|
20
|
-
isCaret: isFocusNode,
|
|
21
|
-
anchor: {
|
|
22
|
-
path: path,
|
|
23
|
-
offset: isAnchorNode ? anchor.offset : isForward ? 0 : node.text.length
|
|
24
|
-
},
|
|
25
|
-
focus: {
|
|
26
|
-
path: path,
|
|
27
|
-
offset: isFocusNode ? focus.offset : isForward ? node.text.length : 0
|
|
28
|
-
}
|
|
29
|
-
}));
|
|
30
|
-
}
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
return ranges;
|
|
34
|
-
};
|
|
35
|
-
};
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
2
|
-
import { Range } from '@seafile/slate';
|
|
3
|
-
import randomColor from 'randomcolor';
|
|
4
|
-
|
|
5
|
-
// selection: { anchor, focus }
|
|
6
|
-
// cursor: { anchor, focus }
|
|
7
|
-
|
|
8
|
-
export var setCursor = function setCursor(editor, operations, user, selection, cursorData) {
|
|
9
|
-
var clientId = user.username;
|
|
10
|
-
var cursorOps = operations.filter(function (operation) {
|
|
11
|
-
return operation.type === 'set_selection';
|
|
12
|
-
});
|
|
13
|
-
if (!editor.cursors) editor.cursors = {};
|
|
14
|
-
var oldCursor = editor.cursors[clientId] ? editor.cursors[clientId] : {};
|
|
15
|
-
var lastCursorOp = cursorOps[cursorOps.length - 1];
|
|
16
|
-
if (selection) {
|
|
17
|
-
var newCursor = lastCursorOp && lastCursorOp.newProperties || {};
|
|
18
|
-
var newCursorData = _objectSpread(_objectSpread(_objectSpread(_objectSpread({}, oldCursor), newCursor), selection), _objectSpread(_objectSpread({}, cursorData), {}, {
|
|
19
|
-
isForward: Range.isForward(selection)
|
|
20
|
-
}));
|
|
21
|
-
editor.cursors[clientId] = newCursorData;
|
|
22
|
-
} else {
|
|
23
|
-
delete editor.cursors[clientId];
|
|
24
|
-
}
|
|
25
|
-
return editor;
|
|
26
|
-
};
|
|
27
|
-
export var deleteCursor = function deleteCursor(editor, username) {
|
|
28
|
-
delete editor.cursors[username];
|
|
29
|
-
};
|
|
30
|
-
export var generateCursorData = function generateCursorData(config) {
|
|
31
|
-
var user = config.user;
|
|
32
|
-
var options = {
|
|
33
|
-
luminosity: 'dark',
|
|
34
|
-
format: 'rgba',
|
|
35
|
-
alpha: 1
|
|
36
|
-
};
|
|
37
|
-
var color = randomColor(options);
|
|
38
|
-
return {
|
|
39
|
-
name: user.name,
|
|
40
|
-
color: color,
|
|
41
|
-
alphaColor: color.slice(0, -2) + '0.2)'
|
|
42
|
-
};
|
|
43
|
-
};
|
|
@@ -1,47 +0,0 @@
|
|
|
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
|
-
isForward = _ref.isForward,
|
|
25
|
-
name = _ref.name;
|
|
26
|
-
var cursorStyles = _objectSpread(_objectSpread({}, cursorStyleBase), {}, {
|
|
27
|
-
background: color,
|
|
28
|
-
left: isForward ? '100%' : '0%'
|
|
29
|
-
});
|
|
30
|
-
var caretStyles = _objectSpread(_objectSpread({}, caretStyleBase), {}, {
|
|
31
|
-
background: color,
|
|
32
|
-
left: isForward ? '100%' : '0%'
|
|
33
|
-
});
|
|
34
|
-
caretStyles[isForward ? 'bottom' : 'top'] = 0;
|
|
35
|
-
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("span", {
|
|
36
|
-
contentEditable: false,
|
|
37
|
-
style: caretStyles
|
|
38
|
-
}, /*#__PURE__*/React.createElement("span", {
|
|
39
|
-
style: {
|
|
40
|
-
position: 'relative'
|
|
41
|
-
}
|
|
42
|
-
}, /*#__PURE__*/React.createElement("span", {
|
|
43
|
-
contentEditable: false,
|
|
44
|
-
style: cursorStyles
|
|
45
|
-
}, name))));
|
|
46
|
-
};
|
|
47
|
-
export default Caret;
|