@seafile/sdoc-editor 0.1.2 → 0.1.4
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/assets/css/textlink-hovermenu.css +51 -0
- package/dist/config.js +16 -0
- package/dist/editor.js +13 -20
- package/dist/{slate-extension → extension}/constants/index.js +4 -0
- package/dist/{slate-extension → extension}/core/queries/index.js +44 -15
- package/dist/{slate-extension → extension}/core/transforms/focus-editor.js +2 -2
- package/dist/extension/core/transforms/index.js +3 -0
- package/dist/{slate-extension → extension}/core/transforms/move-children.js +1 -1
- package/dist/extension/core/transforms/remove-node-children.js +24 -0
- package/dist/{slate-extension → extension}/core/utils/index.js +10 -0
- package/dist/{slate-extension → extension}/index.js +2 -2
- package/dist/{slate-extension → extension}/plugins/blockquote/helpers.js +1 -1
- package/dist/{slate-extension → extension}/plugins/blockquote/menu/index.js +1 -2
- package/dist/{slate-extension → extension}/plugins/blockquote/plugin.js +5 -9
- package/dist/extension/plugins/blockquote/render-elem.js +10 -0
- package/dist/{slate-extension → extension}/plugins/check-list/helpers.js +1 -1
- package/dist/{slate-extension → extension}/plugins/check-list/plugin.js +1 -1
- package/dist/{slate-extension → extension}/plugins/check-list/render-elem.js +5 -3
- package/dist/{slate-extension → extension}/plugins/header/helpers.js +1 -1
- package/dist/{slate-extension → extension}/plugins/header/plugin.js +4 -7
- package/dist/{slate-extension → extension}/plugins/header/render-elem.js +3 -1
- package/dist/extension/plugins/index.js +9 -0
- package/dist/extension/plugins/link/helpers.js +152 -0
- package/dist/extension/plugins/link/index.js +14 -0
- package/dist/extension/plugins/link/menu/add-link-dialog.js +146 -0
- package/dist/extension/plugins/link/menu/hover-link-dialog.js +49 -0
- package/dist/extension/plugins/link/menu/index.js +67 -0
- package/dist/extension/plugins/link/model.js +13 -0
- package/dist/extension/plugins/link/plugin.js +60 -0
- package/dist/extension/plugins/link/render-elem.js +114 -0
- package/dist/{slate-extension → extension}/plugins/list/helpers.js +1 -1
- package/dist/{slate-extension → extension}/plugins/list/menu/index.js +1 -1
- package/dist/{slate-extension → extension}/plugins/list/plugin/normalize-list.js +1 -1
- package/dist/{slate-extension → extension}/plugins/list/plugin/on-tab-handle.js +1 -1
- package/dist/{slate-extension → extension}/plugins/list/queries/index.js +1 -1
- package/dist/{slate-extension → extension}/plugins/list/render-elem.js +11 -4
- package/dist/{slate-extension → extension}/plugins/list/transforms/insert-list-item.js +17 -22
- package/dist/{slate-extension → extension}/plugins/list/transforms/move-list-item-down.js +1 -1
- package/dist/{slate-extension → extension}/plugins/list/transforms/move-list-item-up.js +1 -1
- package/dist/{slate-extension → extension}/plugins/list/transforms/move-list-items-to-list.js +1 -1
- package/dist/{slate-extension → extension}/plugins/list/transforms/move-list-items.js +1 -1
- package/dist/{slate-extension → extension}/plugins/list/transforms/normalize-list-item.js +1 -1
- package/dist/{slate-extension → extension}/plugins/list/transforms/normalize-nested-list.js +1 -1
- package/dist/{slate-extension → extension}/plugins/list/transforms/toggle-list.js +1 -1
- package/dist/{slate-extension → extension}/plugins/list/transforms/unwrap-list.js +1 -1
- package/dist/{slate-extension → extension}/plugins/text-style/render-elem.js +3 -1
- package/dist/{slate-extension → extension}/render/render-element.js +14 -4
- package/dist/{slate-extension → extension}/toolbar/index.js +4 -1
- package/dist/index.js +2 -1
- package/dist/node-id/constants.js +18 -0
- package/dist/node-id/helpers.js +80 -0
- package/dist/node-id/index.js +11 -0
- package/dist/socket/helpers.js +258 -0
- package/dist/socket/index.js +3 -0
- package/dist/socket/socket-client.js +138 -0
- package/dist/socket/socket-manager.js +180 -0
- package/dist/socket/with-socket-io.js +18 -0
- package/dist/viewer.js +81 -0
- package/package.json +9 -6
- package/public/locales/en/seafile-editor.json +4 -1
- package/public/locales/zh-CN/seafile-editor.json +4 -1
- package/dist/slate-extension/core/transforms/index.js +0 -2
- package/dist/slate-extension/plugins/blockquote/render-elem.js +0 -7
- package/dist/slate-extension/plugins/index.js +0 -9
- package/dist/slate-extension/plugins/socket/index.js +0 -6
- package/dist/slate-extension/plugins/socket/plugin.js +0 -23
- package/dist/slate-extension/socket/socket-client.js +0 -94
- package/dist/slate-extension/socket/socket-manager.js +0 -63
- /package/dist/{slate-extension → extension}/core/index.js +0 -0
- /package/dist/{slate-extension → extension}/menu/index.js +0 -0
- /package/dist/{slate-extension → extension}/menu/menu-group.js +0 -0
- /package/dist/{slate-extension → extension}/menu/menu-item.js +0 -0
- /package/dist/{slate-extension → extension}/menu/menu.css +0 -0
- /package/dist/{slate-extension → extension}/plugins/blockquote/index.js +0 -0
- /package/dist/{slate-extension → extension}/plugins/blockquote/model.js +0 -0
- /package/dist/{slate-extension → extension}/plugins/check-list/index.js +0 -0
- /package/dist/{slate-extension → extension}/plugins/check-list/menu/index.js +0 -0
- /package/dist/{slate-extension → extension}/plugins/check-list/model.js +0 -0
- /package/dist/{slate-extension → extension}/plugins/header/index.js +0 -0
- /package/dist/{slate-extension → extension}/plugins/header/menu/index.js +0 -0
- /package/dist/{slate-extension → extension}/plugins/list/index.js +0 -0
- /package/dist/{slate-extension → extension}/plugins/list/model.js +0 -0
- /package/dist/{slate-extension → extension}/plugins/list/plugin/index.js +0 -0
- /package/dist/{slate-extension → extension}/plugins/list/plugin/insert-break-list.js +0 -0
- /package/dist/{slate-extension → extension}/plugins/list/transforms/index.js +0 -0
- /package/dist/{slate-extension → extension}/plugins/list/transforms/remove-first-list-item.js +0 -0
- /package/dist/{slate-extension → extension}/plugins/text-style/index.js +0 -0
- /package/dist/{slate-extension → extension}/plugins/text-style/model.js +0 -0
- /package/dist/{slate-extension → extension}/render/render-leaf.js +0 -0
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
2
|
+
import _createClass from "@babel/runtime/helpers/esm/createClass";
|
|
3
|
+
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
|
|
4
|
+
import io from 'socket.io-client';
|
|
5
|
+
import Debug from 'debug';
|
|
6
|
+
import SocketManager from './socket-manager';
|
|
7
|
+
var debug = Debug('sdoc:socket-client');
|
|
8
|
+
var SocketClient = /*#__PURE__*/_createClass(function SocketClient(config) {
|
|
9
|
+
var _this = this;
|
|
10
|
+
_classCallCheck(this, SocketClient);
|
|
11
|
+
this.getParams = function () {
|
|
12
|
+
var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
13
|
+
var docUuid = _this.config.docUuid;
|
|
14
|
+
return _objectSpread({
|
|
15
|
+
doc_uuid: docUuid
|
|
16
|
+
}, params);
|
|
17
|
+
};
|
|
18
|
+
this.onConnected = function () {
|
|
19
|
+
var _this$config = _this.config,
|
|
20
|
+
doc_uuid = _this$config.docUuid,
|
|
21
|
+
doc_path = _this$config.docPath,
|
|
22
|
+
doc_name = _this$config.docName,
|
|
23
|
+
access_token = _this$config.accessToken;
|
|
24
|
+
var params = {
|
|
25
|
+
doc_uuid: doc_uuid,
|
|
26
|
+
doc_path: doc_path,
|
|
27
|
+
doc_name: doc_name,
|
|
28
|
+
access_token: access_token
|
|
29
|
+
};
|
|
30
|
+
// join room
|
|
31
|
+
_this.socket.emit('join-room', params, function (result) {
|
|
32
|
+
var socketManager = SocketManager.getInstance();
|
|
33
|
+
if (result.success) {
|
|
34
|
+
// sync operations or document
|
|
35
|
+
if (_this.isReconnect) {
|
|
36
|
+
_this.isReconnect = false;
|
|
37
|
+
var serverVersion = result.version;
|
|
38
|
+
var clientVersion = socketManager.getDocumentVersion();
|
|
39
|
+
if (serverVersion !== clientVersion) {
|
|
40
|
+
_this.syncDocumentBySocket();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
socketManager.dispatchConnectState('onConnected', result);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Disconnect the server in the client side. There will be no reconnection.
|
|
48
|
+
_this.socket.disconnect();
|
|
49
|
+
socketManager.dispatchConnectState('connect-error', result);
|
|
50
|
+
});
|
|
51
|
+
};
|
|
52
|
+
this.onReconnect = function (data) {
|
|
53
|
+
debug('reconnect.');
|
|
54
|
+
_this.isReconnect = true;
|
|
55
|
+
var socketManager = SocketManager.getInstance();
|
|
56
|
+
socketManager.dispatchConnectState('reconnect');
|
|
57
|
+
};
|
|
58
|
+
this.onReconnectAttempt = function (attemptNumber) {
|
|
59
|
+
debug('reconnect_attempt. %s', attemptNumber);
|
|
60
|
+
var socketManager = SocketManager.getInstance();
|
|
61
|
+
socketManager.dispatchConnectState('reconnect_attempt', attemptNumber);
|
|
62
|
+
};
|
|
63
|
+
this.onReconnectError = function () {
|
|
64
|
+
debug('reconnect_error. %s');
|
|
65
|
+
var socketManager = SocketManager.getInstance();
|
|
66
|
+
socketManager.dispatchConnectState('reconnect_error');
|
|
67
|
+
};
|
|
68
|
+
this.onDisconnected = function (data) {
|
|
69
|
+
debug('disconnect message: %s', data);
|
|
70
|
+
var socketManager = SocketManager.getInstance();
|
|
71
|
+
socketManager.dispatchConnectState('disconnect');
|
|
72
|
+
};
|
|
73
|
+
this.onJoinRoom = function (username) {
|
|
74
|
+
debug('%s joined room success.', username);
|
|
75
|
+
var socketManager = SocketManager.getInstance();
|
|
76
|
+
socketManager.dispatchConnectState('join-room', username);
|
|
77
|
+
};
|
|
78
|
+
this.onLeaveRoom = function (username) {
|
|
79
|
+
debug('%s leaved room success.', username);
|
|
80
|
+
var socketManager = SocketManager.getInstance();
|
|
81
|
+
socketManager.dispatchConnectState('leave-room', username);
|
|
82
|
+
};
|
|
83
|
+
this.sendOperations = function (operations, version, callback) {
|
|
84
|
+
debug('=========== send operations ==========');
|
|
85
|
+
debug('%O', operations);
|
|
86
|
+
debug('======================================');
|
|
87
|
+
_this.socket.emit('update-document', _this.getParams({
|
|
88
|
+
operations: operations,
|
|
89
|
+
version: version
|
|
90
|
+
}), function (result) {
|
|
91
|
+
callback && callback(result);
|
|
92
|
+
});
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
* receive remote broadcast operations
|
|
96
|
+
* @param {*} params {operations, version}
|
|
97
|
+
*/
|
|
98
|
+
this.receiveOperations = function (params) {
|
|
99
|
+
debug('********* receive operations *********');
|
|
100
|
+
debug('%O', params);
|
|
101
|
+
debug('**************************************');
|
|
102
|
+
var socketManager = SocketManager.getInstance();
|
|
103
|
+
socketManager.receiveOperations(params);
|
|
104
|
+
};
|
|
105
|
+
this.disconnectWithServer = function () {
|
|
106
|
+
_this.socket.disconnect();
|
|
107
|
+
};
|
|
108
|
+
this.syncDocumentBySocket = function () {
|
|
109
|
+
var docUuid = _this.config.docUuid;
|
|
110
|
+
var socketManager = SocketManager.getInstance();
|
|
111
|
+
var clientVersion = socketManager.getDocumentVersion();
|
|
112
|
+
_this.socket.emit('sync-document', {
|
|
113
|
+
doc_uuid: docUuid,
|
|
114
|
+
version: clientVersion
|
|
115
|
+
}, function (result) {
|
|
116
|
+
if (result.success) {
|
|
117
|
+
socketManager.syncDocumentBySocket(result);
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
};
|
|
121
|
+
this.config = config;
|
|
122
|
+
this.isReconnect = false;
|
|
123
|
+
this.socket = io(config.sdocServer, {
|
|
124
|
+
reconnection: true,
|
|
125
|
+
query: {
|
|
126
|
+
doc_uuid: config.docUuid
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
this.socket.on('connect', this.onConnected);
|
|
130
|
+
this.socket.on('disconnect', this.onDisconnected);
|
|
131
|
+
this.socket.on('join-room', this.onJoinRoom);
|
|
132
|
+
this.socket.on('leave-room', this.onLeaveRoom);
|
|
133
|
+
this.socket.on('update-document', this.receiveOperations);
|
|
134
|
+
this.socket.io.on('reconnect', this.onReconnect);
|
|
135
|
+
this.socket.io.on('reconnect_attempt', this.onReconnectAttempt);
|
|
136
|
+
this.socket.io.on('reconnect_error', this.onReconnectError);
|
|
137
|
+
});
|
|
138
|
+
export default SocketClient;
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import _createClass from "@babel/runtime/helpers/esm/createClass";
|
|
2
|
+
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
|
|
3
|
+
import Debug from 'debug';
|
|
4
|
+
import EventBus from '../utils/event-bus';
|
|
5
|
+
import { syncRemoteOperations, reExecRevertOperationList, revertOperationList } from './helpers';
|
|
6
|
+
import SocketClient from './socket-client';
|
|
7
|
+
var debug = Debug('sdoc:socket-client');
|
|
8
|
+
var SocketManager = /*#__PURE__*/_createClass(function SocketManager(editor, document, config) {
|
|
9
|
+
var _this = this;
|
|
10
|
+
_classCallCheck(this, SocketManager);
|
|
11
|
+
this.addOperations = function (operations) {
|
|
12
|
+
_this.pendingOperationList.push(operations);
|
|
13
|
+
_this.sendOperations();
|
|
14
|
+
};
|
|
15
|
+
this.getDocumentVersion = function () {
|
|
16
|
+
var version = _this.document.version;
|
|
17
|
+
return version;
|
|
18
|
+
};
|
|
19
|
+
this.sendOperations = function () {
|
|
20
|
+
if (_this.isSending || _this.pendingOperationList.length === 0) return;
|
|
21
|
+
_this.isSending = true;
|
|
22
|
+
_this.sendNextOperations();
|
|
23
|
+
};
|
|
24
|
+
this.sendNextOperations = function () {
|
|
25
|
+
if (_this.pendingOperationList.length === 0) {
|
|
26
|
+
_this.isSending = false;
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
var version = _this.document.version;
|
|
30
|
+
var operations = _this.pendingOperationList.shift();
|
|
31
|
+
_this.socketClient.sendOperations(operations, version, _this.sendOperationsCallback);
|
|
32
|
+
};
|
|
33
|
+
this.sendOperationsCallback = function (result) {
|
|
34
|
+
if (result && result.success) {
|
|
35
|
+
var serverVersion = result.version;
|
|
36
|
+
_this.document['version'] = serverVersion;
|
|
37
|
+
_this.sendNextOperations();
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Operations are execute failure
|
|
42
|
+
var operations = result.operations;
|
|
43
|
+
// Put the failed operation into the pending list and re-execute it
|
|
44
|
+
_this.pendingOperationList.unshift(operations);
|
|
45
|
+
_this.sendNextOperations();
|
|
46
|
+
};
|
|
47
|
+
this.receiveOperations = function (params) {
|
|
48
|
+
_this.remoteOperationsList.push(params);
|
|
49
|
+
// sort operations by version
|
|
50
|
+
if (_this.remoteOperationsList.length > 1) {
|
|
51
|
+
_this.remoteOperationsList = _this.remoteOperationsList.sort(function (prev, next) {
|
|
52
|
+
return prev.version - next.version;
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
if (_this.isExecRemoteOperations) return;
|
|
56
|
+
_this.isExecRemoteOperations = true;
|
|
57
|
+
_this.editor.isRemote = true;
|
|
58
|
+
_this.execRemoteOperations();
|
|
59
|
+
|
|
60
|
+
// reset control flag
|
|
61
|
+
Promise.resolve().then(function (_) {
|
|
62
|
+
_this.isExecRemoteOperations = false;
|
|
63
|
+
_this.editor.isRemote = false;
|
|
64
|
+
});
|
|
65
|
+
};
|
|
66
|
+
this.execRemoteOperations = function () {
|
|
67
|
+
if (_this.remoteOperationsList.length > 0) {
|
|
68
|
+
var params = _this.remoteOperationsList.shift();
|
|
69
|
+
var serverVersion = params.version;
|
|
70
|
+
var clientVersion = _this.document.version;
|
|
71
|
+
if (serverVersion === clientVersion + 1) {
|
|
72
|
+
// When performing remote operations, the revert operation is only required for the first time
|
|
73
|
+
if (_this.revertOperationList.length === 0) {
|
|
74
|
+
// 1. Revert operations
|
|
75
|
+
// 1.1 record reverted operationList & clear pendingOperationList
|
|
76
|
+
_this.revertOperationList = _this.pendingOperationList.slice();
|
|
77
|
+
_this.pendingOperationList = [];
|
|
78
|
+
|
|
79
|
+
// 1.2 Revert operationList
|
|
80
|
+
debug('revert locale operations: %O', _this.revertOperationList);
|
|
81
|
+
revertOperationList(_this.editor, _this.revertOperationList);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// 2. execute operations
|
|
85
|
+
var operations = params.operations;
|
|
86
|
+
// 2.1 Update content & version
|
|
87
|
+
debug('execute remote operations: %O', operations);
|
|
88
|
+
syncRemoteOperations(_this.editor, operations);
|
|
89
|
+
|
|
90
|
+
// 2.2 Update document
|
|
91
|
+
_this.document.version = serverVersion;
|
|
92
|
+
_this.document.children = _this.editor.children;
|
|
93
|
+
|
|
94
|
+
// Execute next operations
|
|
95
|
+
if (_this.remoteOperationsList.length > 0) {
|
|
96
|
+
_this.execRemoteOperations();
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Re-execute undone operations after isRemote is set to false
|
|
101
|
+
// Need resend this operations to server
|
|
102
|
+
Promise.resolve().then(function (_) {
|
|
103
|
+
debug('Editor isRemote is false: %s', _this.editor.isRemote);
|
|
104
|
+
debug('Re-execute pending operations, %O', _this.revertOperationList);
|
|
105
|
+
|
|
106
|
+
// 3. Execute pending operations
|
|
107
|
+
// 3.1 Re-execute operations
|
|
108
|
+
reExecRevertOperationList(_this.editor, _this.revertOperationList);
|
|
109
|
+
|
|
110
|
+
// 3.2 Clear revert operationList
|
|
111
|
+
_this.revertOperationList = [];
|
|
112
|
+
});
|
|
113
|
+
} else {
|
|
114
|
+
// conflict:
|
|
115
|
+
// remote operations is not empty, waiting until remote operations all executed
|
|
116
|
+
debug('remote operations is not empty, and local version is not match remote version.');
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
this.syncDocumentBySocket = function (result) {
|
|
121
|
+
var mode = result.mode,
|
|
122
|
+
content = result.content;
|
|
123
|
+
// sync document
|
|
124
|
+
if (mode === 'document') {
|
|
125
|
+
var version = content.version,
|
|
126
|
+
children = content.children;
|
|
127
|
+
// 1. update document
|
|
128
|
+
_this.document.children = children;
|
|
129
|
+
_this.document.version = version;
|
|
130
|
+
_this.editor.children = children;
|
|
131
|
+
_this.editor.isRemote = true;
|
|
132
|
+
_this.editor.onChange();
|
|
133
|
+
_this.editor.isRemote = false;
|
|
134
|
+
|
|
135
|
+
// 2. exec client operationList
|
|
136
|
+
var pendingOperationList = _this.pendingOperationList.slice();
|
|
137
|
+
_this.pendingOperationList = [];
|
|
138
|
+
|
|
139
|
+
// need resend this operations to server
|
|
140
|
+
debug('Editor isRemote is false: %s', _this.editor.isRemote);
|
|
141
|
+
reExecRevertOperationList(_this.editor, pendingOperationList);
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// sync operations
|
|
146
|
+
// content is [{version, operations}, {version, operations}, ...]
|
|
147
|
+
_this.remoteOperationsList = content;
|
|
148
|
+
_this.isExecRemoteOperations = true;
|
|
149
|
+
_this.editor.isRemote = true;
|
|
150
|
+
_this.execRemoteOperations();
|
|
151
|
+
|
|
152
|
+
// reset control flag
|
|
153
|
+
Promise.resolve().then(function (_) {
|
|
154
|
+
_this.isExecRemoteOperations = false;
|
|
155
|
+
_this.editor.isRemote = false;
|
|
156
|
+
});
|
|
157
|
+
};
|
|
158
|
+
this.dispatchConnectState = function (type, message) {
|
|
159
|
+
console.log(type);
|
|
160
|
+
};
|
|
161
|
+
this.editor = editor;
|
|
162
|
+
this.document = document;
|
|
163
|
+
this.socketClient = new SocketClient(config);
|
|
164
|
+
this.isSending = false;
|
|
165
|
+
this.pendingOperationList = []; // Two-dimensional arrays: [operations, operations, ...]
|
|
166
|
+
this.remoteOperationsList = []; // Same with pending operations
|
|
167
|
+
this.revertOperationList = [];
|
|
168
|
+
this.eventBus = new EventBus();
|
|
169
|
+
});
|
|
170
|
+
SocketManager.getInstance = function (editor, document, socketConfig) {
|
|
171
|
+
if (SocketManager.instance) {
|
|
172
|
+
return SocketManager.instance;
|
|
173
|
+
}
|
|
174
|
+
if (!document || !socketConfig) {
|
|
175
|
+
throw new Error('SocketManager init params is invalid. Place check your code to fix it.');
|
|
176
|
+
}
|
|
177
|
+
SocketManager.instance = new SocketManager(editor, document, socketConfig);
|
|
178
|
+
return SocketManager.instance;
|
|
179
|
+
};
|
|
180
|
+
export default SocketManager;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import SocketManager from './socket-manager';
|
|
2
|
+
var withSocketIO = function withSocketIO(editor, options) {
|
|
3
|
+
var onChange = editor.onChange;
|
|
4
|
+
var newEditor = editor;
|
|
5
|
+
newEditor.onChange = function () {
|
|
6
|
+
var operations = newEditor.operations;
|
|
7
|
+
operations = operations.filter(function (item) {
|
|
8
|
+
return item.type !== 'set_selection';
|
|
9
|
+
});
|
|
10
|
+
if (!newEditor.isRemote && operations.length > 0) {
|
|
11
|
+
var socketManager = SocketManager.getInstance();
|
|
12
|
+
socketManager.addOperations && socketManager.addOperations(operations);
|
|
13
|
+
}
|
|
14
|
+
onChange();
|
|
15
|
+
};
|
|
16
|
+
return newEditor;
|
|
17
|
+
};
|
|
18
|
+
export default withSocketIO;
|
package/dist/viewer.js
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
|
|
2
|
+
import _createClass from "@babel/runtime/helpers/esm/createClass";
|
|
3
|
+
import _inherits from "@babel/runtime/helpers/esm/inherits";
|
|
4
|
+
import _createSuper from "@babel/runtime/helpers/esm/createSuper";
|
|
5
|
+
import React from 'react';
|
|
6
|
+
import { Editable, Slate } from '@seafile/slate-react';
|
|
7
|
+
import isHotkey from 'is-hotkey';
|
|
8
|
+
import editor, { renderLeaf as _renderLeaf, renderElement as _renderElement } from './extension';
|
|
9
|
+
import { SocketManager, withSocketIO } from './socket';
|
|
10
|
+
import withNodeId from './node-id';
|
|
11
|
+
import './assets/css/sdoc-editor.css';
|
|
12
|
+
var SDocViewer = /*#__PURE__*/function (_React$Component) {
|
|
13
|
+
_inherits(SDocViewer, _React$Component);
|
|
14
|
+
var _super = _createSuper(SDocViewer);
|
|
15
|
+
function SDocViewer(props) {
|
|
16
|
+
var _this;
|
|
17
|
+
_classCallCheck(this, SDocViewer);
|
|
18
|
+
_this = _super.call(this, props);
|
|
19
|
+
var children = props.document.children;
|
|
20
|
+
_this.state = {
|
|
21
|
+
slateValue: children,
|
|
22
|
+
isLoading: true
|
|
23
|
+
};
|
|
24
|
+
_this.socketManager = null;
|
|
25
|
+
if (!props.isOpenSocket) {
|
|
26
|
+
_this.editor = withNodeId(editor);
|
|
27
|
+
} else {
|
|
28
|
+
_this.editor = withSocketIO(withNodeId(editor));
|
|
29
|
+
}
|
|
30
|
+
return _this;
|
|
31
|
+
}
|
|
32
|
+
_createClass(SDocViewer, [{
|
|
33
|
+
key: "componentDidMount",
|
|
34
|
+
value: function componentDidMount() {
|
|
35
|
+
var _this$props = this.props,
|
|
36
|
+
isOpenSocket = _this$props.isOpenSocket,
|
|
37
|
+
document = _this$props.document,
|
|
38
|
+
config = _this$props.config;
|
|
39
|
+
if (isOpenSocket) {
|
|
40
|
+
this.socketManager = SocketManager.getInstance(this.editor, document, config);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}, {
|
|
44
|
+
key: "render",
|
|
45
|
+
value: function render() {
|
|
46
|
+
var _this2 = this;
|
|
47
|
+
var slateValue = this.state.slateValue;
|
|
48
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
49
|
+
className: "sf-editor-container"
|
|
50
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
51
|
+
className: "sf-editor-content"
|
|
52
|
+
}, /*#__PURE__*/React.createElement(Slate, {
|
|
53
|
+
editor: this.editor,
|
|
54
|
+
value: slateValue,
|
|
55
|
+
onChange: function onChange() {}
|
|
56
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
57
|
+
className: "editor-article"
|
|
58
|
+
}, /*#__PURE__*/React.createElement(Editable, {
|
|
59
|
+
readOnly: true,
|
|
60
|
+
placeholder: "",
|
|
61
|
+
renderElement: function renderElement(props) {
|
|
62
|
+
return _renderElement(props, _this2.editor);
|
|
63
|
+
},
|
|
64
|
+
renderLeaf: function renderLeaf(props) {
|
|
65
|
+
return _renderLeaf(props, _this2.editor);
|
|
66
|
+
},
|
|
67
|
+
onDOMBeforeInput: function onDOMBeforeInput(event) {},
|
|
68
|
+
onKeyDown: function onKeyDown(event) {
|
|
69
|
+
if (isHotkey('tab', event) || isHotkey('shift+tab', event)) {
|
|
70
|
+
editor.handleTab && editor.handleTab(event);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
})))));
|
|
74
|
+
}
|
|
75
|
+
}]);
|
|
76
|
+
return SDocViewer;
|
|
77
|
+
}(React.Component);
|
|
78
|
+
SDocViewer.defaultProps = {
|
|
79
|
+
isOpenSocket: false
|
|
80
|
+
};
|
|
81
|
+
export default SDocViewer;
|
package/package.json
CHANGED
|
@@ -1,19 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@seafile/sdoc-editor",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "This is a sdoc editor",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"dependencies": {
|
|
8
8
|
"@seafile/react-image-lightbox": "2.0.2",
|
|
9
|
+
"@seafile/slate": "0.91.8",
|
|
10
|
+
"@seafile/slate-hyperscript": "0.81.7",
|
|
11
|
+
"@seafile/slate-react": "0.92.2",
|
|
12
|
+
"deep-copy": "1.4.2",
|
|
9
13
|
"is-hotkey": "0.2.0",
|
|
14
|
+
"is-url": "^1.2.4",
|
|
10
15
|
"react-cookies": "0.1.1",
|
|
11
16
|
"reactstrap": "8.9.0",
|
|
12
|
-
"
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
-
"slate-react": "0.92.0",
|
|
16
|
-
"socket.io-client": "4.6.1"
|
|
17
|
+
"slugid": "3.2.0",
|
|
18
|
+
"socket.io-client": "4.6.1",
|
|
19
|
+
"uuid": "9.0.0"
|
|
17
20
|
},
|
|
18
21
|
"scripts": {
|
|
19
22
|
"clean": "rm -rf dist && mkdir dist",
|
|
@@ -222,5 +222,8 @@
|
|
|
222
222
|
},
|
|
223
223
|
"Select_field": "Select field",
|
|
224
224
|
"Font_style": "Font style",
|
|
225
|
-
"Insert_column": "Insert column"
|
|
225
|
+
"Insert_column": "Insert column",
|
|
226
|
+
"The_link_address_is_required": "The link address is required.",
|
|
227
|
+
"The_link_title_is_required": "The link title is required.",
|
|
228
|
+
"The_link_address_is_invalid": "The link address is invalid, please enter a correct connection address."
|
|
226
229
|
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
var renderBlockquote = function renderBlockquote(props, editor) {
|
|
3
|
-
var attributes = props.attributes,
|
|
4
|
-
children = props.children;
|
|
5
|
-
return /*#__PURE__*/React.createElement("blockquote", attributes, children);
|
|
6
|
-
};
|
|
7
|
-
export default renderBlockquote;
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import HeaderPlugin from './header';
|
|
2
|
-
import BlockquotePlugin from './blockquote';
|
|
3
|
-
import ListPlugin from './list';
|
|
4
|
-
import CheckListPlugin from './check-list';
|
|
5
|
-
import TextPlugin from './text-style';
|
|
6
|
-
import SocketPlugin from './socket';
|
|
7
|
-
var Plugins = [HeaderPlugin, BlockquotePlugin, ListPlugin, CheckListPlugin, TextPlugin, SocketPlugin];
|
|
8
|
-
export default Plugins;
|
|
9
|
-
export { HeaderPlugin, BlockquotePlugin, ListPlugin, CheckListPlugin, TextPlugin, SocketPlugin };
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import SocketManager from "../../socket/socket-manager";
|
|
2
|
-
var withSocket = function withSocket(editor) {
|
|
3
|
-
var apply = editor.apply;
|
|
4
|
-
var newEditor = editor;
|
|
5
|
-
newEditor.apply = function (operation) {
|
|
6
|
-
var isRemote = operation.is_remote;
|
|
7
|
-
if (isRemote) {
|
|
8
|
-
apply(operation);
|
|
9
|
-
return;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
// 合并 op
|
|
13
|
-
try {
|
|
14
|
-
var socketManager = SocketManager.getInstance();
|
|
15
|
-
socketManager.addOperation && socketManager.addOperation(operation);
|
|
16
|
-
} catch (err) {
|
|
17
|
-
// first load, socketManager has not been init
|
|
18
|
-
}
|
|
19
|
-
apply(operation);
|
|
20
|
-
};
|
|
21
|
-
return newEditor;
|
|
22
|
-
};
|
|
23
|
-
export default withSocket;
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
2
|
-
import _createClass from "@babel/runtime/helpers/esm/createClass";
|
|
3
|
-
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
|
|
4
|
-
import io from 'socket.io-client';
|
|
5
|
-
import Debug from 'debug';
|
|
6
|
-
import SocketManager from './socket-manager';
|
|
7
|
-
var debug = Debug('sdoc:socket-client');
|
|
8
|
-
var SocketClient = /*#__PURE__*/_createClass(function SocketClient(config) {
|
|
9
|
-
var _this = this;
|
|
10
|
-
_classCallCheck(this, SocketClient);
|
|
11
|
-
this.getParams = function () {
|
|
12
|
-
var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
13
|
-
return _objectSpread({}, params);
|
|
14
|
-
};
|
|
15
|
-
this.onConnected = function () {
|
|
16
|
-
var socketManager = SocketManager.getInstance();
|
|
17
|
-
var _this$config = _this.config,
|
|
18
|
-
fileUuid = _this$config.fileUuid,
|
|
19
|
-
filePath = _this$config.filePath,
|
|
20
|
-
fileName = _this$config.fileName,
|
|
21
|
-
accessToken = _this$config.accessToken;
|
|
22
|
-
var params = {
|
|
23
|
-
file_uuid: fileUuid,
|
|
24
|
-
file_path: filePath,
|
|
25
|
-
file_name: fileName,
|
|
26
|
-
access_token: accessToken
|
|
27
|
-
};
|
|
28
|
-
_this.socket.emit('join-room', params, function (result) {
|
|
29
|
-
if (result.status) {
|
|
30
|
-
socketManager.dispatchConnectState('connect', result);
|
|
31
|
-
return;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// Disconnect the server in the client side. There will be no reconnection.
|
|
35
|
-
_this.socket.disconnect();
|
|
36
|
-
socketManager.dispatchConnectState('connect-error', result);
|
|
37
|
-
});
|
|
38
|
-
};
|
|
39
|
-
this.onReconnect = function (data) {
|
|
40
|
-
debug('reconnect.');
|
|
41
|
-
var socketManager = SocketManager.getInstance();
|
|
42
|
-
socketManager.dispatchConnectState('reconnect');
|
|
43
|
-
};
|
|
44
|
-
this.onReconnecting = function (attemptNumber) {
|
|
45
|
-
debug('reconnecting.', attemptNumber);
|
|
46
|
-
var socketManager = SocketManager.getInstance();
|
|
47
|
-
socketManager.dispatchConnectState('reconnecting', attemptNumber);
|
|
48
|
-
};
|
|
49
|
-
this.onDisconnected = function (data) {
|
|
50
|
-
debug('disconnect message: %s', data);
|
|
51
|
-
var socketManager = SocketManager.getInstance();
|
|
52
|
-
socketManager.dispatchConnectState('disconnect');
|
|
53
|
-
};
|
|
54
|
-
this.onJoinRoom = function (username) {
|
|
55
|
-
debug('%s joined room success.', username);
|
|
56
|
-
var socketManager = SocketManager.getInstance();
|
|
57
|
-
socketManager.dispatchConnectState('join-room', username);
|
|
58
|
-
};
|
|
59
|
-
this.onLeaveRoom = function (username) {
|
|
60
|
-
debug('%s leaved room success.', username);
|
|
61
|
-
var socketManager = SocketManager.getInstance();
|
|
62
|
-
socketManager.dispatchConnectState('leave-room', username);
|
|
63
|
-
};
|
|
64
|
-
this.sendOperation = function (operation, callback) {
|
|
65
|
-
debug('==================================');
|
|
66
|
-
debug('send operation: %s' + operation.toString());
|
|
67
|
-
debug('==================================');
|
|
68
|
-
_this.socket.emit('update-document', _this.getParams({
|
|
69
|
-
operation: operation
|
|
70
|
-
}), function (result) {
|
|
71
|
-
callback && callback(result);
|
|
72
|
-
});
|
|
73
|
-
};
|
|
74
|
-
this.receiveOperation = function (operation, version) {
|
|
75
|
-
debug('==================================');
|
|
76
|
-
debug('received operation: %s' + operation.toString());
|
|
77
|
-
debug('==================================');
|
|
78
|
-
var socketManager = SocketManager.getInstance();
|
|
79
|
-
socketManager.receiveOperation(operation, version);
|
|
80
|
-
};
|
|
81
|
-
this.disconnectWithServer = function () {
|
|
82
|
-
_this.socket.disconnect();
|
|
83
|
-
};
|
|
84
|
-
this.config = config;
|
|
85
|
-
this.socket = io(config.sdocServer);
|
|
86
|
-
this.socket.on('connect', this.onConnected);
|
|
87
|
-
this.socket.on('reconnect', this.onReconnect);
|
|
88
|
-
this.socket.on('reconnecting', this.onReconnecting);
|
|
89
|
-
this.socket.on('disconnect', this.onDisconnected);
|
|
90
|
-
this.socket.on('join-room', this.onJoinRoom);
|
|
91
|
-
this.socket.on('leave-room', this.onLeaveRoom);
|
|
92
|
-
this.socket.on('update-document', this.receiveOperation);
|
|
93
|
-
});
|
|
94
|
-
export default SocketClient;
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import _createClass from "@babel/runtime/helpers/esm/createClass";
|
|
2
|
-
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
|
|
3
|
-
import EventBus from '../../utils/event-bus';
|
|
4
|
-
import SocketClient from './socket-client';
|
|
5
|
-
var SocketManager = /*#__PURE__*/_createClass(function SocketManager(document, config) {
|
|
6
|
-
var _this = this;
|
|
7
|
-
_classCallCheck(this, SocketManager);
|
|
8
|
-
this.addOperation = function (operation) {
|
|
9
|
-
_this.pendingOperations.push(operation);
|
|
10
|
-
_this.sendOperation();
|
|
11
|
-
};
|
|
12
|
-
this.sendOperation = function () {
|
|
13
|
-
if (_this.isSendingOperation || _this.pendingOperations.length === 0) return;
|
|
14
|
-
_this.isSendingOperation = true;
|
|
15
|
-
_this.sendNextOperation();
|
|
16
|
-
};
|
|
17
|
-
this.sendNextOperation = function () {
|
|
18
|
-
if (_this.pendingOperations.length === 0) {
|
|
19
|
-
_this.isSendingOperation = false;
|
|
20
|
-
return;
|
|
21
|
-
}
|
|
22
|
-
var operation = _this.pendingOperations.shift();
|
|
23
|
-
_this.sendingOperation = operation;
|
|
24
|
-
_this.socketClient.sendOperation(operation, _this.sendOperationCallback);
|
|
25
|
-
};
|
|
26
|
-
this.sendOperationCallback = function (result) {
|
|
27
|
-
if (result && result.success) {
|
|
28
|
-
_this.sendingOperation = null;
|
|
29
|
-
var remoteVersion = result.version;
|
|
30
|
-
var localeVersion = _this.doc.version;
|
|
31
|
-
_this.doc['version'] = remoteVersion > localeVersion ? remoteVersion : localeVersion;
|
|
32
|
-
_this.sendNextOperation();
|
|
33
|
-
return;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// operation is execute failure
|
|
37
|
-
_this.sendingOperation = null;
|
|
38
|
-
_this.sendNextOperation();
|
|
39
|
-
};
|
|
40
|
-
this.receiveOperation = function (params, last_version) {
|
|
41
|
-
_this.eventBus.dispatch('receive-operation', params);
|
|
42
|
-
};
|
|
43
|
-
this.dispatchConnectState = function (type, message) {
|
|
44
|
-
console.log(type);
|
|
45
|
-
};
|
|
46
|
-
this.doc = document;
|
|
47
|
-
this.socketClient = new SocketClient(config);
|
|
48
|
-
this.sendingOperation = null;
|
|
49
|
-
this.pendingOperations = [];
|
|
50
|
-
this.isSendingOperation = false;
|
|
51
|
-
this.eventBus = new EventBus();
|
|
52
|
-
});
|
|
53
|
-
SocketManager.getInstance = function (document, socketConfig) {
|
|
54
|
-
if (SocketManager.instance) {
|
|
55
|
-
return SocketManager.instance;
|
|
56
|
-
}
|
|
57
|
-
if (!document || !socketConfig) {
|
|
58
|
-
throw new Error('SocketManager init params is invalid. Place check your code to fix it.');
|
|
59
|
-
}
|
|
60
|
-
SocketManager.instance = new SocketManager(document, socketConfig);
|
|
61
|
-
return SocketManager.instance;
|
|
62
|
-
};
|
|
63
|
-
export default SocketManager;
|