@seafile/sdoc-editor 0.1.160 → 0.1.161

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.
Files changed (29) hide show
  1. package/dist/api/seafile-api.js +32 -9
  2. package/dist/basic-sdk/constants/index.js +25 -1
  3. package/dist/basic-sdk/editor/common-editor.js +50 -0
  4. package/dist/basic-sdk/editor/index.css +29 -0
  5. package/dist/basic-sdk/editor/index.js +125 -0
  6. package/dist/basic-sdk/{slate-editor.js → editor/slate-editor.js} +21 -16
  7. package/dist/basic-sdk/extension/constants/element-type.js +6 -1
  8. package/dist/basic-sdk/extension/core/transforms/replace-node-children.js +26 -0
  9. package/dist/basic-sdk/extension/render/render-element.js +221 -1
  10. package/dist/basic-sdk/socket/helpers.js +2 -0
  11. package/dist/basic-sdk/socket/socket-client.js +36 -0
  12. package/dist/basic-sdk/socket/socket-manager.js +25 -2
  13. package/dist/basic-sdk/socket/with-socket-io.js +30 -12
  14. package/dist/basic-sdk/utils/diff.js +4 -3
  15. package/dist/basic-sdk/utils/rebase.js +193 -0
  16. package/dist/basic-sdk/views/diff-viewer.js +3 -1
  17. package/dist/basic-sdk/views/viewer.js +9 -12
  18. package/dist/components/doc-operations/index.js +4 -2
  19. package/dist/components/doc-operations/revision-operations/index.js +5 -2
  20. package/dist/components/doc-operations/revision-operations/publish-button.js +6 -13
  21. package/dist/components/tip-dialog/index.js +50 -0
  22. package/dist/components/tip-dialog/tip-content.js +47 -0
  23. package/dist/constants/index.js +26 -2
  24. package/dist/context.js +44 -9
  25. package/dist/pages/simple-editor.js +255 -88
  26. package/package.json +1 -1
  27. package/public/locales/en/sdoc-editor.json +12 -1
  28. package/public/locales/zh_CN/sdoc-editor.json +10 -1
  29. package/dist/basic-sdk/editor.js +0 -105
@@ -119,6 +119,30 @@ var SocketClient = /*#__PURE__*/_createClass(function SocketClient(config) {
119
119
  this.disconnectWithServer = function () {
120
120
  _this.socket.disconnect();
121
121
  };
122
+ this.receivePublishDocument = function () {
123
+ var socketManager = SocketManager.getInstance();
124
+ socketManager.receivePublishDocument();
125
+ };
126
+ this.receivePublishDocumentError = function () {
127
+ var socketManager = SocketManager.getInstance();
128
+ socketManager.receivePublishDocumentError();
129
+ };
130
+ this.receiveDocumentReplaced = function () {
131
+ var socketManager = SocketManager.getInstance();
132
+ socketManager.receiveDocumentReplaced();
133
+ };
134
+ this.receiveDocumentReplacedError = function () {
135
+ var socketManager = SocketManager.getInstance();
136
+ socketManager.receiveDocumentReplacedError();
137
+ };
138
+ this.receiveRemoveDocument = function () {
139
+ var socketManager = SocketManager.getInstance();
140
+ socketManager.receiveRemoveDocument();
141
+ };
142
+ this.receiveRemoveDocumentError = function () {
143
+ var socketManager = SocketManager.getInstance();
144
+ socketManager.receiveRemoveDocumentError();
145
+ };
122
146
  this.config = config;
123
147
  this.isReconnect = false;
124
148
  this.socket = io(config.sdocServer, {
@@ -133,6 +157,18 @@ var SocketClient = /*#__PURE__*/_createClass(function SocketClient(config) {
133
157
  this.socket.on('join-room', this.onJoinRoom);
134
158
  this.socket.on('leave-room', this.onLeaveRoom);
135
159
  this.socket.on('update-document', this.onReceiveRemoteOperations);
160
+
161
+ // doc replaced
162
+ this.socket.on('doc-replaced', this.receiveDocumentReplaced);
163
+ this.socket.on('doc-replaced-error', this.receiveDocumentReplacedError);
164
+
165
+ // doc published
166
+ this.socket.on('doc-published', this.receivePublishDocument);
167
+ this.socket.on('doc-published-error', this.receivePublishDocumentError);
168
+
169
+ // doc removed
170
+ this.socket.on('doc-removed', this.receiveRemoveDocument);
171
+ this.socket.on('doc-removed-error', this.receiveRemoveDocumentError);
136
172
  this.socket.on('update-cursor', this.receiveCursorLocation);
137
173
  this.socket.io.on('reconnect', this.onReconnect);
138
174
  this.socket.io.on('reconnect_attempt', this.onReconnectAttempt);
@@ -7,6 +7,7 @@ import { syncRemoteOperations, reExecRevertOperationList, revertOperationList, s
7
7
  import SocketClient from './socket-client';
8
8
  import { clientDebug, conflictDebug, serverDebug, stateDebug } from '../utils/debug';
9
9
  import { deleteCursor } from '../cursor/helper';
10
+ import { EXTERNAL_EVENT, MODE } from '../../constants';
10
11
 
11
12
  // idle --> sending --> conflict --> idle
12
13
  // --> conflict --> idle
@@ -19,13 +20,34 @@ var STATE = {
19
20
  DISCONNECT: 'disconnect',
20
21
  NEED_RELOAD: 'need_reload'
21
22
  };
22
- var SocketManager = /*#__PURE__*/_createClass(function SocketManager(editor, document, config) {
23
+ var SocketManager = /*#__PURE__*/_createClass(function SocketManager(editor, _document, config) {
23
24
  var _this = this;
24
25
  _classCallCheck(this, SocketManager);
25
26
  this.getDocumentVersion = function () {
26
27
  var version = _this.document.version;
27
28
  return version;
28
29
  };
30
+ this.updateDocumentVersion = function (document) {
31
+ _this.document['version'] = document.version;
32
+ };
33
+ this.receivePublishDocument = function () {
34
+ _this.eventBus.dispatch(EXTERNAL_EVENT.PUBLISH_DOCUMENT);
35
+ };
36
+ this.receivePublishDocumentError = function () {
37
+ _this.eventBus.dispatch(EXTERNAL_EVENT.PUBLISH_DOCUMENT_ERROR);
38
+ };
39
+ this.receiveRemoveDocument = function () {
40
+ _this.eventBus.dispatch(EXTERNAL_EVENT.REMOVE_DOCUMENT);
41
+ };
42
+ this.receiveRemoveDocumentError = function () {
43
+ _this.eventBus.dispatch(EXTERNAL_EVENT.REMOVE_DOCUMENT_ERROR);
44
+ };
45
+ this.receiveDocumentReplaced = function () {
46
+ _this.eventBus.dispatch(EXTERNAL_EVENT.DOCUMENT_REPLACED);
47
+ };
48
+ this.receiveDocumentReplacedError = function () {
49
+ _this.eventBus.dispatch(EXTERNAL_EVENT.DOCUMENT_REPLACED_ERROR);
50
+ };
29
51
  this.onReceiveLocalOperations = function (operations) {
30
52
  _this.pendingOperationList.push(operations);
31
53
  if (_this.pendingOperationList.length > 5) {
@@ -34,6 +56,7 @@ var SocketManager = /*#__PURE__*/_createClass(function SocketManager(editor, doc
34
56
  _this.sendOperations();
35
57
  };
36
58
  this.sendOperations = function () {
59
+ if (_this.editor.mode !== MODE.EDITOR) return;
37
60
  if (_this.state !== STATE.IDLE) return;
38
61
  stateDebug("State changed: ".concat(_this.state, " -> ").concat(STATE.SENDING));
39
62
  _this.state = STATE.SENDING;
@@ -292,7 +315,7 @@ var SocketManager = /*#__PURE__*/_createClass(function SocketManager(editor, doc
292
315
  _this.socketClient.disconnectWithServer();
293
316
  };
294
317
  this.editor = editor;
295
- this.document = document;
318
+ this.document = _document;
296
319
  this.socketClient = new SocketClient(config);
297
320
  this.pendingOperationList = []; // Two-dimensional arrays: [operations, operations, ...]
298
321
  this.remoteOperationsList = []; // Same with pending operations
@@ -1,3 +1,4 @@
1
+ import { MODE } from '../../constants';
1
2
  import { generateCursorData } from '../cursor/helper';
2
3
  import EventBus from '../utils/event-bus';
3
4
  import SocketManager from './socket-manager';
@@ -19,28 +20,45 @@ var withSocketIO = function withSocketIO(editor, options) {
19
20
  SocketManager.destroy();
20
21
  };
21
22
  newEditor.onChange = function () {
22
- if (newEditor.readonly) return;
23
+ var document = options.document,
24
+ config = options.config;
25
+ if (newEditor.mode === MODE.DIFF_VIEWER) return;
23
26
  var operations = newEditor.operations;
24
27
  if (!newEditor.isRemote && operations.length > 0) {
25
28
  var isAllSetSelection = operations.every(function (operation) {
26
29
  return operation.type === 'set_selection';
27
30
  });
28
- var _socketManager = SocketManager.getInstance();
31
+ var _socketManager = SocketManager.getInstance(newEditor, document, config);
29
32
  if (!isAllSetSelection) {
30
- // get update content value operations
31
- var updateOperations = operations.filter(function (operation) {
32
- return operation.type !== 'set_selection';
33
- });
34
- _socketManager.onReceiveLocalOperations(updateOperations);
33
+ if (newEditor.mode === MODE.EDITOR) {
34
+ // get update content value operations
35
+ var updateOperations = operations.filter(function (operation) {
36
+ return operation.type !== 'set_selection';
37
+ });
38
+ _socketManager.onReceiveLocalOperations(updateOperations);
39
+ }
40
+ }
41
+ if (newEditor.mode === MODE.EDITOR) {
42
+ _socketManager.sendCursorLocation(editor.selection);
35
43
  }
36
- _socketManager.sendCursorLocation(editor.selection);
37
44
  }
38
-
39
- // dispatch editor change event
40
- var eventBus = EventBus.getInstance();
41
- eventBus.dispatch('change');
45
+ if (newEditor.mode === MODE.EDITOR) {
46
+ // dispatch editor change event
47
+ var eventBus = EventBus.getInstance(newEditor, document, config);
48
+ eventBus.dispatch('change');
49
+ }
42
50
  onChange();
43
51
  };
52
+ newEditor.rebaseContent = function (document, originFileVersion) {
53
+ var config = options.config;
54
+ var socketManager = SocketManager.getInstance(newEditor, document, config);
55
+ socketManager.sendRebaseContent(document, originFileVersion);
56
+ };
57
+ newEditor.updateDocumentVersion = function (document) {
58
+ var config = options.config;
59
+ var socketManager = SocketManager.getInstance(newEditor, document, config);
60
+ socketManager.updateDocumentVersion(document);
61
+ };
44
62
  return newEditor;
45
63
  };
46
64
  export default withSocketIO;
@@ -31,7 +31,7 @@ var generatorDiffElement = function generatorDiffElement(element, diffType) {
31
31
  return generatorDiffElement(item, diffType, style);
32
32
  })), _objectSpread3));
33
33
  };
34
- var generateIdMapAndIds = function generateIdMapAndIds(elements) {
34
+ export var generateIdMapAndIds = function generateIdMapAndIds(elements) {
35
35
  var map = {};
36
36
  var ids = [];
37
37
  if (!Array.isArray(elements) || elements.length === 0) return {
@@ -54,7 +54,7 @@ var hasChildren = function hasChildren(element) {
54
54
  };
55
55
 
56
56
  // id diffs
57
- var getIdDiffs = function getIdDiffs(oldIds, newIds) {
57
+ export var getIdDiffs = function getIdDiffs(oldIds, newIds) {
58
58
  var diff = new DiffText(oldIds, newIds);
59
59
  return diff.getDiffs();
60
60
  };
@@ -288,4 +288,5 @@ export var getDiff = function getDiff() {
288
288
  changes: []
289
289
  };
290
290
  return getElementDiffValue(currentContent, oldContent);
291
- };
291
+ };
292
+ window.getIdDiffs = getIdDiffs;
@@ -0,0 +1,193 @@
1
+ import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
2
+ import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
3
+ import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
4
+ import { generateIdMapAndIds, getIdDiffs } from './diff';
5
+ import ObjectUtils from './object-utils';
6
+ import { MODIFY_TYPE, REBASE_TYPE, REBASE_MARK_KEY, REBASE_ORIGIN } from '../constants';
7
+ import { ELEMENT_TYPE } from '../extension/constants';
8
+ import { replaceNodeId } from '../node-id/helpers';
9
+ export var hasConflict = function hasConflict(content) {
10
+ if (!Array.isArray(content) || content.length === 0) return false;
11
+ return content.filter(function (item) {
12
+ return item.rebase_type;
13
+ }).length !== 0;
14
+ };
15
+ var getChanges = function getChanges(masterContent, revisionContent) {
16
+ var _generateIdMapAndIds = generateIdMapAndIds(masterContent.children),
17
+ masterContentMap = _generateIdMapAndIds.map,
18
+ masterIds = _generateIdMapAndIds.ids;
19
+ var _generateIdMapAndIds2 = generateIdMapAndIds(revisionContent.children),
20
+ currentContentMap = _generateIdMapAndIds2.map,
21
+ currentIds = _generateIdMapAndIds2.ids;
22
+ var idDiffs = getIdDiffs(masterIds, currentIds);
23
+ var content = [];
24
+ idDiffs.forEach(function (idDiff) {
25
+ var value = idDiff.value,
26
+ added = idDiff.added,
27
+ removed = idDiff.removed;
28
+ if (added) {
29
+ var addedList = value.map(function (item) {
30
+ return _objectSpread(_objectSpread({}, currentContentMap[item]), {}, _defineProperty({}, REBASE_MARK_KEY.MODIFY_TYPE, MODIFY_TYPE.ADD));
31
+ });
32
+ content.push.apply(content, _toConsumableArray(addedList));
33
+ } else if (removed) {
34
+ var deletedList = value.map(function (item) {
35
+ return _objectSpread(_objectSpread({}, masterContentMap[item]), {}, _defineProperty({}, REBASE_MARK_KEY.MODIFY_TYPE, MODIFY_TYPE.DELETE));
36
+ });
37
+ content.push.apply(content, _toConsumableArray(deletedList));
38
+ } else {
39
+ value.forEach(function (elementId) {
40
+ if (ObjectUtils.isSameObject(masterContentMap[elementId], currentContentMap[elementId])) {
41
+ content.push(currentContentMap[elementId]);
42
+ } else {
43
+ var _objectSpread4;
44
+ var oldElement = masterContentMap[elementId];
45
+ var currentElement = currentContentMap[elementId];
46
+ var newElement = _objectSpread(_objectSpread({}, currentElement), {}, (_objectSpread4 = {}, _defineProperty(_objectSpread4, REBASE_MARK_KEY.MODIFY_TYPE, MODIFY_TYPE.MODIFY), _defineProperty(_objectSpread4, REBASE_MARK_KEY.OLD_ELEMENT, oldElement), _objectSpread4));
47
+ if (currentElement.type === oldElement.type) {
48
+ var elementType = currentElement.type;
49
+ if ([ELEMENT_TYPE.UNORDERED_LIST, ELEMENT_TYPE.ORDERED_LIST].includes(elementType)) {
50
+ var listContent = getChanges(oldElement, currentElement);
51
+ newElement[REBASE_MARK_KEY.MODIFY_TYPE] = MODIFY_TYPE.CHILDREN_MODIFY;
52
+ newElement['children'] = listContent;
53
+ }
54
+ }
55
+ content.push(newElement);
56
+ }
57
+ });
58
+ }
59
+ });
60
+ return content;
61
+ };
62
+ var getMergeElement = function getMergeElement(diffElement, baseElement) {
63
+ var modifyType = diffElement[REBASE_MARK_KEY.MODIFY_TYPE];
64
+ var newElement = _objectSpread({}, diffElement);
65
+ newElement[REBASE_MARK_KEY.MODIFY_TYPE] && delete newElement[REBASE_MARK_KEY.MODIFY_TYPE];
66
+
67
+ // revision does not have this element, master has this element
68
+ if (modifyType === MODIFY_TYPE.DELETE) {
69
+ // base content does not have this element, indicating that it is newly added by master and needs to be retained, and will not be counted as a conflict.
70
+ if (!baseElement) return [newElement];
71
+
72
+ // base content has this element, master modified it, indicating that revision deleted it, and the user manually selected the conflict
73
+ if (!ObjectUtils.isSameObject(baseElement, diffElement, [REBASE_MARK_KEY.MODIFY_TYPE])) {
74
+ newElement[REBASE_MARK_KEY.REBASE_TYPE] = REBASE_TYPE.MODIFY_DELETE;
75
+ return [newElement];
76
+ }
77
+
78
+ // base content has this element, but master has not modified it. It means that revision has deleted it and the program has deleted it. The conflict will not be counted.
79
+ return [];
80
+ }
81
+
82
+ // revision has this element, master does not have this element
83
+ if (modifyType === MODIFY_TYPE.ADD) {
84
+ // base content does not have this element, indicating that it is newly added by revision and needs to be retained, and will not be counted as a conflict.
85
+ if (!baseElement) return [newElement];
86
+
87
+ // master deleted it, revision modified it, and the user manually selected the conflict
88
+ if (!ObjectUtils.isSameObject(baseElement, diffElement, [REBASE_MARK_KEY.MODIFY_TYPE])) {
89
+ newElement[REBASE_MARK_KEY.REBASE_TYPE] = REBASE_TYPE.DELETE_MODIFY;
90
+ return [newElement];
91
+ }
92
+
93
+ // master deleted it, revision did not modify it, the program deleted it, and the conflict is not counted.
94
+ return [];
95
+ }
96
+
97
+ // Elements that differ between revision and master
98
+ if (modifyType === MODIFY_TYPE.MODIFY) {
99
+ var _objectSpread7, _objectSpread8;
100
+ var masterElement = _objectSpread({}, diffElement[REBASE_MARK_KEY.OLD_ELEMENT]);
101
+ delete newElement[REBASE_MARK_KEY.OLD_ELEMENT];
102
+
103
+ // revision and master both add a new element, but the content is different. ===》 At present, this situation does not exist, it only exists in the theoretical stage.
104
+ if (!baseElement) {
105
+ var _objectSpread5, _objectSpread6;
106
+ return [_objectSpread(_objectSpread({}, replaceNodeId(masterElement)), {}, (_objectSpread5 = {}, _defineProperty(_objectSpread5, REBASE_MARK_KEY.REBASE_TYPE, REBASE_TYPE.MODIFY_MODIFY), _defineProperty(_objectSpread5, REBASE_MARK_KEY.OLD_ELEMENT, masterElement), _defineProperty(_objectSpread5, REBASE_MARK_KEY.ORIGIN, REBASE_ORIGIN.OTHER), _objectSpread5)), _objectSpread(_objectSpread({}, newElement), {}, (_objectSpread6 = {}, _defineProperty(_objectSpread6, REBASE_MARK_KEY.REBASE_TYPE, REBASE_TYPE.MODIFY_MODIFY), _defineProperty(_objectSpread6, REBASE_MARK_KEY.ORIGIN, REBASE_ORIGIN.MY), _objectSpread6))];
107
+ }
108
+
109
+ // master is the same as base, indicating that revision has modified the content
110
+ if (ObjectUtils.isSameObject(masterElement, baseElement)) return [newElement];
111
+
112
+ // revision is the same as base, indicating that master has modified the content
113
+ if (ObjectUtils.isSameObject(newElement, baseElement)) return [masterElement];
114
+
115
+ // They are all different. Revision and master were modified at the same time. If there is a conflict, the conflict needs to be resolved manually.
116
+ return [_objectSpread(_objectSpread({}, replaceNodeId(masterElement)), {}, (_objectSpread7 = {}, _defineProperty(_objectSpread7, REBASE_MARK_KEY.REBASE_TYPE, REBASE_TYPE.MODIFY_MODIFY), _defineProperty(_objectSpread7, REBASE_MARK_KEY.OLD_ELEMENT, masterElement), _defineProperty(_objectSpread7, REBASE_MARK_KEY.ORIGIN, REBASE_ORIGIN.OTHER), _objectSpread7)), _objectSpread(_objectSpread({}, newElement), {}, (_objectSpread8 = {}, _defineProperty(_objectSpread8, REBASE_MARK_KEY.REBASE_TYPE, REBASE_TYPE.MODIFY_MODIFY), _defineProperty(_objectSpread8, REBASE_MARK_KEY.ORIGIN, REBASE_ORIGIN.MY), _objectSpread8))];
117
+ }
118
+ if (modifyType === MODIFY_TYPE.CHILDREN_MODIFY) {
119
+ var _masterElement = _objectSpread({}, diffElement[REBASE_MARK_KEY.OLD_ELEMENT]);
120
+ delete newElement[REBASE_MARK_KEY.OLD_ELEMENT];
121
+
122
+ // revision and master both add a new element, but the content is different. ===》 At present, this situation does not exist, it only exists in the theoretical stage.
123
+ if (!baseElement) {
124
+ var _objectSpread9, _objectSpread10;
125
+ return [_objectSpread(_objectSpread({}, replaceNodeId(_masterElement)), {}, (_objectSpread9 = {}, _defineProperty(_objectSpread9, REBASE_MARK_KEY.REBASE_TYPE, REBASE_TYPE.MODIFY_MODIFY), _defineProperty(_objectSpread9, REBASE_MARK_KEY.OLD_ELEMENT, _masterElement), _defineProperty(_objectSpread9, REBASE_MARK_KEY.ORIGIN, REBASE_ORIGIN.OTHER), _objectSpread9)), _objectSpread(_objectSpread({}, newElement), {}, (_objectSpread10 = {}, _defineProperty(_objectSpread10, REBASE_MARK_KEY.REBASE_TYPE, REBASE_TYPE.MODIFY_MODIFY), _defineProperty(_objectSpread10, REBASE_MARK_KEY.ORIGIN, REBASE_ORIGIN.MY), _objectSpread10))];
126
+ }
127
+ if (ObjectUtils.isSameObject(_masterElement, baseElement)) return [newElement];
128
+ if (ObjectUtils.isSameObject(newElement, baseElement)) return [_masterElement];
129
+ if (ObjectUtils.isSameObject(_masterElement, newElement, ['type'])) {
130
+ if (ObjectUtils.isSameObject(_masterElement, baseElement, ['type'])) return [newElement];
131
+ if (ObjectUtils.isSameObject(newElement, baseElement, ['type'])) return [_masterElement];
132
+ }
133
+
134
+ // The content of the subnode has changed and needs to be solved manually.
135
+ var _getMergeContent = getMergeContent(baseElement, diffElement.children),
136
+ childrenContent = _getMergeContent.content;
137
+ return [_objectSpread(_objectSpread({}, newElement), {}, _defineProperty({
138
+ children: childrenContent
139
+ }, REBASE_MARK_KEY.REBASE_TYPE, REBASE_TYPE.CHILDREN_MODIFY))];
140
+ }
141
+ newElement[REBASE_MARK_KEY.OLD_ELEMENT] && delete newElement[REBASE_MARK_KEY.OLD_ELEMENT];
142
+ return [newElement];
143
+ };
144
+ var getMergeContent = function getMergeContent(baseContent, diffChanges) {
145
+ var _generateIdMapAndIds3 = generateIdMapAndIds(diffChanges),
146
+ diffChangesContentMap = _generateIdMapAndIds3.map,
147
+ diffChangesContentIds = _generateIdMapAndIds3.ids;
148
+ var _generateIdMapAndIds4 = generateIdMapAndIds(baseContent.children),
149
+ baseContentMap = _generateIdMapAndIds4.map;
150
+ var content = [];
151
+ diffChangesContentIds.forEach(function (elementId) {
152
+ var diffElement = diffChangesContentMap[elementId];
153
+ var baseElement = baseContentMap[elementId];
154
+ var mergeElements = getMergeElement(diffElement, baseElement);
155
+ content.push.apply(content, _toConsumableArray(mergeElements));
156
+ });
157
+ var canMerge = !hasConflict(content);
158
+ return {
159
+ content: content,
160
+ canMerge: canMerge
161
+ };
162
+ };
163
+ export var getRebase = function getRebase(masterContent, baseContent, revisionContent) {
164
+ // master no changes, merged directly
165
+ if (masterContent.version === baseContent.version) {
166
+ return {
167
+ canMerge: true,
168
+ isNeedReplaceMaster: true,
169
+ value: revisionContent
170
+ };
171
+ }
172
+
173
+ // The revision content has not changed
174
+ if (baseContent.version === revisionContent.version) {
175
+ return {
176
+ canMerge: true,
177
+ isNeedReplaceMaster: false,
178
+ value: masterContent
179
+ };
180
+ }
181
+ var diffChanges = getChanges(masterContent, revisionContent);
182
+ var _getMergeContent2 = getMergeContent(baseContent, diffChanges),
183
+ canMerge = _getMergeContent2.canMerge,
184
+ content = _getMergeContent2.content;
185
+ return {
186
+ canMerge: canMerge,
187
+ isNeedReplaceMaster: true,
188
+ value: _objectSpread(_objectSpread({}, revisionContent), {}, {
189
+ children: content,
190
+ version: Math.max(masterContent.version, revisionContent.version) + 1
191
+ })
192
+ };
193
+ };
@@ -6,7 +6,8 @@ import { ELEMENT_TYPE, ADDED_STYLE, DELETED_STYLE } from '../extension/constants
6
6
  import SDocViewer from './viewer';
7
7
  import '../../assets/css/diff-viewer.css';
8
8
  var DiffViewer = function DiffViewer(_ref) {
9
- var currentContent = _ref.currentContent,
9
+ var editor = _ref.editor,
10
+ currentContent = _ref.currentContent,
10
11
  lastContent = _ref.lastContent,
11
12
  didMountCallback = _ref.didMountCallback,
12
13
  showToolbar = _ref.showToolbar,
@@ -38,6 +39,7 @@ var DiffViewer = function DiffViewer(_ref) {
38
39
  return renderElement(props, editor);
39
40
  }, []);
40
41
  return /*#__PURE__*/React.createElement(SDocViewer, {
42
+ editor: editor,
41
43
  showToolbar: showToolbar,
42
44
  showOutline: showOutline,
43
45
  document: {
@@ -1,4 +1,4 @@
1
- import React, { Fragment, useMemo } from 'react';
1
+ import React, { Fragment } from 'react';
2
2
  import { Editable, Slate } from '@seafile/slate-react';
3
3
  import { renderLeaf as _renderLeaf, renderElement as _renderElement, createDefaultEditor } from '../extension';
4
4
  import withNodeId from '../node-id';
@@ -8,18 +8,15 @@ import { usePipDecorate } from '../decorates';
8
8
  import { ArticleContainer, EditorContainer, EditorContent } from '../layout';
9
9
  import '../assets/css/simple-viewer.css';
10
10
  var SDocViewer = function SDocViewer(_ref) {
11
- var document = _ref.document,
11
+ var editor = _ref.editor,
12
+ document = _ref.document,
12
13
  customRenderLeaf = _ref.renderLeaf,
13
14
  customRenderElement = _ref.renderElement,
14
15
  showToolbar = _ref.showToolbar,
15
16
  showOutline = _ref.showOutline;
16
- var editor = useMemo(function () {
17
- var defaultEditor = createDefaultEditor();
18
- return withNodeId(defaultEditor);
19
- }, []);
20
- editor.readonly = true;
17
+ var validEditor = editor || withNodeId(createDefaultEditor());
21
18
  var slateValue = (document || generateDefaultDocContent()).children;
22
- var decorate = usePipDecorate(editor);
19
+ var decorate = usePipDecorate(validEditor);
23
20
  return /*#__PURE__*/React.createElement(EditorContainer, {
24
21
  editor: editor,
25
22
  showToolbar: showToolbar,
@@ -29,19 +26,19 @@ var SDocViewer = function SDocViewer(_ref) {
29
26
  readonly: true,
30
27
  showOutline: showOutline
31
28
  }, /*#__PURE__*/React.createElement(Slate, {
32
- editor: editor,
29
+ editor: validEditor,
33
30
  value: slateValue
34
31
  }, /*#__PURE__*/React.createElement(ArticleContainer, {
35
- editor: editor,
32
+ editor: validEditor,
36
33
  readOnly: true
37
34
  }, /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement(SetNodeToDecorations, null), /*#__PURE__*/React.createElement(Editable, {
38
35
  readOnly: true,
39
36
  placeholder: "",
40
37
  renderElement: function renderElement(props) {
41
- return (customRenderElement || _renderElement)(props, editor);
38
+ return (customRenderElement || _renderElement)(props, validEditor);
42
39
  },
43
40
  renderLeaf: function renderLeaf(props) {
44
- return (customRenderLeaf || _renderLeaf)(props, editor);
41
+ return (customRenderLeaf || _renderLeaf)(props, validEditor);
45
42
  },
46
43
  onDOMBeforeInput: function onDOMBeforeInput(event) {},
47
44
  decorate: decorate
@@ -11,14 +11,16 @@ import './style.css';
11
11
  var DocOperations = function DocOperations(_ref) {
12
12
  var isShowChanges = _ref.isShowChanges,
13
13
  changes = _ref.changes,
14
- toggleViewChanges = _ref.toggleViewChanges;
14
+ toggleViewChanges = _ref.toggleViewChanges,
15
+ publishRevision = _ref.publishRevision;
15
16
  var isSdocRevision = context.getSetting('isSdocRevision');
16
17
  return /*#__PURE__*/React.createElement("div", {
17
18
  className: "doc-ops"
18
19
  }, /*#__PURE__*/React.createElement(RevisionOperations, {
19
20
  isShowChanges: isShowChanges,
20
21
  changes: changes,
21
- toggleViewChanges: toggleViewChanges
22
+ toggleViewChanges: toggleViewChanges,
23
+ publishRevision: publishRevision
22
24
  }), /*#__PURE__*/React.createElement(CommentsOperation, null), !isSdocRevision && /*#__PURE__*/React.createElement(ShareOperation, null), /*#__PURE__*/React.createElement(HistoryOperation, null), /*#__PURE__*/React.createElement(CollaboratorsOperation, null), !isSdocRevision && /*#__PURE__*/React.createElement(MoreOperations, null));
23
25
  };
24
26
  export default withTranslation('sdoc-editor')(DocOperations);
@@ -8,7 +8,8 @@ import ChangesCount from './changes-count';
8
8
  var RevisionOperations = function RevisionOperations(_ref) {
9
9
  var isShowChanges = _ref.isShowChanges,
10
10
  changes = _ref.changes,
11
- toggleViewChanges = _ref.toggleViewChanges;
11
+ toggleViewChanges = _ref.toggleViewChanges,
12
+ publishRevision = _ref.publishRevision;
12
13
  var isSdocRevision = context.getSetting('isSdocRevision');
13
14
  var isPublished = context.getSetting('isPublished');
14
15
  return /*#__PURE__*/React.createElement(React.Fragment, null, !isSdocRevision && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(MoreRevisionOperations, null), /*#__PURE__*/React.createElement(Revisions, null)), isSdocRevision && isShowChanges && /*#__PURE__*/React.createElement(ChangesCount, {
@@ -16,6 +17,8 @@ var RevisionOperations = function RevisionOperations(_ref) {
16
17
  }), isSdocRevision && /*#__PURE__*/React.createElement(ViewChanges, {
17
18
  isShowChanges: isShowChanges,
18
19
  toggleViewChanges: toggleViewChanges
19
- }), isSdocRevision && !isPublished && /*#__PURE__*/React.createElement(PublishRevision, null));
20
+ }), isSdocRevision && !isPublished && /*#__PURE__*/React.createElement(PublishRevision, {
21
+ publishRevision: publishRevision
22
+ }));
20
23
  };
21
24
  export default RevisionOperations;
@@ -1,21 +1,14 @@
1
1
  import React, { useCallback } from 'react';
2
+ import { useTranslation } from 'react-i18next';
2
3
  import { Button } from 'reactstrap';
3
- import { withTranslation } from 'react-i18next';
4
- import context from '../../../context';
5
- import toaster from '../../../components/toast';
6
4
  var PublishRevision = function PublishRevision(_ref) {
7
- var t = _ref.t;
8
- var repoID = context.getSetting('repoID');
9
- var siteRoot = context.getSetting('siteRoot');
5
+ var publishRevision = _ref.publishRevision;
6
+ var _useTranslation = useTranslation(),
7
+ t = _useTranslation.t;
10
8
  var publish = useCallback(function (event) {
11
9
  event.stopPropagation();
12
10
  event.nativeEvent.stopImmediatePropagation();
13
- context.publishSdocRevision().then(function (res) {
14
- var origin_file_path = res.data.origin_file_path;
15
- window.location.href = "".concat(siteRoot, "lib/").concat(repoID, "/file/").concat(origin_file_path);
16
- }).catch(function (error) {
17
- toaster.danger(t('Error'));
18
- });
11
+ publishRevision();
19
12
 
20
13
  // eslint-disable-next-line react-hooks/exhaustive-deps
21
14
  }, []);
@@ -25,4 +18,4 @@ var PublishRevision = function PublishRevision(_ref) {
25
18
  className: "ml-4"
26
19
  }, t('Publish'));
27
20
  };
28
- export default withTranslation('sdoc-editor')(PublishRevision);
21
+ export default PublishRevision;
@@ -0,0 +1,50 @@
1
+ import React, { useCallback } from 'react';
2
+ import { useTranslation } from 'react-i18next';
3
+ import { Modal, ModalHeader, ModalBody, ModalFooter, Button } from 'reactstrap';
4
+ import classnames from 'classnames';
5
+ import { TIP_TYPE, TIP_TITLE } from '../../constants';
6
+ import TipContent from './tip-content';
7
+ var NOT_CLOSE_DIALOG_TIP_TYPE = [TIP_TYPE.HAS_BEEN_REPLACED, TIP_TYPE.HAS_BEEN_PUBLISHED];
8
+ var TipDialog = function TipDialog(_ref) {
9
+ var className = _ref.className,
10
+ tipType = _ref.tipType,
11
+ toggle = _ref.toggle,
12
+ submit = _ref.submit;
13
+ var _useTranslation = useTranslation(),
14
+ t = _useTranslation.t;
15
+ var closeDialog = useCallback(function () {
16
+ if (NOT_CLOSE_DIALOG_TIP_TYPE.includes(tipType)) return;
17
+ toggle && toggle();
18
+
19
+ // eslint-disable-next-line react-hooks/exhaustive-deps
20
+ }, [tipType]);
21
+ var confirmTip = useCallback(function () {
22
+ submit && submit();
23
+
24
+ // eslint-disable-next-line react-hooks/exhaustive-deps
25
+ }, []);
26
+ return /*#__PURE__*/React.createElement(Modal, {
27
+ isOpen: true,
28
+ autoFocus: false,
29
+ zIndex: 1071,
30
+ returnFocusAfterClose: false,
31
+ toggle: closeDialog,
32
+ className: classnames('sdoc-tip-dialog', className),
33
+ contentClassName: "sdoc-tip-modal"
34
+ }, /*#__PURE__*/React.createElement(ModalHeader, {
35
+ toggle: NOT_CLOSE_DIALOG_TIP_TYPE.includes(tipType) ? undefined : closeDialog
36
+ }, t(TIP_TITLE[tipType])), /*#__PURE__*/React.createElement(ModalBody, {
37
+ className: "sdoc-tip-body"
38
+ }, /*#__PURE__*/React.createElement(TipContent, {
39
+ tipType: tipType
40
+ })), !NOT_CLOSE_DIALOG_TIP_TYPE.includes(tipType) && /*#__PURE__*/React.createElement(ModalFooter, null, /*#__PURE__*/React.createElement(Button, {
41
+ color: "secondary",
42
+ className: "mr-2",
43
+ onClick: closeDialog
44
+ }, t('Cancel')), /*#__PURE__*/React.createElement(Button, {
45
+ color: "primary",
46
+ className: "highlight-bg-color",
47
+ onClick: confirmTip
48
+ }, t('Confirm'))));
49
+ };
50
+ export default TipDialog;
@@ -0,0 +1,47 @@
1
+ import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
2
+ import React, { useEffect, useState } from 'react';
3
+ import PropTypes from 'prop-types';
4
+ import { useTranslation } from 'react-i18next';
5
+ import { TIP_TYPE, TIP_CONTENT } from '../../constants';
6
+ import context from '../../context';
7
+ var TipContent = function TipContent(_ref) {
8
+ var tipType = _ref.tipType;
9
+ var _useState = useState(3),
10
+ _useState2 = _slicedToArray(_useState, 2),
11
+ time = _useState2[0],
12
+ setTime = _useState2[1];
13
+ useEffect(function () {
14
+ if (tipType === TIP_TYPE.HAS_BEEN_PUBLISHED) {
15
+ var _time = 3;
16
+ var timer = setInterval(function () {
17
+ _time--;
18
+ setTime(_time);
19
+ if (_time === 0) {
20
+ clearInterval(timer);
21
+ timer = null;
22
+ }
23
+ }, 1000);
24
+ return function () {
25
+ timer && clearInterval(timer);
26
+ };
27
+ }
28
+ }, [tipType]);
29
+ useEffect(function () {
30
+ if (time === 0) {
31
+ var originFileURL = context.getSetting('originFileURL');
32
+ window.location.href = originFileURL;
33
+ }
34
+ }, [time]);
35
+ var _useTranslation = useTranslation(),
36
+ t = _useTranslation.t;
37
+ if (tipType === TIP_TYPE.HAS_BEEN_PUBLISHED) {
38
+ return /*#__PURE__*/React.createElement(React.Fragment, null, t(TIP_CONTENT[tipType], {
39
+ time: time
40
+ }));
41
+ }
42
+ return /*#__PURE__*/React.createElement(React.Fragment, null, t(TIP_CONTENT[tipType]));
43
+ };
44
+ TipContent.propTypes = {
45
+ tipType: PropTypes.string
46
+ };
47
+ export default TipContent;