@seafile/sdoc-editor 0.1.69 → 0.1.71

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 (30) hide show
  1. package/dist/api/seafile-api.js +21 -0
  2. package/dist/basic-sdk/editor.js +1 -2
  3. package/dist/basic-sdk/extension/core/queries/index.js +0 -8
  4. package/dist/basic-sdk/extension/core/utils/index.js +1 -0
  5. package/dist/basic-sdk/extension/plugins/check-list/plugin.js +1 -1
  6. package/dist/basic-sdk/extension/plugins/code-block/helpers.js +3 -2
  7. package/dist/basic-sdk/extension/plugins/code-block/plugin.js +3 -2
  8. package/dist/basic-sdk/extension/plugins/code-block/render-elem.js +6 -7
  9. package/dist/basic-sdk/extension/plugins/header/plugin.js +3 -7
  10. package/dist/basic-sdk/extension/plugins/html/rules/code-block.js +37 -10
  11. package/dist/basic-sdk/extension/plugins/html/rules/list.js +1 -0
  12. package/dist/basic-sdk/extension/plugins/link/helpers.js +7 -3
  13. package/dist/basic-sdk/extension/plugins/link/plugin.js +2 -0
  14. package/dist/basic-sdk/extension/plugins/list/model.js +21 -2
  15. package/dist/basic-sdk/extension/plugins/list/plugin/insert-fragment-list.js +8 -16
  16. package/dist/basic-sdk/extension/plugins/list/plugin/normalize-list.js +3 -4
  17. package/dist/basic-sdk/extension/plugins/list/transforms/insert-list-item.js +10 -15
  18. package/dist/basic-sdk/extension/plugins/list/transforms/move-list-item-down.js +3 -5
  19. package/dist/basic-sdk/extension/plugins/list/transforms/move-list-item-up.js +3 -8
  20. package/dist/basic-sdk/extension/plugins/list/transforms/normalize-list-item.js +2 -6
  21. package/dist/basic-sdk/extension/plugins/list/transforms/toggle-list.js +7 -16
  22. package/dist/basic-sdk/extension/plugins/table/plugin.js +3 -3
  23. package/dist/basic-sdk/socket/socket-manager.js +17 -4
  24. package/dist/basic-sdk/views/viewer.js +14 -20
  25. package/dist/components/doc-operations/revision-operations.js +20 -2
  26. package/dist/components/tip-message/index.js +11 -0
  27. package/dist/context.js +8 -0
  28. package/package.json +1 -1
  29. package/public/locales/en/sdoc-editor.json +3 -1
  30. package/public/locales/zh-CN/sdoc-editor.json +3 -1
@@ -12,6 +12,17 @@ var SeafileAPI = /*#__PURE__*/function () {
12
12
  });
13
13
  }
14
14
  _createClass(SeafileAPI, [{
15
+ key: "_sendPostRequest",
16
+ value: function _sendPostRequest(url, form) {
17
+ if (form.getHeaders) {
18
+ return this.req.post(url, form, {
19
+ headers: form.getHeaders()
20
+ });
21
+ } else {
22
+ return this.req.post(url, form);
23
+ }
24
+ }
25
+ }, {
15
26
  key: "getImageFileNameWithTimestamp",
16
27
  value: function getImageFileNameWithTimestamp(file) {
17
28
  var d = Date.now();
@@ -41,6 +52,16 @@ var SeafileAPI = /*#__PURE__*/function () {
41
52
  var url = '/api/v2.1/seadoc/publish-revision/' + docUuid + '/';
42
53
  return this.req.post(url);
43
54
  }
55
+ }, {
56
+ key: "startRevise",
57
+ value: function startRevise(repoID, fileUuid, path) {
58
+ var url = '/api/v2.1/seadoc/revisions/';
59
+ var form = new FormData();
60
+ form.append('p', path);
61
+ form.append('repo_id', repoID);
62
+ form.append('file_uuid', fileUuid);
63
+ return this._sendPostRequest(url, form);
64
+ }
44
65
  }]);
45
66
  return SeafileAPI;
46
67
  }();
@@ -111,8 +111,7 @@ var SDocEditor = function SDocEditor(_ref) {
111
111
  docUuid: config.docUuid
112
112
  }), /*#__PURE__*/React.createElement("div", {
113
113
  ref: scrollRef,
114
- className: "sdoc-editor-article-container",
115
- id: "sdoc-editor-article-container"
114
+ className: "sdoc-editor-article-container"
116
115
  }, /*#__PURE__*/React.createElement(ScrollContext.Provider, {
117
116
  value: {
118
117
  scrollRef: scrollRef
@@ -190,14 +190,6 @@ export var getSelectedElems = function getSelectedElems(editor) {
190
190
  }
191
191
  return elems;
192
192
  };
193
- export var genEmptyParagraph = function genEmptyParagraph() {
194
- return {
195
- type: 'paragraph',
196
- children: [{
197
- text: ''
198
- }]
199
- };
200
- };
201
193
 
202
194
  // siblings
203
195
  export var getNextSiblingNodes = function getNextSiblingNodes(ancestorEntry, path) {
@@ -26,6 +26,7 @@ export var generateDefaultText = function generateDefaultText() {
26
26
  };
27
27
  export var generateEmptyElement = function generateEmptyElement(type) {
28
28
  return {
29
+ id: slugid.nice(),
29
30
  type: type,
30
31
  children: [generateDefaultText()]
31
32
  };
@@ -32,7 +32,7 @@ var withCheckList = function withCheckList(editor) {
32
32
  if (selection && Range.isCollapsed(selection)) {
33
33
  var selectedTodo = getSelectedNodeByType(editor, CHECK_LIST_ITEM);
34
34
  if (selectedTodo) {
35
- // 当前 todo 已经没有文字,则转换为 paragraph
35
+ // If the current todo has no text, it will be converted to a paragraph
36
36
  if (Node.string(selectedTodo).length === 0) {
37
37
  Transforms.setNodes(editor, {
38
38
  type: PARAGRAPH
@@ -58,6 +58,7 @@ export var changeToCodeBlock = function changeToCodeBlock(editor, language) {
58
58
 
59
59
  // Insert the codeBlockNode node
60
60
  var newCodeBlockNode = {
61
+ id: slugid.nice(),
61
62
  type: CODE_BLOCK,
62
63
  language: language,
63
64
  style: {
@@ -94,12 +95,12 @@ export var changeToPlainText = function changeToPlainText(editor) {
94
95
  // Insert p node
95
96
  var pList = str.split('\n').map(function (s) {
96
97
  return {
98
+ id: elem.id,
97
99
  type: 'paragraph',
98
100
  children: [{
99
101
  text: s,
100
102
  id: slugid.nice()
101
- }],
102
- id: elem.id
103
+ }]
103
104
  };
104
105
  });
105
106
  Transforms.insertNodes(editor, pList, {
@@ -3,7 +3,7 @@ import _toArray from "@babel/runtime/helpers/esm/toArray";
3
3
  import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
4
4
  import slugid from 'slugid';
5
5
  import { Transforms, Node, Range, Editor } from '@seafile/slate';
6
- import { getNodeType, isLastNode, genEmptyParagraph, getSelectedNodeByType, generateEmptyElement } from '../../core';
6
+ import { getNodeType, isLastNode, getSelectedNodeByType, generateEmptyElement } from '../../core';
7
7
  import { CODE_BLOCK, PARAGRAPH, CODE_LINE } from '../../constants';
8
8
  var withCodeBlock = function withCodeBlock(editor) {
9
9
  var normalizeNode = editor.normalizeNode,
@@ -84,7 +84,8 @@ var withCodeBlock = function withCodeBlock(editor) {
84
84
  // code-block is the last node in the editor and needs to be followed by a p node
85
85
  var isLast = isLastNode(newEditor, node);
86
86
  if (isLast) {
87
- Transforms.insertNodes(newEditor, genEmptyParagraph(), {
87
+ var paragraph = generateEmptyElement(PARAGRAPH);
88
+ Transforms.insertNodes(newEditor, paragraph, {
88
89
  at: [path[0] + 1]
89
90
  });
90
91
  }
@@ -3,12 +3,15 @@ import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
3
3
  import React, { useCallback, useEffect, useState, useRef } from 'react';
4
4
  import { ReactEditor, useSlateStatic, useReadOnly } from '@seafile/slate-react';
5
5
  import { Transforms } from '@seafile/slate';
6
+ import { useScrollContext } from '../../../hooks/use-scroll-context';
6
7
  import CodeBlockHoverMenu from '../../../../components/code-block-hover-menu';
7
8
  import '../../../assets/css/code-block.css';
8
9
  var CodeBlock = function CodeBlock(_ref) {
9
10
  var codeBlockProps = _ref.codeBlockProps;
10
11
  var readOnly = useReadOnly();
12
+ var editor = useSlateStatic();
11
13
  var codeBlockRef = useRef();
14
+ var scrollRef = useScrollContext();
12
15
  var attributes = codeBlockProps.attributes,
13
16
  children = codeBlockProps.children,
14
17
  element = codeBlockProps.element;
@@ -17,7 +20,6 @@ var CodeBlock = function CodeBlock(_ref) {
17
20
  white_space: 'nowrap'
18
21
  } : _element$style;
19
22
  var white_space = style.white_space;
20
- var editor = useSlateStatic();
21
23
  var _useState = useState({
22
24
  top: '',
23
25
  left: ''
@@ -97,15 +99,12 @@ var CodeBlock = function CodeBlock(_ref) {
97
99
  // eslint-disable-next-line react-hooks/exhaustive-deps
98
100
  }, []);
99
101
  useEffect(function () {
102
+ if (readOnly) return;
100
103
  if (showHoverMenu) {
101
- document.getElementById('sdoc-editor-article-container').addEventListener('scroll', onScroll);
104
+ scrollRef.current && scrollRef.current.addEventListener('scroll', onScroll);
102
105
  } else {
103
- document.getElementById('sdoc-editor-article-container').removeEventListener('scroll', onScroll);
106
+ scrollRef.current && scrollRef.current.removeEventListener('scroll', onScroll);
104
107
  }
105
- return function () {
106
- var articleContainer = document.getElementById('sdoc-editor-article-container');
107
- articleContainer && articleContainer.removeEventListener('scroll', onScroll);
108
- };
109
108
  // eslint-disable-next-line react-hooks/exhaustive-deps
110
109
  }, [showHoverMenu]);
111
110
  return /*#__PURE__*/React.createElement("div", {
@@ -12,19 +12,17 @@ var withHeader = function withHeader(editor) {
12
12
  var insertBreak = editor.insertBreak;
13
13
  var newEditor = editor;
14
14
 
15
- // 重写 insertBreak - header 末尾回车时要插入 paragraph
15
+ // Rewrite insertBreak - insert paragraph when carriage return at the end of header
16
16
  newEditor.insertBreak = function () {
17
17
  var _Editor$nodes = Editor.nodes(newEditor, {
18
18
  match: function match(n) {
19
19
  return Element.isElement(n) && n.type.startsWith('header');
20
20
  },
21
- // 匹配 node.type header 开头的 node
21
+ // Matches nodes whose node.type starts with header
22
22
  universal: true
23
23
  }),
24
24
  _Editor$nodes2 = _slicedToArray(_Editor$nodes, 1),
25
25
  match = _Editor$nodes2[0];
26
-
27
- // 未匹配到
28
26
  if (!match) {
29
27
  insertBreak();
30
28
  return;
@@ -43,7 +41,7 @@ var withHeader = function withHeader(editor) {
43
41
  }
44
42
  var isAtLineEnd = isSelectionAtLineEnd(editor, match[1]);
45
43
 
46
- // 如果在行末插入一个空 p,否则正常换行
44
+ // If an empty p is inserted at the end of the line, otherwise wrap normally
47
45
  if (isAtLineEnd) {
48
46
  var p = generateEmptyElement(PARAGRAPH);
49
47
  Transforms.insertNodes(newEditor, p, {
@@ -53,8 +51,6 @@ var withHeader = function withHeader(editor) {
53
51
  insertBreak();
54
52
  }
55
53
  };
56
-
57
- // 返回 editor
58
54
  return newEditor;
59
55
  };
60
56
  export default withHeader;
@@ -1,27 +1,54 @@
1
1
  import slugid from 'slugid';
2
2
  import { CODE_BLOCK, CODE_LINE } from '../../../constants';
3
+ import { genCodeLangs } from '../../../../utils/prismjs';
3
4
  var codeBlockRule = function codeBlockRule(element, parseChild) {
4
5
  var nodeName = element.nodeName,
5
6
  childNodes = element.childNodes;
6
7
  if (nodeName === 'PRE') {
8
+ var children = Array.from(childNodes).filter(function (item) {
9
+ return item.nodeName === 'CODE';
10
+ });
11
+ var codeChild = children[0];
12
+ var lang = codeChild.getAttribute('lang');
13
+ lang = genCodeLangs().find(function (item) {
14
+ return item.value === lang;
15
+ }) || 'plaintext';
7
16
  return {
8
17
  level: 'level1',
9
18
  id: slugid.nice(),
19
+ language: lang,
10
20
  type: CODE_BLOCK,
11
- children: parseChild(childNodes)
21
+ children: parseChild(children)
12
22
  };
13
23
  }
14
24
  if (nodeName === 'CODE' && element.parentElement.nodeName === 'PRE') {
15
- return {
16
- level: 'level2',
17
- id: slugid.nice(),
18
- type: CODE_LINE,
19
- children: [{
20
- level: 'level3',
25
+ var content = element.textContent;
26
+ var hasNewLine = content.indexOf('\n') > -1;
27
+ if (!hasNewLine) {
28
+ return {
29
+ level: 'level2',
21
30
  id: slugid.nice(),
22
- text: element.textContent
23
- }]
24
- };
31
+ type: CODE_LINE,
32
+ children: [{
33
+ level: 'level3',
34
+ id: slugid.nice(),
35
+ text: element.textContent
36
+ }]
37
+ };
38
+ }
39
+ var codes = content.split('\n');
40
+ return codes.map(function (item) {
41
+ return {
42
+ level: 'level2',
43
+ id: slugid.nice(),
44
+ type: CODE_LINE,
45
+ children: [{
46
+ level: 'level3',
47
+ id: slugid.nice(),
48
+ text: item
49
+ }]
50
+ };
51
+ });
25
52
  }
26
53
  return;
27
54
  };
@@ -34,6 +34,7 @@ var listRule = function listRule(element, parseChild) {
34
34
  id: slugid.nice(),
35
35
  type: LIST_ITEM,
36
36
  children: [{
37
+ id: slugid.nice(),
37
38
  level: 'level3',
38
39
  type: LIST_LIC,
39
40
  children: parseChild(childNodes)
@@ -3,6 +3,7 @@ import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
3
3
  import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
4
4
  function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return exports; }; var exports = {}, Op = Object.prototype, hasOwn = Op.hasOwnProperty, defineProperty = Object.defineProperty || function (obj, key, desc) { obj[key] = desc.value; }, $Symbol = "function" == typeof Symbol ? Symbol : {}, iteratorSymbol = $Symbol.iterator || "@@iterator", asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator", toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag"; function define(obj, key, value) { return Object.defineProperty(obj, key, { value: value, enumerable: !0, configurable: !0, writable: !0 }), obj[key]; } try { define({}, ""); } catch (err) { define = function define(obj, key, value) { return obj[key] = value; }; } function wrap(innerFn, outerFn, self, tryLocsList) { var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator, generator = Object.create(protoGenerator.prototype), context = new Context(tryLocsList || []); return defineProperty(generator, "_invoke", { value: makeInvokeMethod(innerFn, self, context) }), generator; } function tryCatch(fn, obj, arg) { try { return { type: "normal", arg: fn.call(obj, arg) }; } catch (err) { return { type: "throw", arg: err }; } } exports.wrap = wrap; var ContinueSentinel = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var IteratorPrototype = {}; define(IteratorPrototype, iteratorSymbol, function () { return this; }); var getProto = Object.getPrototypeOf, NativeIteratorPrototype = getProto && getProto(getProto(values([]))); NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol) && (IteratorPrototype = NativeIteratorPrototype); var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype); function defineIteratorMethods(prototype) { ["next", "throw", "return"].forEach(function (method) { define(prototype, method, function (arg) { return this._invoke(method, arg); }); }); } function AsyncIterator(generator, PromiseImpl) { function invoke(method, arg, resolve, reject) { var record = tryCatch(generator[method], generator, arg); if ("throw" !== record.type) { var result = record.arg, value = result.value; return value && "object" == typeof value && hasOwn.call(value, "__await") ? PromiseImpl.resolve(value.__await).then(function (value) { invoke("next", value, resolve, reject); }, function (err) { invoke("throw", err, resolve, reject); }) : PromiseImpl.resolve(value).then(function (unwrapped) { result.value = unwrapped, resolve(result); }, function (error) { return invoke("throw", error, resolve, reject); }); } reject(record.arg); } var previousPromise; defineProperty(this, "_invoke", { value: function value(method, arg) { function callInvokeWithMethodAndArg() { return new PromiseImpl(function (resolve, reject) { invoke(method, arg, resolve, reject); }); } return previousPromise = previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(innerFn, self, context) { var state = "suspendedStart"; return function (method, arg) { if ("executing" === state) throw new Error("Generator is already running"); if ("completed" === state) { if ("throw" === method) throw arg; return doneResult(); } for (context.method = method, context.arg = arg;;) { var delegate = context.delegate; if (delegate) { var delegateResult = maybeInvokeDelegate(delegate, context); if (delegateResult) { if (delegateResult === ContinueSentinel) continue; return delegateResult; } } if ("next" === context.method) context.sent = context._sent = context.arg;else if ("throw" === context.method) { if ("suspendedStart" === state) throw state = "completed", context.arg; context.dispatchException(context.arg); } else "return" === context.method && context.abrupt("return", context.arg); state = "executing"; var record = tryCatch(innerFn, self, context); if ("normal" === record.type) { if (state = context.done ? "completed" : "suspendedYield", record.arg === ContinueSentinel) continue; return { value: record.arg, done: context.done }; } "throw" === record.type && (state = "completed", context.method = "throw", context.arg = record.arg); } }; } function maybeInvokeDelegate(delegate, context) { var methodName = context.method, method = delegate.iterator[methodName]; if (undefined === method) return context.delegate = null, "throw" === methodName && delegate.iterator.return && (context.method = "return", context.arg = undefined, maybeInvokeDelegate(delegate, context), "throw" === context.method) || "return" !== methodName && (context.method = "throw", context.arg = new TypeError("The iterator does not provide a '" + methodName + "' method")), ContinueSentinel; var record = tryCatch(method, delegate.iterator, context.arg); if ("throw" === record.type) return context.method = "throw", context.arg = record.arg, context.delegate = null, ContinueSentinel; var info = record.arg; return info ? info.done ? (context[delegate.resultName] = info.value, context.next = delegate.nextLoc, "return" !== context.method && (context.method = "next", context.arg = undefined), context.delegate = null, ContinueSentinel) : info : (context.method = "throw", context.arg = new TypeError("iterator result is not an object"), context.delegate = null, ContinueSentinel); } function pushTryEntry(locs) { var entry = { tryLoc: locs[0] }; 1 in locs && (entry.catchLoc = locs[1]), 2 in locs && (entry.finallyLoc = locs[2], entry.afterLoc = locs[3]), this.tryEntries.push(entry); } function resetTryEntry(entry) { var record = entry.completion || {}; record.type = "normal", delete record.arg, entry.completion = record; } function Context(tryLocsList) { this.tryEntries = [{ tryLoc: "root" }], tryLocsList.forEach(pushTryEntry, this), this.reset(!0); } function values(iterable) { if (iterable) { var iteratorMethod = iterable[iteratorSymbol]; if (iteratorMethod) return iteratorMethod.call(iterable); if ("function" == typeof iterable.next) return iterable; if (!isNaN(iterable.length)) { var i = -1, next = function next() { for (; ++i < iterable.length;) if (hasOwn.call(iterable, i)) return next.value = iterable[i], next.done = !1, next; return next.value = undefined, next.done = !0, next; }; return next.next = next; } } return { next: doneResult }; } function doneResult() { return { value: undefined, done: !0 }; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, defineProperty(Gp, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), defineProperty(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, toStringTagSymbol, "GeneratorFunction"), exports.isGeneratorFunction = function (genFun) { var ctor = "function" == typeof genFun && genFun.constructor; return !!ctor && (ctor === GeneratorFunction || "GeneratorFunction" === (ctor.displayName || ctor.name)); }, exports.mark = function (genFun) { return Object.setPrototypeOf ? Object.setPrototypeOf(genFun, GeneratorFunctionPrototype) : (genFun.__proto__ = GeneratorFunctionPrototype, define(genFun, toStringTagSymbol, "GeneratorFunction")), genFun.prototype = Object.create(Gp), genFun; }, exports.awrap = function (arg) { return { __await: arg }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, asyncIteratorSymbol, function () { return this; }), exports.AsyncIterator = AsyncIterator, exports.async = function (innerFn, outerFn, self, tryLocsList, PromiseImpl) { void 0 === PromiseImpl && (PromiseImpl = Promise); var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList), PromiseImpl); return exports.isGeneratorFunction(outerFn) ? iter : iter.next().then(function (result) { return result.done ? result.value : iter.next(); }); }, defineIteratorMethods(Gp), define(Gp, toStringTagSymbol, "Generator"), define(Gp, iteratorSymbol, function () { return this; }), define(Gp, "toString", function () { return "[object Generator]"; }), exports.keys = function (val) { var object = Object(val), keys = []; for (var key in object) keys.push(key); return keys.reverse(), function next() { for (; keys.length;) { var key = keys.pop(); if (key in object) return next.value = key, next.done = !1, next; } return next.done = !0, next; }; }, exports.values = values, Context.prototype = { constructor: Context, reset: function reset(skipTempReset) { if (this.prev = 0, this.next = 0, this.sent = this._sent = undefined, this.done = !1, this.delegate = null, this.method = "next", this.arg = undefined, this.tryEntries.forEach(resetTryEntry), !skipTempReset) for (var name in this) "t" === name.charAt(0) && hasOwn.call(this, name) && !isNaN(+name.slice(1)) && (this[name] = undefined); }, stop: function stop() { this.done = !0; var rootRecord = this.tryEntries[0].completion; if ("throw" === rootRecord.type) throw rootRecord.arg; return this.rval; }, dispatchException: function dispatchException(exception) { if (this.done) throw exception; var context = this; function handle(loc, caught) { return record.type = "throw", record.arg = exception, context.next = loc, caught && (context.method = "next", context.arg = undefined), !!caught; } for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i], record = entry.completion; if ("root" === entry.tryLoc) return handle("end"); if (entry.tryLoc <= this.prev) { var hasCatch = hasOwn.call(entry, "catchLoc"), hasFinally = hasOwn.call(entry, "finallyLoc"); if (hasCatch && hasFinally) { if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0); if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc); } else if (hasCatch) { if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0); } else { if (!hasFinally) throw new Error("try statement without catch or finally"); if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc); } } } }, abrupt: function abrupt(type, arg) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) { var finallyEntry = entry; break; } } finallyEntry && ("break" === type || "continue" === type) && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc && (finallyEntry = null); var record = finallyEntry ? finallyEntry.completion : {}; return record.type = type, record.arg = arg, finallyEntry ? (this.method = "next", this.next = finallyEntry.finallyLoc, ContinueSentinel) : this.complete(record); }, complete: function complete(record, afterLoc) { if ("throw" === record.type) throw record.arg; return "break" === record.type || "continue" === record.type ? this.next = record.arg : "return" === record.type ? (this.rval = this.arg = record.arg, this.method = "return", this.next = "end") : "normal" === record.type && afterLoc && (this.next = afterLoc), ContinueSentinel; }, finish: function finish(finallyLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.finallyLoc === finallyLoc) return this.complete(entry.completion, entry.afterLoc), resetTryEntry(entry), ContinueSentinel; } }, catch: function _catch(tryLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc === tryLoc) { var record = entry.completion; if ("throw" === record.type) { var thrown = record.arg; resetTryEntry(entry); } return thrown; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(iterable, resultName, nextLoc) { return this.delegate = { iterator: values(iterable), resultName: resultName, nextLoc: nextLoc }, "next" === this.method && (this.arg = undefined), ContinueSentinel; } }, exports; }
5
5
  import { Editor, Transforms, Range } from '@seafile/slate';
6
+ import slugid from 'slugid';
6
7
  import { LINK } from '../../constants';
7
8
  import { getNodeType, getSelectedElems, getAboveNode, getEditorString, replaceNodeChildren } from '../../core';
8
9
  export var isMenuDisabled = function isMenuDisabled(editor) {
@@ -26,12 +27,14 @@ export var checkLink = function checkLink(url) {
26
27
  };
27
28
  export var genLinkNode = function genLinkNode(url, text) {
28
29
  var linkNode = {
30
+ id: slugid.nice(),
29
31
  type: 'link',
30
32
  href: url,
31
33
  title: text,
32
- children: text ? [{
33
- text: text
34
- }] : []
34
+ children: [{
35
+ id: slugid.nice(),
36
+ text: text || ''
37
+ }]
35
38
  };
36
39
  return linkNode;
37
40
  };
@@ -64,6 +67,7 @@ export var insertLink = function insertLink(editor, text, url) {
64
67
 
65
68
  // Not being able to use insertText directly causes the added Spaces to be added to the linked text, as in the issue above, replaced by insertFragment
66
69
  editor.insertFragment([{
70
+ id: slugid.nice(),
67
71
  text: ' '
68
72
  }]);
69
73
  } else {
@@ -1,5 +1,6 @@
1
1
  import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
2
2
  import { Transforms, Node } from '@seafile/slate';
3
+ import slugid from 'slugid';
3
4
  import isUrl from 'is-url';
4
5
  import { genLinkNode } from './helpers';
5
6
  import { getNodeType } from '../../core';
@@ -31,6 +32,7 @@ var withLink = function withLink(editor) {
31
32
  }
32
33
  var link = genLinkNode(text, text);
33
34
  Transforms.insertNodes(newEditor, [link, {
35
+ id: slugid.nice(),
34
36
  text: ' '
35
37
  }]);
36
38
  return;
@@ -1,6 +1,8 @@
1
1
  import _createClass from "@babel/runtime/helpers/esm/createClass";
2
2
  import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
3
- import { UNORDERED_LIST } from '../../constants';
3
+ import slugid from 'slugid';
4
+ import { LIST_ITEM, LIST_LIC, UNORDERED_LIST } from '../../constants';
5
+ import { generateEmptyElement } from '../../core';
4
6
  var List = /*#__PURE__*/_createClass(function List(options) {
5
7
  _classCallCheck(this, List);
6
8
  this.type = options.type || UNORDERED_LIST;
@@ -8,4 +10,21 @@ var List = /*#__PURE__*/_createClass(function List(options) {
8
10
  text: ''
9
11
  }];
10
12
  });
11
- export default List;
13
+ export default List;
14
+ export var generateEmptyListItem = function generateEmptyListItem() {
15
+ return {
16
+ id: slugid.nice(),
17
+ type: LIST_ITEM,
18
+ children: []
19
+ };
20
+ };
21
+ export var generateEmptyListLic = function generateEmptyListLic() {
22
+ return generateEmptyElement(LIST_LIC);
23
+ };
24
+ export var generateEmptyList = function generateEmptyList(type) {
25
+ return {
26
+ id: slugid.nice(),
27
+ type: type,
28
+ children: []
29
+ };
30
+ };
@@ -2,8 +2,9 @@ import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
2
2
  import _toArray from "@babel/runtime/helpers/esm/toArray";
3
3
  import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
4
4
  import { Element, Path, Transforms, Node, Editor } from '@seafile/slate';
5
+ import slugid from 'slugid';
5
6
  import { LIST_ITEM, LIST_LIC } from '../../../constants';
6
- import { findNode, getCommonNode, getNode, getNodes } from '../../../core';
7
+ import { findNode, generateDefaultText, getCommonNode, getNode, getNodes } from '../../../core';
7
8
  import { getListTypes } from '../queries';
8
9
  var isListRoot = function isListRoot(node) {
9
10
  return Element.isElement(node) && getListTypes().includes(node.type);
@@ -48,6 +49,7 @@ var trimList = function trimList(listRoot) {
48
49
  };
49
50
  var wrapNodeIntoListItem = function wrapNodeIntoListItem(node) {
50
51
  return node.type === LIST_ITEM ? node : {
52
+ id: slugid.nice(),
51
53
  type: LIST_ITEM,
52
54
  children: [node]
53
55
  };
@@ -114,14 +116,10 @@ export var getTextAndListItemNodes = function getTextAndListItemNodes(editor, fr
114
116
  });
115
117
  }
116
118
  }
117
- textNode = {
118
- text: ''
119
- };
119
+ textNode = generateDefaultText();
120
120
  listItemNodes = rest;
121
121
  } else {
122
- textNode = {
123
- text: ''
124
- };
122
+ textNode = generateDefaultText();
125
123
  listItemNodes = [first].concat(_toConsumableArray(rest));
126
124
  }
127
125
  } else {
@@ -148,14 +146,10 @@ export var insertFragmentList = function insertFragmentList(editor) {
148
146
  mode: 'lowest'
149
147
  });
150
148
  if (!liEntry) {
151
- var nodes = isListRoot(fragment) ? [{
152
- text: ''
153
- }].concat(_toConsumableArray(fragment)) : fragment;
149
+ var nodes = isListRoot(fragment) ? [generateDefaultText()].concat(_toConsumableArray(fragment)) : fragment;
154
150
  return _insertFragment(nodes);
155
151
  }
156
- Transforms.insertFragment(editor, [{
157
- text: ''
158
- }]); // need ' '
152
+ Transforms.insertFragment(editor, [generateDefaultText()]); // need ' '
159
153
 
160
154
  liEntry = findNode(editor, {
161
155
  match: {
@@ -170,9 +164,7 @@ export var insertFragmentList = function insertFragmentList(editor) {
170
164
  mode: 'lowest'
171
165
  });
172
166
  if (!licEntry) {
173
- var _nodes = isListRoot(fragment) ? [{
174
- text: ''
175
- }].concat(_toConsumableArray(fragment)) : fragment;
167
+ var _nodes = isListRoot(fragment) ? [generateDefaultText()].concat(_toConsumableArray(fragment)) : fragment;
176
168
  return _insertFragment(_nodes);
177
169
  }
178
170
  var _getTextAndListItemNo = getTextAndListItemNodes(editor, fragment, liEntry, licEntry),
@@ -4,6 +4,7 @@ import { LIST_ITEM, LIST_LIC, PARAGRAPH } from '../../../constants';
4
4
  import { getChildren, getNode, getPreviousPath, match } from '../../../core';
5
5
  import { getListTypes } from '../queries';
6
6
  import { moveListItemsToList, normalizeListItem, normalizeNestedList } from '../transforms';
7
+ import { generateEmptyListItem } from '../model';
7
8
  export var normalizeList = function normalizeList(editor) {
8
9
  var normalizeNode = editor.normalizeNode;
9
10
  return function (_ref) {
@@ -24,10 +25,8 @@ export var normalizeList = function normalizeList(editor) {
24
25
  return child.type !== LIST_ITEM;
25
26
  });
26
27
  if (nonLiChild) {
27
- Transforms.wrapNodes(editor, {
28
- type: LIST_ITEM,
29
- children: []
30
- }, {
28
+ var listItem = generateEmptyListItem();
29
+ Transforms.wrapNodes(editor, listItem, {
31
30
  at: nonLiChild[1]
32
31
  });
33
32
  return;
@@ -2,7 +2,8 @@ import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
2
2
  import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
3
3
  import { Transforms, Editor, Path, Range } from '@seafile/slate';
4
4
  import { LIST_ITEM, LIST_LIC } from '../../../constants';
5
- import { generateEmptyElement, getAboveNode, isBlockTextEmptyAfterSelection, isStartPoint } from '../../../core';
5
+ import { getAboveNode, isBlockTextEmptyAfterSelection, isStartPoint } from '../../../core';
6
+ import { generateEmptyListItem, generateEmptyListLic } from '../model';
6
7
  export var insertListItem = function insertListItem(editor) {
7
8
  var licEntry = getAboveNode(editor, {
8
9
  match: {
@@ -33,14 +34,12 @@ export var insertListItem = function insertListItem(editor) {
33
34
  var nextListItemPath = Path.next(listItemPath);
34
35
  if (_isStartPoint) {
35
36
  // listItem 有内容,光标在开始
36
- var licItem = generateEmptyElement(LIST_LIC);
37
+ var licItem = generateEmptyListLic();
37
38
  Transforms.insertNodes(editor, licItem, {
38
39
  at: listItemPath
39
40
  });
40
- Transforms.wrapNodes(editor, {
41
- type: LIST_ITEM,
42
- children: []
43
- }, {
41
+ var listItem = generateEmptyListItem();
42
+ Transforms.wrapNodes(editor, listItem, {
44
43
  at: listItemPath
45
44
  });
46
45
  success = true;
@@ -49,10 +48,8 @@ export var insertListItem = function insertListItem(editor) {
49
48
  if (!isEndPoint) {
50
49
  // listItem 有内容,光标在中间
51
50
  Transforms.splitNodes(editor);
52
- Transforms.wrapNodes(editor, {
53
- type: LIST_ITEM,
54
- children: []
55
- }, {
51
+ var _listItem = generateEmptyListItem();
52
+ Transforms.wrapNodes(editor, _listItem, {
56
53
  at: nextParagraphPath
57
54
  });
58
55
  Transforms.moveNodes(editor, {
@@ -68,14 +65,12 @@ export var insertListItem = function insertListItem(editor) {
68
65
  var _Editor$marks;
69
66
  // listItem 有内容,光标在结尾
70
67
  var marks = (_Editor$marks = Editor.marks(editor)) === null || _Editor$marks === void 0 ? void 0 : _Editor$marks.key;
71
- var _licItem = generateEmptyElement(LIST_LIC);
68
+ var _licItem = generateEmptyListLic();
72
69
  Transforms.insertNodes(editor, _objectSpread(_objectSpread({}, _licItem), marks), {
73
70
  at: nextListItemPath
74
71
  });
75
- Transforms.wrapNodes(editor, {
76
- type: LIST_ITEM,
77
- children: []
78
- }, {
72
+ var _listItem2 = generateEmptyListItem();
73
+ Transforms.wrapNodes(editor, _listItem2, {
79
74
  at: nextListItemPath
80
75
  });
81
76
  Transforms.select(editor, nextListItemPath);
@@ -1,6 +1,7 @@
1
1
  import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
2
2
  import { Transforms, Path, Editor } from '@seafile/slate';
3
3
  import { getListTypes } from '../queries';
4
+ import { generateEmptyList } from '../model';
4
5
  export var movedListItemDown = function movedListItemDown(editor, _ref) {
5
6
  var list = _ref.list,
6
7
  listItem = _ref.listItem;
@@ -26,11 +27,8 @@ export var movedListItemDown = function movedListItemDown(editor, _ref) {
26
27
  var newPath = previousPath.concat(subList ? [1, subList.children.length] : [1]);
27
28
  Editor.withoutNormalizing(editor, function () {
28
29
  if (!subList) {
29
- var _list2 = {
30
- type: listNode.type,
31
- children: []
32
- };
33
- // 插入一个 list 子元素
30
+ // Insert a list child element
31
+ var _list2 = generateEmptyList(listNode.type);
34
32
  Transforms.wrapNodes(editor, _list2, {
35
33
  at: listItemPath
36
34
  });
@@ -5,6 +5,7 @@ import { getAboveNode, getNode, isLastChild } from '../../../core';
5
5
  import { hasListChild } from '../queries';
6
6
  import { moveListItemsToList } from './move-list-items-to-list';
7
7
  import { unwrapList } from './unwrap-list';
8
+ import { generateEmptyList } from '../model';
8
9
  export var movedListItemUp = function movedListItemUp(editor, _ref) {
9
10
  var list = _ref.list,
10
11
  listItem = _ref.listItem;
@@ -35,11 +36,8 @@ export var movedListItemUp = function movedListItemUp(editor, _ref) {
35
36
  var condA = hasListChild(editor, liNode);
36
37
  var condB = !isLastChild(list, liPath);
37
38
  if (condA || condB) {
38
- var _list2 = {
39
- type: listNode.type,
40
- children: []
41
- };
42
39
  // 创建一个新的兄弟节点
40
+ var _list2 = generateEmptyList(listNode.type);
43
41
  Transforms.insertNodes(editor, _list2, {
44
42
  at: _toListPath
45
43
  });
@@ -90,10 +88,7 @@ export var movedListItemUp = function movedListItemUp(editor, _ref) {
90
88
  // 第一步:把当前节点的兄弟节点,移动到当前节点 “子节点(ol)” 的孩子节点中
91
89
  // 第二步:把当前节点的字节点,移动为当前节点 “父节点” 的 “兄弟” 节点
92
90
  if (!hasListChild(liNode)) {
93
- var _list3 = {
94
- type: listNode.type,
95
- children: []
96
- };
91
+ var _list3 = generateEmptyList(listNode.type);
97
92
  Transforms.insertNodes(editor, _list3, {
98
93
  at: toListPath
99
94
  });
@@ -6,6 +6,7 @@ import { LIST_LIC } from '../../../constants';
6
6
  import { getChildren, getDeepInlineChildren, match } from '../../../core';
7
7
  import { getListTypes } from '../queries';
8
8
  import { movedListItemUp } from './move-list-item-up';
9
+ import { generateEmptyListLic } from '../model';
9
10
  export var normalizeListItem = function normalizeListItem(editor, _ref) {
10
11
  var listItem = _ref.listItem;
11
12
  var changed = false;
@@ -28,12 +29,7 @@ export var normalizeListItem = function normalizeListItem(editor, _ref) {
28
29
  firstLiChildNode = _ref7[0],
29
30
  firstLiChildPath = _ref7[1];
30
31
  if (!firstLiChild || !Editor.isBlock(editor, firstLiChildNode)) {
31
- var emptyLic = {
32
- type: LIST_LIC,
33
- children: [{
34
- text: ''
35
- }]
36
- };
32
+ var emptyLic = generateEmptyListLic();
37
33
  Transforms.insertNodes(editor, emptyLic, {
38
34
  at: liPath.concat([0])
39
35
  });
@@ -5,11 +5,10 @@ import { LIST_ITEM, LIST_LIC, PARAGRAPH } from '../../../constants';
5
5
  import { findNode, getNodeEntries, getNodeType, getSelectedNodeEntryByType, isRangeAcrossBlocks } from '../../../core';
6
6
  import { getListItemEntry, getListTypes } from '../queries';
7
7
  import { unwrapList } from './unwrap-list';
8
+ import { generateEmptyList, generateEmptyListItem } from '../model';
8
9
  var wrapLineList = function wrapLineList(editor, type) {
9
- Transforms.wrapNodes(editor, {
10
- type: type,
11
- children: []
12
- });
10
+ var list = generateEmptyList(type);
11
+ Transforms.wrapNodes(editor, list);
13
12
  var nodeEntry = getSelectedNodeEntryByType(editor, PARAGRAPH);
14
13
  if (!nodeEntry) return;
15
14
  var _nodeEntry = _slicedToArray(nodeEntry, 2),
@@ -21,10 +20,8 @@ var wrapLineList = function wrapLineList(editor, type) {
21
20
  type: LIST_LIC
22
21
  });
23
22
  }
24
- Transforms.wrapNodes(editor, {
25
- type: LIST_ITEM,
26
- children: []
27
- }, {
23
+ var listItem = generateEmptyListItem();
24
+ Transforms.wrapNodes(editor, listItem, {
28
25
  at: path
29
26
  });
30
27
  return;
@@ -101,17 +98,11 @@ var wrapRangeList = function wrapRangeList(editor, type) {
101
98
  at: n[1]
102
99
  });
103
100
  }
104
- var listItem = {
105
- type: LIST_ITEM,
106
- children: []
107
- };
101
+ var listItem = generateEmptyListItem();
108
102
  Transforms.wrapNodes(editor, listItem, {
109
103
  at: n[1]
110
104
  });
111
- var list = {
112
- type: type,
113
- children: []
114
- };
105
+ var list = generateEmptyList(type);
115
106
  Transforms.wrapNodes(editor, list, {
116
107
  at: n[1]
117
108
  });
@@ -5,8 +5,8 @@ import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
5
5
  import isHotkey from 'is-hotkey';
6
6
  import { Editor, Transforms, Point, Path, Node } from '@seafile/slate';
7
7
  import { ReactEditor } from '@seafile/slate-react';
8
- import { getNodeType, getParentNode, getSelectedNodeByType, isTextNode, isLastNode, genEmptyParagraph, replaceNodeChildren, focusEditor, getNode } from '../../core';
9
- import { ELEMENT_TYPE, TABLE_ELEMENT, TABLE_ELEMENT_POSITION, KEYBOARD } from '../../constants';
8
+ import { getNodeType, getParentNode, getSelectedNodeByType, isTextNode, isLastNode, replaceNodeChildren, focusEditor, getNode, generateEmptyElement } from '../../core';
9
+ import { ELEMENT_TYPE, TABLE_ELEMENT, TABLE_ELEMENT_POSITION, KEYBOARD, PARAGRAPH } from '../../constants';
10
10
  import { TABLE_MAX_ROWS, EMPTY_SELECTED_RANGE } from './constants';
11
11
  import ObjectUtils from '../../../utils/object-utils';
12
12
  import { getSelectedInfo, insertTableElement } from './helpers';
@@ -322,7 +322,7 @@ var withTable = function withTable(editor) {
322
322
  // insert empty node,continue editor
323
323
  var isLast = isLastNode(newEditor, node);
324
324
  if (isLast) {
325
- var p = genEmptyParagraph();
325
+ var p = generateEmptyElement(PARAGRAPH);
326
326
  Transforms.insertNodes(newEditor, p, {
327
327
  at: [path[0] + 1]
328
328
  });
@@ -42,10 +42,23 @@ var SocketManager = /*#__PURE__*/_createClass(function SocketManager(editor, doc
42
42
  }
43
43
 
44
44
  // Operations are execute failure
45
- var operations = result.operations;
46
- // Put the failed operation into the pending list and re-execute it
47
- _this.pendingOperationList.unshift(operations);
48
- _this.sendNextOperations();
45
+ var error_type = result.error_type,
46
+ operations = result.operations;
47
+ if (error_type === 'version_behind_server') {
48
+ // Put the failed operation into the pending list and re-execute it
49
+ _this.pendingOperationList.unshift(operations);
50
+ _this.sendNextOperations();
51
+ } else if (error_type === 'operation_exec_error') {
52
+ _this.editor.isRemote = true;
53
+ revertOperationList(_this.editor, [operations]);
54
+
55
+ // reset control flag
56
+ Promise.resolve().then(function (_) {
57
+ _this.editor.isRemote = false;
58
+ _this.dispatchConnectState(error_type);
59
+ _this.sendNextOperations();
60
+ });
61
+ }
49
62
  };
50
63
  this.receiveOperations = function (params) {
51
64
  _this.remoteOperationsList.push(params);
@@ -1,30 +1,21 @@
1
- import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
2
- import React, { useRef, useEffect, useState } from 'react';
1
+ import React, { useRef, useEffect } from 'react';
3
2
  import { Editable, Slate } from '@seafile/slate-react';
4
3
  import defaultEditor, { renderLeaf as _renderLeaf, renderElement as _renderElement } from '../extension';
5
- import { withSocketIO } from '../socket';
6
4
  import withNodeId from '../node-id';
5
+ import { ScrollContext } from '../hooks/use-scroll-context';
6
+ import { generateDefaultDocContent } from '../../utils';
7
7
  import '../assets/css/layout.css';
8
8
  import '../assets/css/sdoc-editor-plugins.css';
9
- import { generateDefaultDocContent } from '../../utils';
10
9
  var SDocViewer = function SDocViewer(_ref) {
11
- var isOpenSocket = _ref.isOpenSocket,
12
- document = _ref.document,
13
- config = _ref.config,
10
+ var document = _ref.document,
14
11
  customRenderLeaf = _ref.renderLeaf,
15
12
  customRenderElement = _ref.renderElement;
16
- var editor = !isOpenSocket ? withNodeId(defaultEditor) : withSocketIO(withNodeId(defaultEditor, {
17
- document: document,
18
- config: config
19
- }));
13
+ var editor = withNodeId(defaultEditor);
20
14
  var slateValue = (document || generateDefaultDocContent()).children;
21
15
  var articleRef = useRef(null);
22
- var _useState = useState(false),
23
- _useState2 = _slicedToArray(_useState, 2),
24
- setUpdate = _useState2[1];
16
+ var scrollRef = useRef(null);
25
17
  useEffect(function () {
26
18
  editor.width = articleRef.current.children[0].clientWidth;
27
- setUpdate(true);
28
19
  // eslint-disable-next-line react-hooks/exhaustive-deps
29
20
  }, []);
30
21
  return /*#__PURE__*/React.createElement("div", {
@@ -32,12 +23,15 @@ var SDocViewer = function SDocViewer(_ref) {
32
23
  }, /*#__PURE__*/React.createElement("div", {
33
24
  className: "sdoc-editor-content"
34
25
  }, /*#__PURE__*/React.createElement("div", {
35
- className: "flex-fill o-auto sdoc-editor-article-container",
36
- id: "sdoc-editor-article-container"
26
+ ref: scrollRef,
27
+ className: "sdoc-editor-article-container"
28
+ }, /*#__PURE__*/React.createElement(ScrollContext.Provider, {
29
+ value: {
30
+ scrollRef: scrollRef
31
+ }
37
32
  }, /*#__PURE__*/React.createElement(Slate, {
38
33
  editor: editor,
39
- value: slateValue,
40
- onChange: function onChange() {}
34
+ value: slateValue
41
35
  }, /*#__PURE__*/React.createElement("div", {
42
36
  className: "article mx-auto",
43
37
  ref: articleRef
@@ -51,6 +45,6 @@ var SDocViewer = function SDocViewer(_ref) {
51
45
  return (customRenderLeaf || _renderLeaf)(props, editor);
52
46
  },
53
47
  onDOMBeforeInput: function onDOMBeforeInput(event) {}
54
- }))))));
48
+ })))))));
55
49
  };
56
50
  export default SDocViewer;
@@ -29,8 +29,26 @@ var RevisionOperations = function RevisionOperations(_ref) {
29
29
 
30
30
  // eslint-disable-next-line react-hooks/exhaustive-deps
31
31
  }, []);
32
- if (!isSdocRevision) return null;
33
- return /*#__PURE__*/React.createElement(React.Fragment, null, !isPublished && revisionURL && /*#__PURE__*/React.createElement(Button, {
32
+ var startRevise = useCallback(function () {
33
+ context.startRevise().then(function (res) {
34
+ window.location.href = "".concat(siteRoot, "lib/").concat(repoID, "/file").concat(res.data.file_path);
35
+ }).catch(function (error) {
36
+ toaster.danger(t('Error'));
37
+ });
38
+
39
+ // eslint-disable-next-line react-hooks/exhaustive-deps
40
+ }, []);
41
+ var startReviseBtn = useCallback(function (className) {
42
+ return /*#__PURE__*/React.createElement(Button, {
43
+ color: "success",
44
+ className: className,
45
+ onClick: startRevise
46
+ }, t('Start_revise'));
47
+
48
+ // eslint-disable-next-line react-hooks/exhaustive-deps
49
+ }, []);
50
+ if (!isSdocRevision) return startReviseBtn();
51
+ return /*#__PURE__*/React.createElement(React.Fragment, null, startReviseBtn('mr-4'), !isPublished && revisionURL && /*#__PURE__*/React.createElement(Button, {
34
52
  color: "success",
35
53
  className: "mr-4",
36
54
  onClick: viewChanges
@@ -14,6 +14,14 @@ var TipMessage = /*#__PURE__*/function (_React$Component) {
14
14
  var _this;
15
15
  _classCallCheck(this, TipMessage);
16
16
  _this = _super.call(this, props);
17
+ _this.onOperationExecuteError = function () {
18
+ var t = _this.props.t;
19
+ var message = t('Failed_to_execute_operation_on_server');
20
+ toaster.danger(message, {
21
+ hasCloseButton: true,
22
+ duration: null
23
+ });
24
+ };
17
25
  _this.onDisconnect = function () {
18
26
  var t = _this.props.t;
19
27
  var message = t('Server_is_not_connected_Operation_will_be_sent_to_server_later');
@@ -97,6 +105,9 @@ var TipMessage = /*#__PURE__*/function (_React$Component) {
97
105
  this.unsubscribeDisconnectEvent = eventBus.subscribe('disconnect', this.onDisconnect);
98
106
  this.unsubscribeReconnectErrorEvent = eventBus.subscribe('reconnect_error', this.onReconnectError);
99
107
  this.unsubscribeReconnectEvent = eventBus.subscribe('reconnect', this.onReconnect);
108
+
109
+ // op execute error
110
+ this.unsubscribeOpExecError = eventBus.subscribe('operation_exec_error', this.onOperationExecuteError);
100
111
  }
101
112
  }, {
102
113
  key: "componentWillUnmount",
package/dist/context.js CHANGED
@@ -125,6 +125,14 @@ var Context = /*#__PURE__*/function () {
125
125
  }
126
126
 
127
127
  // revision
128
+ }, {
129
+ key: "startRevise",
130
+ value: function startRevise() {
131
+ var repoID = this.getSetting('repoID');
132
+ var filePath = this.getSetting('docPath');
133
+ var fileUuid = this.getSetting('docUuid');
134
+ return this.api.startRevise(repoID, fileUuid, filePath);
135
+ }
128
136
  }, {
129
137
  key: "publishSdocRevision",
130
138
  value: function publishSdocRevision() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seafile/sdoc-editor",
3
- "version": "0.1.69",
3
+ "version": "0.1.71",
4
4
  "private": false,
5
5
  "description": "This is a sdoc editor",
6
6
  "main": "dist/index.js",
@@ -254,5 +254,7 @@
254
254
  "Confirm": "Confirm",
255
255
  "View_changes": "View changes",
256
256
  "Revision": "Revision",
257
- "Error": "Error"
257
+ "Error": "Error",
258
+ "Start_revise": "Start revise",
259
+ "Failed_to_execute_operation_on_server": "Failed to execute operation on server"
258
260
  }
@@ -254,5 +254,7 @@
254
254
  "Confirm": "确定",
255
255
  "View_changes": "查看改动",
256
256
  "Revision": "修订",
257
- "Error": "错误"
257
+ "Error": "错误",
258
+ "Start_revise": "开始修订",
259
+ "Failed_to_execute_operation_on_server": "无法在服务器上执行操作"
258
260
  }