@seafile/sdoc-editor 0.1.117 → 0.1.118

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.
@@ -2,6 +2,7 @@ import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
2
2
  import { ReactEditor } from '@seafile/slate-react';
3
3
  import { Editor, Transforms, Range } from '@seafile/slate';
4
4
  import slugid from 'slugid';
5
+ import copy from 'copy-to-clipboard';
5
6
  import context from '../../../../context';
6
7
  import { SDOC_LINK, LINK, INSERT_FILE_DISPLAY_TYPE } from '../../constants';
7
8
  import { getNodeType, getSelectedElems } from '../../core';
@@ -121,4 +122,18 @@ export var getNewFileListData = function getNewFileListData(fileListData, indexI
121
122
  };
122
123
  export var getUrl = function getUrl(uuid) {
123
124
  return context.getSdocLocalFileUrl(uuid);
125
+ };
126
+ export var onCopySdocLinkNode = function onCopySdocLinkNode(editor, element) {
127
+ if (editor.selection == null || Range.isExpanded(editor.selection)) return;
128
+ var p = ReactEditor.findPath(editor, element);
129
+ Transforms.select(editor, p);
130
+ var newData = editor.setFragmentData(new DataTransfer());
131
+ copy('copy', {
132
+ onCopy: function onCopy(clipboardData) {
133
+ newData.types.forEach(function (type) {
134
+ var data = newData.getData(type);
135
+ clipboardData.setData(type, data);
136
+ });
137
+ }
138
+ });
124
139
  };
@@ -19,7 +19,7 @@
19
19
  .sdoc-link-menu .sdoc-link-menu-popover {
20
20
  position: absolute;
21
21
  top: 36px;
22
- left: 0px;
22
+ left: -15px;
23
23
  padding: 8px 0;
24
24
  background-color: #fff;
25
25
  border: 1px solid #e5e6e8;
@@ -30,7 +30,7 @@
30
30
  align-items: flex-start;
31
31
  z-index: 101;
32
32
  white-space: nowrap;
33
- width: 180px;
33
+ width: 138px;
34
34
  }
35
35
 
36
36
  .sdoc-link-menu .sdoc-link-menu-popover .sdoc-link-menu-item {
@@ -40,9 +40,9 @@
40
40
  user-select: none;
41
41
  display: flex;
42
42
  align-items: center;
43
- font-size: 12px;
43
+ font-size: 14px;
44
44
  color: #212529;
45
- padding-left: 24px;
45
+ padding-left: 5px;
46
46
  }
47
47
 
48
48
  .sdoc-link-menu .sdoc-link-menu-popover .sdoc-link-menu-item > span :first-child {
@@ -1,6 +1,6 @@
1
1
  import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
2
2
  import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
3
- import React, { useCallback, useState } from 'react';
3
+ import React, { useCallback, useEffect, useState } from 'react';
4
4
  import { withTranslation } from 'react-i18next';
5
5
  import { SDOC_LINK, MENUS_CONFIG_MAP } from '../../../constants';
6
6
  import { MenuItem } from '../../../commons';
@@ -30,13 +30,13 @@ var SdocLinkMenu = function SdocLinkMenu(_ref) {
30
30
  }, []);
31
31
  var onInsertFileDialogToggle = useCallback(function () {
32
32
  setShowInsertPopover(true);
33
- // setShowInsertDialog(!showInsertDialog);
34
33
  }, []);
35
- var onMouseDown = useCallback(function () {
34
+ var onMouseDown = useCallback(function (e) {
35
+ e.stopPropagation();
36
36
  onInsertFileDialogToggle();
37
37
  // eslint-disable-next-line react-hooks/exhaustive-deps
38
38
  }, []);
39
- var onInsertSdocFile = useCallback(function () {
39
+ var onInsertSdocFile = useCallback(function (e) {
40
40
  setShowInsertPopover(false);
41
41
  setShowInsertDialog(true);
42
42
  // eslint-disable-next-line react-hooks/exhaustive-deps
@@ -44,6 +44,20 @@ var SdocLinkMenu = function SdocLinkMenu(_ref) {
44
44
  var onDialogToggle = useCallback(function (value) {
45
45
  setShowInsertDialog(value);
46
46
  }, []);
47
+ var onHidenInsertPopover = useCallback(function () {
48
+ setShowInsertPopover(false);
49
+ }, []);
50
+ useEffect(function () {
51
+ if (showInsertPopover) {
52
+ window.addEventListener('click', onHidenInsertPopover);
53
+ } else {
54
+ window.removeEventListener('click', onHidenInsertPopover);
55
+ }
56
+ return function () {
57
+ window.removeEventListener('click', onHidenInsertPopover);
58
+ };
59
+ // eslint-disable-next-line react-hooks/exhaustive-deps
60
+ }, [showInsertPopover]);
47
61
  var menuConfig = MENUS_CONFIG_MAP[SDOC_LINK];
48
62
  var props = _objectSpread(_objectSpread({
49
63
  isRichEditor: isRichEditor,
@@ -2,37 +2,37 @@ import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
2
2
  import React, { useCallback, useState } from 'react';
3
3
  import { Transforms } from '@seafile/slate';
4
4
  import { ReactEditor } from '@seafile/slate-react';
5
- import copy from 'copy-to-clipboard';
6
5
  import { withTranslation } from 'react-i18next';
7
6
  import { ElementPopover } from '../../../commons';
8
7
  import toaster from '../../../../../components/toast';
9
- import { getUrl } from '../helpers';
8
+ import { getUrl, onCopySdocLinkNode } from '../helpers';
10
9
  import './sdoc-link-hover-menu.css';
11
10
  var SdocLinkHoverMenu = function SdocLinkHoverMenu(_ref) {
12
11
  var editor = _ref.editor,
13
12
  menuPosition = _ref.menuPosition,
14
13
  element = _ref.element,
15
14
  onUnwrapFileLinkNode = _ref.onUnwrapFileLinkNode,
15
+ onHideInsertHoverMenu = _ref.onHideInsertHoverMenu,
16
16
  t = _ref.t;
17
17
  var _useState = useState(false),
18
18
  _useState2 = _slicedToArray(_useState, 2),
19
19
  isShowDisplayStylePopover = _useState2[0],
20
20
  setIsShowDisplayStylePopover = _useState2[1];
21
- var onCopy = useCallback(function () {
22
- copy(String(getUrl(element.doc_uuid)), {
23
- format: 'text/plain'
24
- });
21
+ var onCopy = useCallback(function (e) {
22
+ e.stopPropagation();
23
+ onCopySdocLinkNode(editor, element);
25
24
  toaster.success(t('Copied'), {
26
25
  hasCloseButton: false,
27
26
  duration: 2
28
27
  });
28
+ onHideInsertHoverMenu();
29
29
  // eslint-disable-next-line react-hooks/exhaustive-deps
30
30
  }, []);
31
31
  var onShowProver = useCallback(function (e) {
32
- e.stopPropagation();
33
32
  setIsShowDisplayStylePopover(true);
34
33
  }, []);
35
- var onSelect = useCallback(function (value) {
34
+ var onSelect = useCallback(function (e, value) {
35
+ e.stopPropagation();
36
36
  var path = ReactEditor.findPath(editor, element);
37
37
  if (path) {
38
38
  Transforms.setNodes(editor, {
@@ -41,6 +41,7 @@ var SdocLinkHoverMenu = function SdocLinkHoverMenu(_ref) {
41
41
  at: path
42
42
  });
43
43
  }
44
+ onHideInsertHoverMenu();
44
45
  // eslint-disable-next-line react-hooks/exhaustive-deps
45
46
  }, []);
46
47
  return /*#__PURE__*/React.createElement(ElementPopover, null, /*#__PURE__*/React.createElement("div", {
@@ -84,8 +85,8 @@ var SdocLinkHoverMenu = function SdocLinkHoverMenu(_ref) {
84
85
  className: "sdoc-file-display-style-popover"
85
86
  }, /*#__PURE__*/React.createElement("div", {
86
87
  className: "sdoc-file-display-style-item ".concat(element.display_type === 'text_link' ? 'active' : 'inactive'),
87
- onClick: function onClick() {
88
- onSelect('text_link');
88
+ onClick: function onClick(e) {
89
+ onSelect(e, 'text_link');
89
90
  }
90
91
  }, /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement("i", {
91
92
  className: "sdocfont sdoc-text-link"
@@ -93,8 +94,8 @@ var SdocLinkHoverMenu = function SdocLinkHoverMenu(_ref) {
93
94
  className: "sdocfont sdoc-check-mark"
94
95
  }))), /*#__PURE__*/React.createElement("div", {
95
96
  className: "sdoc-file-display-style-item ".concat(element.display_type === 'icon_link' ? 'active' : 'inactive'),
96
- onClick: function onClick() {
97
- onSelect('icon_link');
97
+ onClick: function onClick(e) {
98
+ onSelect(e, 'icon_link');
98
99
  }
99
100
  }, /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement("i", {
100
101
  className: "sdocfont sdoc-inline-link"
@@ -102,8 +103,8 @@ var SdocLinkHoverMenu = function SdocLinkHoverMenu(_ref) {
102
103
  className: "sdocfont sdoc-check-mark"
103
104
  }))), /*#__PURE__*/React.createElement("div", {
104
105
  className: "sdoc-file-display-style-item ".concat(element.display_type === 'card_link' ? 'active' : 'inactive'),
105
- onClick: function onClick() {
106
- onSelect('card_link');
106
+ onClick: function onClick(e) {
107
+ onSelect(e, 'card_link');
107
108
  }
108
109
  }, /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement("i", {
109
110
  className: "sdocfont sdoc-card-link"
@@ -69,6 +69,7 @@ var SdocFileLink = function SdocFileLink(_ref) {
69
69
  // eslint-disable-next-line react-hooks/exhaustive-deps
70
70
  }, [isShowInsertHoverMenu]);
71
71
  var onClickFile = useCallback(function (e) {
72
+ e.stopPropagation();
72
73
  setPosition(e.currentTarget);
73
74
  setIsShowInsertHoverMenu(true);
74
75
  setTimeout(function () {
@@ -76,7 +77,7 @@ var SdocFileLink = function SdocFileLink(_ref) {
76
77
  }, 0);
77
78
  // eslint-disable-next-line react-hooks/exhaustive-deps
78
79
  }, []);
79
- var onHideInsertHoverMenu = useCallback(function () {
80
+ var onHideInsertHoverMenu = useCallback(function (e) {
80
81
  setIsShowInsertHoverMenu(false);
81
82
  unregisterEventHandle();
82
83
  // eslint-disable-next-line react-hooks/exhaustive-deps
@@ -107,7 +108,8 @@ var SdocFileLink = function SdocFileLink(_ref) {
107
108
  editor: editor,
108
109
  menuPosition: menuPosition,
109
110
  element: element,
110
- onUnwrapFileLinkNode: onUnwrapFileLinkNode
111
+ onUnwrapFileLinkNode: onUnwrapFileLinkNode,
112
+ onHideInsertHoverMenu: onHideInsertHoverMenu
111
113
  }));
112
114
  };
113
115
  var renderSdocLink = function renderSdocLink(props, editor) {
@@ -1,3 +1,4 @@
1
+ import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
1
2
  import _createClass from "@babel/runtime/helpers/esm/createClass";
2
3
  import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
3
4
  import EventBus from '../utils/event-bus';
@@ -8,6 +9,10 @@ import { deleteCursor } from '../cursor/helper';
8
9
  var SocketManager = /*#__PURE__*/_createClass(function SocketManager(editor, document, config) {
9
10
  var _this = this;
10
11
  _classCallCheck(this, SocketManager);
12
+ this.getDocumentVersion = function () {
13
+ var version = _this.document.version;
14
+ return version;
15
+ };
11
16
  this.addOperations = function (operations) {
12
17
  _this.pendingOperationList.push(operations);
13
18
  if (_this.pendingOperationList.length > 5) {
@@ -15,10 +20,6 @@ var SocketManager = /*#__PURE__*/_createClass(function SocketManager(editor, doc
15
20
  }
16
21
  _this.sendOperations();
17
22
  };
18
- this.getDocumentVersion = function () {
19
- var version = _this.document.version;
20
- return version;
21
- };
22
23
  this.sendOperations = function () {
23
24
  if (_this.isSending || _this.pendingOperationList.length === 0) return;
24
25
  _this.isSending = true;
@@ -38,8 +39,8 @@ var SocketManager = /*#__PURE__*/_createClass(function SocketManager(editor, doc
38
39
  _this.socketClient.sendOperations(operations, version, selection, _this.sendOperationsCallback);
39
40
  };
40
41
  this.sendOperationsCallback = function (result) {
41
- _this._sendingOperations = null;
42
42
  if (result && result.success) {
43
+ _this._sendingOperations = null;
43
44
  var serverVersion = result.version;
44
45
  _this.document['version'] = serverVersion;
45
46
  var lastSavedAt = new Date().getTime();
@@ -49,20 +50,25 @@ var SocketManager = /*#__PURE__*/_createClass(function SocketManager(editor, doc
49
50
  }
50
51
 
51
52
  // Operations are execute failure
52
- var error_type = result.error_type,
53
- operations = result.operations;
53
+ var error_type = result.error_type;
54
54
  if (error_type === 'version_behind_server') {
55
+ var dupSendingOperations = _toConsumableArray(_this._sendingOperations);
55
56
  // Put the failed operation into the pending list and re-execute it
56
- _this.pendingOperationList.unshift(operations);
57
- _this.sendNextOperations();
57
+ _this.pendingOperationList.unshift(dupSendingOperations);
58
+ var lose_operations = result.lose_operations;
59
+ _this.execLoseOperations(lose_operations);
58
60
  } else if (error_type === 'document_content_load_failed') {
61
+ _this._sendingOperations = null;
59
62
  // After a short-term reconnection, the content of the document fails to load
60
63
  _this.dispatchConnectState(error_type);
61
64
  } else if (error_type === 'Internal_server_error') {
65
+ _this._sendingOperations = null;
62
66
  _this.dispatchConnectState(error_type);
63
67
  } else if (error_type === 'operation_exec_error') {
68
+ var _dupSendingOperations = _toConsumableArray(_this._sendingOperations);
69
+ _this._sendingOperations = null;
64
70
  _this.editor.isRemote = true;
65
- revertOperationList(_this.editor, [operations]);
71
+ revertOperationList(_this.editor, [_dupSendingOperations]);
66
72
 
67
73
  // reset control flag
68
74
  Promise.resolve().then(function (_) {
@@ -72,6 +78,51 @@ var SocketManager = /*#__PURE__*/_createClass(function SocketManager(editor, doc
72
78
  });
73
79
  }
74
80
  };
81
+ this.execLoseOperations = function (loseOperations) {
82
+ // 1. Revert operations
83
+ // 1.1 record reverted operationList & clear pendingOperationList
84
+ _this.revertOperationList = _this.pendingOperationList.slice();
85
+ _this.pendingOperationList = [];
86
+
87
+ // 1.2 Revert operationList
88
+ debug('revert locale operations: %O', _this.revertOperationList);
89
+ revertOperationList(_this.editor, _this.revertOperationList);
90
+ _this.editor.isRemote = true;
91
+ loseOperations = loseOperations.sort(function (prev, next) {
92
+ return prev.version - next.version;
93
+ });
94
+ debug('Editor isRemote is true: %s', _this.editor.isRemote);
95
+ while (loseOperations.length > 0) {
96
+ var operationParams = loseOperations.shift();
97
+ // 2. execute operations
98
+ var operations = operationParams.operations,
99
+ serverVersion = operationParams.version;
100
+ // 2.1 Update content & version
101
+ debug('execute remote operations: %O', operations);
102
+ syncRemoteOperations(_this.editor, operations);
103
+
104
+ // 2.2 Update document
105
+ _this.document.version = serverVersion;
106
+ _this.document.children = _this.editor.children;
107
+ }
108
+
109
+ // Re-execute undone operations after isRemote is set to false
110
+ // Need resend this operations to server
111
+
112
+ // reset execute remote operations flag
113
+ _this.editor.isRemote = false;
114
+ _this.isSending = false;
115
+ _this._sendingOperations = null;
116
+
117
+ // 3. Execute pending operations
118
+ // 3.1 Re-execute operations
119
+ debug('Editor isRemote is false: %s', _this.editor.isRemote);
120
+ debug('Re-execute pending operations, %O', _this.revertOperationList);
121
+ reExecRevertOperationList(_this.editor, _this.revertOperationList);
122
+
123
+ // 3.2 Clear revert operationList
124
+ _this.revertOperationList = [];
125
+ };
75
126
  this.receiveOperations = function (params) {
76
127
  _this.remoteOperationsList.push(params);
77
128
  // sort operations by version
@@ -79,8 +130,12 @@ var SocketManager = /*#__PURE__*/_createClass(function SocketManager(editor, doc
79
130
  _this.remoteOperationsList = _this.remoteOperationsList.sort(function (prev, next) {
80
131
  return prev.version - next.version;
81
132
  });
133
+ var clientVersion = _this.document.version;
134
+ _this.remoteOperationsList = _this.remoteOperationsList.filter(function (item) {
135
+ return item.version > clientVersion;
136
+ });
82
137
  }
83
- if (_this.isExecRemoteOperations) return;
138
+ if (_this.isExecRemoteOperations || _this._sendingOperations) return;
84
139
 
85
140
  // update execute remote operations flag
86
141
  _this.isExecRemoteOperations = true;
@@ -141,7 +141,7 @@ var SimpleEditor = function SimpleEditor(_ref) {
141
141
  className: "error-page"
142
142
  }, /*#__PURE__*/React.createElement("div", {
143
143
  className: "error-tip"
144
- }, t(errorMessage))), !isLoadingSdoc && /*#__PURE__*/React.createElement(React.Fragment, null, isShowChanges ? /*#__PURE__*/React.createElement(DiffViewer, {
144
+ }, t(errorMessage))), !isLoadingSdoc && !errorMessage && /*#__PURE__*/React.createElement(React.Fragment, null, isShowChanges ? /*#__PURE__*/React.createElement(DiffViewer, {
145
145
  currentContent: currentContent,
146
146
  lastContent: lastContent
147
147
  }) : /*#__PURE__*/React.createElement(SDocEditor, {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seafile/sdoc-editor",
3
- "version": "0.1.117",
3
+ "version": "0.1.118",
4
4
  "private": false,
5
5
  "description": "This is a sdoc editor",
6
6
  "main": "dist/index.js",