@seafile/sdoc-editor 0.3.22 → 0.3.24

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 (38) hide show
  1. package/dist/api/seafile-api.js +8 -6
  2. package/dist/basic-sdk/assets/css/sdoc-editor-plugins.css +1 -0
  3. package/dist/basic-sdk/comment/components/comment-item-wrapper.js +5 -3
  4. package/dist/basic-sdk/comment/components/comment-list.css +15 -7
  5. package/dist/basic-sdk/comment/components/global-comment/index.css +1 -1
  6. package/dist/basic-sdk/editor/revision-editor.js +74 -0
  7. package/dist/basic-sdk/editor/sdoc-editor.js +23 -18
  8. package/dist/basic-sdk/extension/commons/insert-element-dialog/index.js +3 -2
  9. package/dist/basic-sdk/extension/plugins/image/helpers.js +8 -6
  10. package/dist/basic-sdk/extension/plugins/image/plugin.js +1 -1
  11. package/dist/basic-sdk/extension/plugins/table/constants/index.js +4 -4
  12. package/dist/basic-sdk/extension/plugins/table/helpers.js +11 -2
  13. package/dist/basic-sdk/extension/plugins/table/popover/table-template/index.js +2 -2
  14. package/dist/basic-sdk/extension/plugins/table/popover/table-template/sample-table.js +13 -15
  15. package/dist/basic-sdk/extension/plugins/table/render/alternate-color.css +8 -8
  16. package/dist/basic-sdk/extension/plugins/table/render/index.js +2 -5
  17. package/dist/basic-sdk/extension/plugins/table/render/render-cell.js +22 -4
  18. package/dist/basic-sdk/index.js +2 -1
  19. package/dist/basic-sdk/socket/socket-manager.js +6 -0
  20. package/dist/basic-sdk/socket/with-socket-io.js +1 -0
  21. package/dist/basic-sdk/views/revision-diff-viewer.js +6 -0
  22. package/dist/context.js +2 -2
  23. package/dist/pages/simple-editor.js +28 -14
  24. package/package.json +1 -1
  25. package/public/locales/cs/sdoc-editor.json +8 -1
  26. package/public/locales/de/sdoc-editor.json +8 -1
  27. package/public/locales/en/sdoc-editor.json +1 -0
  28. package/public/locales/es/sdoc-editor.json +8 -1
  29. package/public/locales/fr/sdoc-editor.json +8 -1
  30. package/public/locales/it/sdoc-editor.json +8 -1
  31. package/public/locales/ru/sdoc-editor.json +10 -3
  32. package/public/locales/zh_CN/sdoc-editor.json +1 -0
  33. package/public/media/sdoc-editor-font/iconfont.eot +0 -0
  34. package/public/media/sdoc-editor-font/iconfont.svg +3 -9
  35. package/public/media/sdoc-editor-font/iconfont.ttf +0 -0
  36. package/public/media/sdoc-editor-font/iconfont.woff +0 -0
  37. package/public/media/sdoc-editor-font/iconfont.woff2 +0 -0
  38. package/public/media/sdoc-editor-font.css +13 -12
@@ -29,14 +29,16 @@ class SeafileAPI {
29
29
  var d = Date.now();
30
30
  return 'image-' + d.toString() + file.name.slice(file.name.lastIndexOf('.'));
31
31
  }
32
- uploadSdocImage(docUuid, imageFile) {
32
+ uploadSdocImage(docUuid, imageFiles) {
33
33
  const url = '/api/v2.1/seadoc/upload-image/' + docUuid + '/';
34
34
  const form = new FormData();
35
- const fileName = this.getImageFileNameWithTimestamp(imageFile);
36
- const file = new File([imageFile], fileName, {
37
- type: imageFile.type
38
- });
39
- form.append('file', file);
35
+ for (const fileItem of imageFiles) {
36
+ const fileName = this.getImageFileNameWithTimestamp(fileItem);
37
+ const file = new File([fileItem], fileName, {
38
+ type: fileItem.type
39
+ });
40
+ form.append('file', file);
41
+ }
40
42
  return this.req.post(url, form);
41
43
  }
42
44
  getSdocDownloadImageUrl(docUuid, imageName) {
@@ -165,4 +165,5 @@
165
165
 
166
166
  .sdoc-editor-container .article .virtual-link:hover {
167
167
  text-decoration: underline;
168
+ text-underline-position: under;
168
169
  }
@@ -238,10 +238,12 @@ const CommentItemWrapper = _ref => {
238
238
  className: className,
239
239
  onClick: onItemClick
240
240
  }, element && /*#__PURE__*/React.createElement("div", {
241
- className: "comment-item-selected-text"
241
+ className: "comment-item-selected-text-container"
242
242
  }, /*#__PURE__*/React.createElement("i", {
243
- className: "sdocfont sdoc-selected-text mr-2"
244
- }), Node.string(element)), /*#__PURE__*/React.createElement("ul", {
243
+ className: "sdocfont sdoc-comment-quote mr-2"
244
+ }), /*#__PURE__*/React.createElement("div", {
245
+ className: "comment-item-selected-text"
246
+ }, Node.string(element))), /*#__PURE__*/React.createElement("ul", {
245
247
  ref: listRef,
246
248
  className: "comment-item-list"
247
249
  }, /*#__PURE__*/React.createElement(CommentItemContent, {
@@ -18,19 +18,27 @@
18
18
  box-shadow: 0 1px 3px rgba(0,0,0,.3), 0 4px 8px 3px rgba(0,0,0,.15);
19
19
  }
20
20
 
21
- .sdoc-comment-list-container .comment-item-selected-text {
22
- padding: 6px 16px;
21
+ .sdoc-comment-list-container .comment-item-selected-text-container {
23
22
  width: 100%;
23
+ height: 32px;
24
+ display: flex;
25
+ padding: 6px 16px;
26
+ align-items: center;
24
27
  overflow: hidden;
25
- text-overflow: ellipsis;
26
- white-space: nowrap;
27
- font-size: 14px;
28
- line-height: 20px;
29
28
  border-radius: 8px 8px 0 0;
30
29
  }
31
30
 
32
- .sdoc-comment-list-container .comment-item-selected-text .sdoc-selected-text {
31
+ .sdoc-comment-list-container .comment-item-selected-text-container .sdoc-comment-quote {
33
32
  font-size: 12px;
33
+ flex-shrink: 0;
34
+ }
35
+
36
+ .sdoc-comment-list-container .comment-item-selected-text-container .comment-item-selected-text {
37
+ flex: 1;
38
+ font-size: 14px;
39
+ overflow: hidden;
40
+ text-overflow: ellipsis;
41
+ white-space: nowrap;
34
42
  }
35
43
 
36
44
  .sdoc-comment-list-container .comment-item-list {
@@ -136,7 +136,7 @@
136
136
  border: 1px solid #c7c7c7;
137
137
  }
138
138
 
139
- .global-comments-popover .sdoc-comment-list-container .comment-item-selected-text {
139
+ .global-comments-popover .sdoc-comment-list-container .comment-item-selected-text-container {
140
140
  background-color: #F5F5F5;
141
141
  border-bottom: 1px solid #c7c7c7;
142
142
  }
@@ -0,0 +1,74 @@
1
+ import React, { useEffect, useRef, useImperativeHandle, forwardRef, useMemo } from 'react';
2
+ import SdocEditor from './sdoc-editor';
3
+ import { RevisionDiffViewer } from '../views';
4
+ import context from '../../context';
5
+ import { createDefaultEditor } from '../extension';
6
+ import withNodeId from '../node-id';
7
+ import { withSocketIO } from '../socket';
8
+ import { PAGE_EDIT_AREA_WIDTH } from '../constants';
9
+ const RevisionEditor = forwardRef((_ref, ref) => {
10
+ let {
11
+ isShowChanges,
12
+ isReloading,
13
+ document,
14
+ revisionContent,
15
+ didMountCallback
16
+ } = _ref;
17
+ const editorRef = useRef(null);
18
+ const editor = useMemo(() => {
19
+ const defaultEditor = createDefaultEditor();
20
+ const editorConfig = context.getEditorConfig();
21
+ const newEditor = withNodeId(withSocketIO(defaultEditor, {
22
+ document,
23
+ config: editorConfig
24
+ }));
25
+ const {
26
+ cursors
27
+ } = document;
28
+ newEditor.cursors = cursors || {};
29
+ newEditor.width = PAGE_EDIT_AREA_WIDTH; // default width
30
+ return newEditor;
31
+
32
+ // eslint-disable-next-line react-hooks/exhaustive-deps
33
+ }, []);
34
+
35
+ // useMount: init socket connection
36
+ useEffect(() => {
37
+ editor.openConnection();
38
+ return () => {
39
+ editor.closeConnection();
40
+ };
41
+
42
+ // eslint-disable-next-line react-hooks/exhaustive-deps
43
+ }, []);
44
+
45
+ // The parent component can call the method of this component through ref
46
+ useImperativeHandle(ref, () => ({
47
+ setSlateValue: document => {
48
+ return editorRef.current.setSlateValue(document);
49
+ },
50
+ updateDocumentVersion: document => {
51
+ return editorRef.current.updateDocumentVersion(document);
52
+ },
53
+ // get value
54
+ getSlateValue: () => {
55
+ return editorRef.current.getSlateValue();
56
+ }
57
+
58
+ // eslint-disable-next-line react-hooks/exhaustive-deps
59
+ }), [editorRef]);
60
+ if (isShowChanges) {
61
+ return /*#__PURE__*/React.createElement(RevisionDiffViewer, {
62
+ editor: editor,
63
+ revisionContent: revisionContent,
64
+ didMountCallback: didMountCallback
65
+ });
66
+ }
67
+ return /*#__PURE__*/React.createElement(SdocEditor, {
68
+ ref: editorRef,
69
+ editor: editor,
70
+ isReloading: isReloading,
71
+ document: document
72
+ });
73
+ });
74
+ export default RevisionEditor;
@@ -19,10 +19,11 @@ import { isMobile } from '../../utils';
19
19
  import { CollaboratorsProvider } from '../../hooks';
20
20
  const SdocEditor = forwardRef((_ref, ref) => {
21
21
  let {
22
+ editor,
22
23
  document,
23
24
  isReloading
24
25
  } = _ref;
25
- const editor = useMemo(() => {
26
+ const validEditor = editor || useMemo(() => {
26
27
  const defaultEditor = createDefaultEditor();
27
28
  const editorConfig = context.getEditorConfig();
28
29
  const newEditor = withNodeId(withSocketIO(defaultEditor, {
@@ -39,12 +40,16 @@ const SdocEditor = forwardRef((_ref, ref) => {
39
40
  // eslint-disable-next-line react-hooks/exhaustive-deps
40
41
  }, []);
41
42
  const [slateValue, setSlateValue] = useState(document.children);
43
+ useEffect(() => {
44
+ validEditor.readonly = false;
45
+ }, []);
42
46
 
43
47
  // useMount: init socket connection
44
48
  useEffect(() => {
45
- editor.openConnection();
49
+ if (editor) return;
50
+ validEditor.openConnection();
46
51
  return () => {
47
- editor.closeConnection();
52
+ validEditor.closeConnection();
48
53
  };
49
54
 
50
55
  // eslint-disable-next-line react-hooks/exhaustive-deps
@@ -53,16 +58,16 @@ const SdocEditor = forwardRef((_ref, ref) => {
53
58
  // useMount: focus editor
54
59
  useEffect(() => {
55
60
  const timer = setTimeout(() => {
56
- const [firstNode] = editor.children;
61
+ const [firstNode] = validEditor.children;
57
62
  if (firstNode) {
58
63
  const [firstNodeFirstChild] = firstNode.children;
59
64
  if (firstNodeFirstChild) {
60
- const endOfFirstNode = Editor.end(editor, [0, 0]);
65
+ const endOfFirstNode = Editor.end(validEditor, [0, 0]);
61
66
  const range = {
62
67
  anchor: endOfFirstNode,
63
68
  focus: endOfFirstNode
64
69
  };
65
- focusEditor(editor, range);
70
+ focusEditor(validEditor, range);
66
71
  }
67
72
  }
68
73
  }, 300);
@@ -76,11 +81,11 @@ const SdocEditor = forwardRef((_ref, ref) => {
76
81
  useImperativeHandle(ref, () => ({
77
82
  setSlateValue: document => {
78
83
  // Force update of editor's child elements
79
- editor.children = document.children;
84
+ validEditor.children = document.children;
80
85
  setSlateValue([...document.children]);
81
86
  },
82
87
  updateDocumentVersion: document => {
83
- editor.updateDocumentVersion(document);
88
+ validEditor.updateDocumentVersion(document);
84
89
  },
85
90
  // get value
86
91
  getSlateValue: () => {
@@ -90,7 +95,7 @@ const SdocEditor = forwardRef((_ref, ref) => {
90
95
  }
91
96
 
92
97
  // eslint-disable-next-line react-hooks/exhaustive-deps
93
- }), [document, editor, slateValue]);
98
+ }), [document, validEditor, slateValue]);
94
99
  const isFreezed = context.getSetting('isFreezed');
95
100
  if (isReloading) {
96
101
  return /*#__PURE__*/React.createElement("div", {
@@ -99,47 +104,47 @@ const SdocEditor = forwardRef((_ref, ref) => {
99
104
  }
100
105
  if (isMobile) {
101
106
  return /*#__PURE__*/React.createElement(EditorContainer, {
102
- editor: editor,
107
+ editor: validEditor,
103
108
  readonly: true
104
109
  }, /*#__PURE__*/React.createElement(ColorProvider, null, /*#__PURE__*/React.createElement(EditorContent, {
105
110
  docValue: slateValue,
106
111
  readonly: true,
107
112
  showOutline: false
108
113
  }, /*#__PURE__*/React.createElement(ReadOnlyArticle, {
109
- editor: editor,
114
+ editor: validEditor,
110
115
  slateValue: slateValue
111
116
  }))));
112
117
  }
113
118
  if (isFreezed) {
114
119
  return /*#__PURE__*/React.createElement(EditorContainer, {
115
- editor: editor,
120
+ editor: validEditor,
116
121
  readonly: isFreezed
117
122
  }, /*#__PURE__*/React.createElement(CollaboratorsProvider, null, /*#__PURE__*/React.createElement(ColorProvider, null, /*#__PURE__*/React.createElement(HeaderToolbar, {
118
- editor: editor,
123
+ editor: validEditor,
119
124
  readonly: isFreezed
120
125
  }), /*#__PURE__*/React.createElement(EditorContent, {
121
126
  docValue: slateValue,
122
127
  showOutline: true,
123
128
  readonly: isFreezed
124
129
  }, /*#__PURE__*/React.createElement(ReadOnlyArticle, {
125
- editor: editor,
130
+ editor: validEditor,
126
131
  slateValue: slateValue,
127
132
  isShowComment: true
128
133
  })))));
129
134
  }
130
135
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(EditorContainer, {
131
- editor: editor
136
+ editor: validEditor
132
137
  }, /*#__PURE__*/React.createElement(CollaboratorsProvider, null, /*#__PURE__*/React.createElement(ColorProvider, null, /*#__PURE__*/React.createElement(HeaderToolbar, {
133
- editor: editor
138
+ editor: validEditor
134
139
  }), /*#__PURE__*/React.createElement(EditorContent, {
135
140
  docValue: slateValue,
136
141
  showOutline: true
137
142
  }, /*#__PURE__*/React.createElement(EditableArticle, {
138
- editor: editor,
143
+ editor: validEditor,
139
144
  slateValue: slateValue,
140
145
  updateSlateValue: setSlateValue
141
146
  }))))), /*#__PURE__*/React.createElement(InsertElementDialog, {
142
- editor: editor
147
+ editor: validEditor
143
148
  }));
144
149
  });
145
150
  export default SdocEditor;
@@ -18,8 +18,8 @@ const InsertElementDialog = _ref => {
18
18
  const [insertLinkCallback, setInsertLinkCallback] = useState(null);
19
19
  const uploadLocalImageInputRef = useRef();
20
20
  const onFileChanged = useCallback(event => {
21
- const file = event.target.files[0];
22
- context.uploadLocalImage(file).then(fileUrl => {
21
+ const files = event.target.files;
22
+ context.uploadLocalImage(files).then(fileUrl => {
23
23
  insertImage(editor, fileUrl, editor.selection, insertPosition, slateNode);
24
24
  if (uploadLocalImageInputRef.current) {
25
25
  uploadLocalImageInputRef.current.value = '';
@@ -110,6 +110,7 @@ const InsertElementDialog = _ref => {
110
110
  return /*#__PURE__*/React.createElement("input", {
111
111
  ref: uploadLocalImageInputRef,
112
112
  type: "file",
113
+ multiple: true,
113
114
  accept: "image/*",
114
115
  style: {
115
116
  display: 'none'
@@ -39,33 +39,35 @@ export const generateImageNode = src => {
39
39
  }
40
40
  });
41
41
  };
42
- export const insertImage = function (editor, src, selection) {
42
+ export const insertImage = function (editor, srcList, selection) {
43
43
  let position = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : INSERT_POSITION.CURRENT;
44
44
  let slateNode = arguments.length > 4 ? arguments[4] : undefined;
45
- if (!src) return;
45
+ if (!srcList) return;
46
46
  if (position !== INSERT_POSITION.AFTER) {
47
47
  if (isInsertImageMenuDisabled(editor)) return;
48
48
  }
49
- const imageNode = generateImageNode(src);
49
+ const imageNodes = srcList.map(src => generateImageNode(src));
50
50
  const validSelection = selection || editor.selection;
51
51
  if (position === INSERT_POSITION.AFTER) {
52
52
  let path = Editor.path(editor, validSelection);
53
53
  if (slateNode && (slateNode === null || slateNode === void 0 ? void 0 : slateNode.type) === LIST_ITEM) {
54
54
  path = ReactEditor.findPath(editor, slateNode);
55
55
  const nextPath = Path.next(path);
56
- Transforms.insertNodes(editor, imageNode, {
56
+ Transforms.insertNodes(editor, imageNodes, {
57
57
  at: nextPath
58
58
  });
59
59
  return;
60
60
  }
61
61
  const p = generateEmptyElement(ELEMENT_TYPE.PARAGRAPH);
62
- p.children[0] = imageNode;
62
+ imageNodes.forEach((item, index) => {
63
+ p.children[index] = item;
64
+ });
63
65
  Transforms.insertNodes(editor, p, {
64
66
  at: [path[0] + 1]
65
67
  });
66
68
  return;
67
69
  }
68
- Transforms.insertNodes(editor, imageNode, {
70
+ Transforms.insertNodes(editor, imageNodes, {
69
71
  at: validSelection
70
72
  });
71
73
  };
@@ -67,7 +67,7 @@ const withImage = editor => {
67
67
  }
68
68
  }
69
69
  if (data.types && data.types.includes('Files') && data.files[0].type.includes(IMAGE)) {
70
- context.uploadLocalImage(data.files[0]).then(fileUrl => {
70
+ context.uploadLocalImage(data.files).then(fileUrl => {
71
71
  insertImage(newEditor, fileUrl, editor.selection, INSERT_POSITION.CURRENT);
72
72
  resetCursor(newEditor);
73
73
  });
@@ -32,10 +32,10 @@ export const TABLE_ROW_STYLE = {
32
32
  MIN_HEIGHT: 'min_height'
33
33
  };
34
34
  export const TABLE_ALTERNATE_HIGHLIGHT_CLASS_MAP = {
35
- '#3f495d': 'sdoc-table-3f495d',
36
- '#2367f2': 'sdoc-table-2367f2',
37
- '#f77d21': 'sdoc-table-f77d21',
38
- '#0099f4': 'sdoc-table-0099f4'
35
+ 'sdoc-table-header-3f495d': 'sdoc-table-body-3f495d',
36
+ 'sdoc-table-header-2367f2': 'sdoc-table-body-2367f2',
37
+ 'sdoc-table-header-f77d21': 'sdoc-table-body-f77d21',
38
+ 'sdoc-table-header-0099f4': 'sdoc-table-body-0099f4'
39
39
  };
40
40
  export const INHERIT_CELL_STYLE_WHEN_SELECT_SINGLE = ['background_color'];
41
41
  export const INHERIT_CELL_STYLE_WHEN_SELECT_MULTIPLE = ['background_color', 'text_align'];
@@ -1,11 +1,11 @@
1
1
  import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
2
2
  import slugid from 'slugid';
3
- import { Editor, Range, Transforms, Point, Node, Path } from '@seafile/slate';
3
+ import { Editor, Range, Transforms, Point, Node } from '@seafile/slate';
4
4
  import { ReactEditor } from '@seafile/slate-react';
5
5
  import deepCopy from 'deep-copy';
6
6
  import { getNodeType, getParentNode, getSelectedNodeByType, isTextNode, getSelectedElems, focusEditor, getNode, findPath, replaceNodeChildren, replaceNode, getSelectedNodeEntryByType, getAboveBlockNode } from '../../core';
7
7
  import { ELEMENT_TYPE, KEYBOARD, CLIPBOARD_FORMAT_KEY, INSERT_POSITION } from '../../constants';
8
- import { TABLE_MAX_ROWS, TABLE_MAX_COLUMNS, EMPTY_SELECTED_RANGE, TABLE_ROW_MIN_HEIGHT, TABLE_CELL_MIN_WIDTH, TABLE_ELEMENT, TABLE_ELEMENT_POSITION, TABLE_ROW_STYLE, INHERIT_CELL_STYLE_WHEN_SELECT_MULTIPLE, INHERIT_CELL_STYLE_WHEN_SELECT_SINGLE } from './constants';
8
+ import { TABLE_MAX_ROWS, TABLE_MAX_COLUMNS, EMPTY_SELECTED_RANGE, TABLE_ROW_MIN_HEIGHT, TABLE_CELL_MIN_WIDTH, TABLE_ELEMENT, TABLE_ELEMENT_POSITION, TABLE_ROW_STYLE, INHERIT_CELL_STYLE_WHEN_SELECT_MULTIPLE, INHERIT_CELL_STYLE_WHEN_SELECT_SINGLE, TABLE_ALTERNATE_HIGHLIGHT_CLASS_MAP } from './constants';
9
9
  import EventBus from '../../../utils/event-bus';
10
10
  import { INTERNAL_EVENT, PAGE_EDIT_AREA_WIDTH } from '../../../constants';
11
11
  import ObjectUtils from '../../../utils/object-utils';
@@ -1389,4 +1389,13 @@ export const getCellInheritStyles = (editor, tablePath, rowIndex, colIndex) => {
1389
1389
  const tableCell = (_table$children$rowIn = table.children[rowIndex]) === null || _table$children$rowIn === void 0 ? void 0 : _table$children$rowIn.children[colIndex];
1390
1390
  if (!tableCell) return {};
1391
1391
  return (_tableCell$inherit_st = tableCell['inherit_style']) !== null && _tableCell$inherit_st !== void 0 ? _tableCell$inherit_st : {};
1392
+ };
1393
+ export const getCellHighlightClassName = (primaryColorClassName, rowIndex) => {
1394
+ let className = '';
1395
+ if (rowIndex === 0) {
1396
+ className = primaryColorClassName;
1397
+ } else if (rowIndex % 2 === 0) {
1398
+ className = TABLE_ALTERNATE_HIGHLIGHT_CLASS_MAP[primaryColorClassName];
1399
+ }
1400
+ return className;
1392
1401
  };
@@ -1,7 +1,7 @@
1
1
  import React, { useCallback, useMemo } from 'react';
2
2
  import { UncontrolledPopover } from 'reactstrap';
3
3
  import { TABLE_ALTERNATE_HIGHLIGHT_CLASS_MAP } from '../../constants';
4
- import SmapleTable from './sample-table';
4
+ import SampleTable from './sample-table';
5
5
  import { insertTableByTemplate } from '../../helpers';
6
6
  import './index.css';
7
7
  import '../../render/alternate-color.css';
@@ -22,7 +22,7 @@ const TableTemplate = _ref => {
22
22
  fade: false,
23
23
  className: "sdoc-sub-dropdown-menu sdoc-table-template-popover",
24
24
  innerClassName: "sdoc-table-template-inner-popover"
25
- }, tableTemplatePreviewList.map((alternateColor, index) => /*#__PURE__*/React.createElement(SmapleTable, {
25
+ }, tableTemplatePreviewList.map((alternateColor, index) => /*#__PURE__*/React.createElement(SampleTable, {
26
26
  key: alternateColor + index,
27
27
  alternateColor: alternateColor,
28
28
  onClickTemplate: handleClickTemplate
@@ -1,29 +1,27 @@
1
1
  import React, { useCallback } from 'react';
2
2
  import PropTypes from 'prop-types';
3
- import { TABLE_ALTERNATE_HIGHLIGHT_CLASS_MAP } from '../../constants';
3
+ import { getCellHighlightClassName } from '../../helpers';
4
4
  import './index.css';
5
- const SmapleTable = _ref => {
5
+ const SampleTable = _ref => {
6
6
  let {
7
7
  alternateColor,
8
8
  onClickTemplate
9
9
  } = _ref;
10
10
  // generate table
11
- const renderTableRow = useCallback((row, column) => new Array(row).fill(null).map((_, index) => {
12
- return /*#__PURE__*/React.createElement("div", {
13
- className: "sdoc-table-template-row table-row",
14
- key: "sdoc-template-table-row-".concat(index),
15
- onClick: e => onClickTemplate(e, alternateColor)
16
- }, new Array(column).fill(null).map((_, index) => /*#__PURE__*/React.createElement("div", {
17
- className: "sdoc-table-template-cell",
18
- key: "sdoc-template-table-cell-".concat(index)
19
- })));
20
- }), [onClickTemplate, alternateColor]);
11
+ const renderTableRow = useCallback((row, column) => new Array(row).fill(null).map((_, index) => /*#__PURE__*/React.createElement("div", {
12
+ className: "sdoc-table-template-row table-row ".concat(getCellHighlightClassName(alternateColor, index)),
13
+ key: "sdoc-template-table-row-".concat(index),
14
+ onClick: e => onClickTemplate(e, alternateColor)
15
+ }, new Array(column).fill(null).map((_, index) => /*#__PURE__*/React.createElement("div", {
16
+ className: "sdoc-table-template-cell",
17
+ key: "sdoc-template-table-cell-".concat(index)
18
+ })))), [onClickTemplate, alternateColor]);
21
19
  return /*#__PURE__*/React.createElement("div", {
22
- className: "sdoc-table-template-view-table ".concat(TABLE_ALTERNATE_HIGHLIGHT_CLASS_MAP[alternateColor])
20
+ className: "sdoc-table-template-view-table"
23
21
  }, renderTableRow(4, 4));
24
22
  };
25
- SmapleTable.proptoTypes = {
23
+ SampleTable.protoTypes = {
26
24
  alternateColor: PropTypes.string.isRequired,
27
25
  onClickTemplate: PropTypes.func.isRequired
28
26
  };
29
- export default SmapleTable;
27
+ export default SampleTable;
@@ -1,37 +1,37 @@
1
1
  /* type1 */
2
- .sdoc-table-3f495d .table-row:nth-child(2n + 1) {
2
+ .sdoc-table-body-3f495d {
3
3
  background-color: #f1f3f6;
4
4
  }
5
5
 
6
- .sdoc-table-3f495d .table-row:first-child {
6
+ .sdoc-table-header-3f495d {
7
7
  background-color: #3f495d;
8
8
  color: white;
9
9
  }
10
10
 
11
11
  /* type2 */
12
- .sdoc-table-2367f2 .table-row:nth-child(2n + 1) {
12
+ .sdoc-table-body-2367f2 {
13
13
  background-color: #e1edff;
14
14
  }
15
15
 
16
- .sdoc-table-2367f2 .table-row:first-child {
16
+ .sdoc-table-header-2367f2 {
17
17
  background-color: #2367f2;
18
18
  color: white;
19
19
  }
20
20
 
21
21
  /* type3 */
22
- .sdoc-table-f77d21 .table-row:nth-child(2n + 1) {
22
+ .sdoc-table-body-f77d21 {
23
23
  background-color: #fff1e8;
24
24
  }
25
25
 
26
- .sdoc-table-f77d21 .table-row:first-child {
26
+ .sdoc-table-header-f77d21 {
27
27
  background-color: #f77d21;
28
28
  }
29
29
 
30
30
  /* type4 */
31
- .sdoc-table-0099f4 .table-row:nth-child(2n + 1) {
31
+ .sdoc-table-body-0099f4 {
32
32
  background-color: #e1f5ff;
33
33
  }
34
34
 
35
- .sdoc-table-0099f4 .table-row:first-child {
35
+ .sdoc-table-header-0099f4 {
36
36
  background-color: #0099f4;
37
37
  }
@@ -4,7 +4,7 @@ import classnames from 'classnames';
4
4
  import throttle from 'lodash.throttle';
5
5
  import { useSelected, useSlateStatic, useReadOnly } from '@seafile/slate-react';
6
6
  import { Transforms, Editor } from '@seafile/slate';
7
- import { EMPTY_SELECTED_RANGE, TABLE_ALTERNATE_HIGHLIGHT_CLASS_MAP } from '../constants';
7
+ import { EMPTY_SELECTED_RANGE } from '../constants';
8
8
  import { ResizeHandlersContext, TableSelectedRangeContext, SettingSelectRangeContext } from './hooks';
9
9
  import EventBus from '../../../../utils/event-bus';
10
10
  import { INTERNAL_EVENT } from '../../../../constants';
@@ -18,7 +18,6 @@ import { findPath } from '../../../core';
18
18
  import './index.css';
19
19
  import './alternate-color.css';
20
20
  const Table = _ref => {
21
- var _element$ui, _element$ui2;
22
21
  let {
23
22
  className,
24
23
  attributes,
@@ -190,9 +189,7 @@ const Table = _ref => {
190
189
  table: element,
191
190
  setSelectedRange: setSelectedRangeByClick
192
191
  }), /*#__PURE__*/React.createElement("div", {
193
- className: classnames(tableContainerClassName, {
194
- [TABLE_ALTERNATE_HIGHLIGHT_CLASS_MAP[element === null || element === void 0 ? void 0 : (_element$ui = element.ui) === null || _element$ui === void 0 ? void 0 : _element$ui.alternate_highlight_color]]: element === null || element === void 0 ? void 0 : (_element$ui2 = element.ui) === null || _element$ui2 === void 0 ? void 0 : _element$ui2.alternate_highlight
195
- }),
192
+ className: classnames(tableContainerClassName),
196
193
  style: style,
197
194
  onMouseDown: onMouseDown,
198
195
  ref: table,
@@ -1,13 +1,14 @@
1
1
  import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
2
- import React, { useCallback } from 'react';
2
+ import React, { useCallback, useMemo } from 'react';
3
3
  import classnames from 'classnames';
4
4
  import { useSlateStatic, useReadOnly } from '@seafile/slate-react';
5
- import { Transforms } from '@seafile/slate';
5
+ import { Editor, Transforms } from '@seafile/slate';
6
6
  import ObjectUtils from '../../../../utils/object-utils';
7
7
  import { findPath, focusEditor } from '../../../core';
8
8
  import { useResizeHandlersContext, useTableSelectedRangeContext } from './hooks';
9
9
  import { EMPTY_SELECTED_RANGE, SELECTED_TABLE_CELL_BACKGROUND_COLOR, TABLE_CELL_STYLE } from '../constants';
10
- import { getTableColumns, colorBlend } from '../helpers';
10
+ import { getTableColumns, colorBlend, getCellHighlightClassName } from '../helpers';
11
+ import { ELEMENT_TYPE } from '../../../constants';
11
12
  const TableCell = _ref => {
12
13
  let {
13
14
  attributes,
@@ -70,9 +71,26 @@ const TableCell = _ref => {
70
71
  if (element.style) {
71
72
  style = _objectSpread(_objectSpread({}, element.style), style);
72
73
  }
74
+
75
+ // Table alternate highlight
76
+ const highlightClass = useMemo(() => {
77
+ var _tableEntry$;
78
+ const [tableEntry] = Editor.nodes(editor, {
79
+ at: cellPath,
80
+ match: n => n.type === ELEMENT_TYPE.TABLE
81
+ });
82
+ const {
83
+ alternate_highlight,
84
+ alternate_highlight_color
85
+ } = ((_tableEntry$ = tableEntry[0]) === null || _tableEntry$ === void 0 ? void 0 : _tableEntry$.ui) || {};
86
+ if (!alternate_highlight) return '';
87
+ const className = getCellHighlightClassName(alternate_highlight_color, rowIndex);
88
+ return className;
89
+ // eslint-disable-next-line react-hooks/exhaustive-deps
90
+ }, [editor, rowIndex]);
73
91
  return /*#__PURE__*/React.createElement("div", Object.assign({}, attributes, {
74
92
  style: _objectSpread(_objectSpread({}, element.style), style),
75
- className: classnames('table-cell', attributes.className, {
93
+ className: classnames('table-cell', attributes.className, highlightClass, {
76
94
  'cell-selected': isSelected,
77
95
  'cell-light-height-left-border': isSelectedFirstCell,
78
96
  'cell-light-height-right-border': isSelectedLastCell,
@@ -1,5 +1,6 @@
1
1
  import SDocEditor from './editor/sdoc-editor';
2
+ import RevisionEditor from './editor/revision-editor';
2
3
  import { DiffViewer, SDocViewer, PublishedRevisionDiffViewer } from './views';
3
4
  import SDocOutline from './outline';
4
5
  import EventBus from './utils/event-bus';
5
- export { SDocEditor, SDocViewer, SDocOutline, EventBus, DiffViewer, PublishedRevisionDiffViewer };
6
+ export { SDocEditor, RevisionEditor, SDocViewer, SDocOutline, EventBus, DiffViewer, PublishedRevisionDiffViewer };
@@ -50,6 +50,7 @@ class SocketManager {
50
50
  this.eventBus.dispatch(EXTERNAL_EVENT.NEW_NOTIFICATION, notification);
51
51
  };
52
52
  this.onReceiveLocalOperations = operations => {
53
+ if (this.editor.readonly) return;
53
54
  this.pendingOperationList.push(operations);
54
55
  const lastOpBeginTime = new Date().getTime();
55
56
  this.pendingOperationBeginTimeList.push(lastOpBeginTime);
@@ -61,6 +62,7 @@ class SocketManager {
61
62
  this.sendOperations();
62
63
  };
63
64
  this.sendOperations = () => {
65
+ if (this.editor.readonly) return;
64
66
  if (this.state !== STATE.IDLE) return;
65
67
  stateDebug("State changed: ".concat(this.state, " -> ").concat(STATE.SENDING));
66
68
  this.state = STATE.SENDING;
@@ -141,6 +143,7 @@ class SocketManager {
141
143
  this.onReceiveRemoteOperations = params => {
142
144
  // if this.disconnect is true, Then the message sent by the remote end cannot be received
143
145
  if (this.state !== STATE.IDLE) return;
146
+ if (this.editor.readonly) return;
144
147
  const {
145
148
  version: serverVersion
146
149
  } = params;
@@ -203,6 +206,7 @@ class SocketManager {
203
206
  this.socketClient.getRecentOperations();
204
207
  };
205
208
  this.onGetRecentOperations = result => {
209
+ if (this.editor.readonly) return;
206
210
  const {
207
211
  mode,
208
212
  content
@@ -242,6 +246,7 @@ class SocketManager {
242
246
  this.resolveConflicting(loseOperations);
243
247
  };
244
248
  this.resolveConflicting = loseOperations => {
249
+ if (this.editor.readonly) return;
245
250
  conflictDebug('resolve conflicts');
246
251
  this.editor.isRemote = true;
247
252
  if (this.pendingOperationList.length !== 0) {
@@ -312,6 +317,7 @@ class SocketManager {
312
317
  this.socketClient.sendCursorLocation(location);
313
318
  };
314
319
  this.receiveCursorLocation = params => {
320
+ if (this.editor.readonly) return;
315
321
  const {
316
322
  user,
317
323
  location,
@@ -25,6 +25,7 @@ const withSocketIO = (editor, options) => {
25
25
  SocketManager.destroy();
26
26
  };
27
27
  newEditor.onChange = () => {
28
+ if (newEditor.readonly) return;
28
29
  const {
29
30
  document,
30
31
  config
@@ -6,6 +6,7 @@ import Loading from '../../components/loading';
6
6
  import '../../assets/css/diff-viewer.css';
7
7
  const RevisionDiffViewer = _ref => {
8
8
  let {
9
+ editor,
9
10
  revisionContent,
10
11
  didMountCallback
11
12
  } = _ref;
@@ -27,12 +28,17 @@ const RevisionDiffViewer = _ref => {
27
28
  setIsLoading(false);
28
29
  });
29
30
  }, [revisionContent, didMountCallback]);
31
+ useEffect(() => {
32
+ if (!editor) return;
33
+ editor.readonly = true;
34
+ }, []);
30
35
  if (isLoading) {
31
36
  return /*#__PURE__*/React.createElement(Loading, null);
32
37
  }
33
38
  return /*#__PURE__*/React.createElement(SDocViewer, {
34
39
  showToolbar: true,
35
40
  showOutline: true,
41
+ editor: editor,
36
42
  document: {
37
43
  children: diff.value
38
44
  }
package/dist/context.js CHANGED
@@ -25,9 +25,9 @@ class Context {
25
25
  this.settings['originFileURL'] = originFileURL;
26
26
  }
27
27
  };
28
- this.uploadLocalImage = imageFile => {
28
+ this.uploadLocalImage = imageFiles => {
29
29
  const docUuid = this.getSetting('docUuid');
30
- return this.api.uploadSdocImage(docUuid, imageFile).then(res => {
30
+ return this.api.uploadSdocImage(docUuid, imageFiles).then(res => {
31
31
  const {
32
32
  relative_path
33
33
  } = res.data;
@@ -6,8 +6,8 @@ import DocOperations from '../components/doc-operations';
6
6
  import Layout, { Header, Content } from '../layout';
7
7
  import context from '../context';
8
8
  import ErrorBoundary from './error-boundary';
9
- import { SDocEditor } from '../basic-sdk';
10
- import { PublishedRevisionDiffViewer, RevisionDiffViewer } from '../basic-sdk/views';
9
+ import { SDocEditor, RevisionEditor } from '../basic-sdk';
10
+ import { PublishedRevisionDiffViewer } from '../basic-sdk/views';
11
11
  import { useDocument } from '../hooks';
12
12
  import { resetWebTitle } from '../utils';
13
13
  import '../assets/css/simple-editor.css';
@@ -31,6 +31,7 @@ const SimpleEditor = _ref => {
31
31
  const [revisionContent, setRevisionContent] = useState(null);
32
32
  const [changes, setChanges] = useState([]);
33
33
  const initIsPublished = context.getSetting('isPublished') || false;
34
+ const isSdocRevision = context.getSetting('isSdocRevision') || false;
34
35
  const [isPublished, setPublished] = useState(initIsPublished);
35
36
 
36
37
  // useMount: reset title
@@ -93,6 +94,30 @@ const SimpleEditor = _ref => {
93
94
  setPublished(true);
94
95
  });
95
96
  }, [setErrorMessage]);
97
+ const renderEditor = useCallback(() => {
98
+ if (!isSdocRevision) {
99
+ return /*#__PURE__*/React.createElement(SDocEditor, {
100
+ ref: editorRef,
101
+ isReloading: isReloading,
102
+ document: document
103
+ });
104
+ }
105
+ if (isPublished) {
106
+ return /*#__PURE__*/React.createElement(PublishedRevisionDiffViewer, {
107
+ isShowChanges: isShowChanges,
108
+ revisionContent: revisionContent,
109
+ didMountCallback: setDiffChanges
110
+ });
111
+ }
112
+ return /*#__PURE__*/React.createElement(RevisionEditor, {
113
+ ref: editorRef,
114
+ isShowChanges: isShowChanges,
115
+ isReloading: isReloading,
116
+ document: document,
117
+ revisionContent: revisionContent,
118
+ didMountCallback: setDiffChanges
119
+ });
120
+ }, [isSdocRevision, editorRef, isReloading, document, isPublished, isShowChanges, revisionContent, setDiffChanges]);
96
121
  if (isFirstLoading) {
97
122
  return /*#__PURE__*/React.createElement(Loading, null);
98
123
  }
@@ -115,17 +140,6 @@ const SimpleEditor = _ref => {
115
140
  handleViewChangesToggle: handleViewChangesToggle,
116
141
  handleRevisionMerged: handleRevisionMerged,
117
142
  handleRevisionPublished: handleRevisionPublished
118
- })), /*#__PURE__*/React.createElement(Content, null, isPublished && /*#__PURE__*/React.createElement(PublishedRevisionDiffViewer, {
119
- isShowChanges: isShowChanges,
120
- revisionContent: revisionContent,
121
- didMountCallback: setDiffChanges
122
- }), !isPublished && !isShowChanges && /*#__PURE__*/React.createElement(SDocEditor, {
123
- ref: editorRef,
124
- isReloading: isReloading,
125
- document: document
126
- }), !isPublished && isShowChanges && /*#__PURE__*/React.createElement(RevisionDiffViewer, {
127
- revisionContent: revisionContent,
128
- didMountCallback: setDiffChanges
129
- }))));
143
+ })), /*#__PURE__*/React.createElement(Content, null, renderEditor())));
130
144
  };
131
145
  export default withTranslation('sdoc-editor')(SimpleEditor);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seafile/sdoc-editor",
3
- "version": "0.3.22",
3
+ "version": "0.3.24",
4
4
  "private": false,
5
5
  "description": "This is a sdoc editor",
6
6
  "main": "dist/index.js",
@@ -54,6 +54,7 @@
54
54
  "Edit": "Upravit",
55
55
  "Copy": "Kopírovat",
56
56
  "Copied": "Zkopírováno",
57
+ "Cut": "Cut",
57
58
  "Internal_link": "Interní odkaz",
58
59
  "Copy_internal_link": "Interní odkaz byl zkopírován do schránky",
59
60
  "Internal_link_desc": "Interní odkaz směřuje na soubor nebo složku u které má uživatel oprávnění ke čtení.",
@@ -417,5 +418,11 @@
417
418
  "Freezed": "Freezed",
418
419
  "Callout": "Callout",
419
420
  "The_current_location_does_not_support_pasting": "The current location does not support pasting ",
420
- "Please_enter...": "Please enter..."
421
+ "Please_enter...": "Please enter...",
422
+ "Combine_cell": "Combine cells",
423
+ "Split_cell": "Split cell",
424
+ "Row_number": "Row number",
425
+ "Column_number": "Column number",
426
+ "The_maximum_row_number_is_{number}": "The maximum row number is {number}",
427
+ "The_maximum_column_number_is_{number}": "The maximum column number is {number}"
421
428
  }
@@ -54,6 +54,7 @@
54
54
  "Edit": "Bearbeiten",
55
55
  "Copy": "Kopieren",
56
56
  "Copied": "Kopiert",
57
+ "Cut": "Cut",
57
58
  "Internal_link": "Interner Link",
58
59
  "Copy_internal_link": "Der interne Link wurde in den Zwischenspeicher kopiert.",
59
60
  "Internal_link_desc": "Interne Links sind Verweise auf Dateien bzw. Ordner, die nur von Benutzer/innen mit mindestens Leserechten für die Dateien bzw. Ordner genutzt werden können. Interne Links eignen sich insbesondere für die interne Kommunikation in Ticket-/CRM-Systemen sowie E-Mails und Chats.",
@@ -417,5 +418,11 @@
417
418
  "Freezed": "Freezed",
418
419
  "Callout": "Callout",
419
420
  "The_current_location_does_not_support_pasting": "The current location does not support pasting ",
420
- "Please_enter...": "Please enter..."
421
+ "Please_enter...": "Please enter...",
422
+ "Combine_cell": "Combine cells",
423
+ "Split_cell": "Split cell",
424
+ "Row_number": "Row number",
425
+ "Column_number": "Column number",
426
+ "The_maximum_row_number_is_{number}": "The maximum row number is {number}",
427
+ "The_maximum_column_number_is_{number}": "The maximum column number is {number}"
421
428
  }
@@ -54,6 +54,7 @@
54
54
  "Edit": "Edit",
55
55
  "Copy": "Copy",
56
56
  "Copied": "Copied",
57
+ "Cut": "Cut",
57
58
  "Internal_link": "Internal link",
58
59
  "Copy_internal_link": "Internal link has been copied to clipboard",
59
60
  "Internal_link_desc": "An internal link is a link to a file or folder that can be accessed by users with read permission to the file or folder.",
@@ -54,6 +54,7 @@
54
54
  "Edit": "Editar",
55
55
  "Copy": "Copiar",
56
56
  "Copied": "Copiado",
57
+ "Cut": "Cut",
57
58
  "Internal_link": "Enlace interno",
58
59
  "Copy_internal_link": "El enlace interno ha sido copiado al portapapeles",
59
60
  "Internal_link_desc": "Un enlace interno es un enlace a un archivo o carpeta que puede ser accedido por usuarios con permiso de lectura al archivo o carpeta. ",
@@ -417,5 +418,11 @@
417
418
  "Freezed": "Freezed",
418
419
  "Callout": "Callout",
419
420
  "The_current_location_does_not_support_pasting": "The current location does not support pasting ",
420
- "Please_enter...": "Please enter..."
421
+ "Please_enter...": "Please enter...",
422
+ "Combine_cell": "Combine cells",
423
+ "Split_cell": "Split cell",
424
+ "Row_number": "Row number",
425
+ "Column_number": "Column number",
426
+ "The_maximum_row_number_is_{number}": "The maximum row number is {number}",
427
+ "The_maximum_column_number_is_{number}": "The maximum column number is {number}"
421
428
  }
@@ -54,6 +54,7 @@
54
54
  "Edit": "Modifier",
55
55
  "Copy": "Copier",
56
56
  "Copied": "Copié",
57
+ "Cut": "Cut",
57
58
  "Internal_link": "Lien interne",
58
59
  "Copy_internal_link": "Le lien interne a été copié dans le presse-papiers.",
59
60
  "Internal_link_desc": "Un lien interne est un lien vers un fichier ou un dossier accessible en lecture par un utilisateur.",
@@ -417,5 +418,11 @@
417
418
  "Freezed": "Freezed",
418
419
  "Callout": "Callout",
419
420
  "The_current_location_does_not_support_pasting": "The current location does not support pasting ",
420
- "Please_enter...": "Please enter..."
421
+ "Please_enter...": "Please enter...",
422
+ "Combine_cell": "Combine cells",
423
+ "Split_cell": "Split cell",
424
+ "Row_number": "Row number",
425
+ "Column_number": "Column number",
426
+ "The_maximum_row_number_is_{number}": "The maximum row number is {number}",
427
+ "The_maximum_column_number_is_{number}": "The maximum column number is {number}"
421
428
  }
@@ -54,6 +54,7 @@
54
54
  "Edit": "Modifica",
55
55
  "Copy": "Copia",
56
56
  "Copied": "Copiato",
57
+ "Cut": "Cut",
57
58
  "Internal_link": "Collegamento Interno",
58
59
  "Copy_internal_link": "Il collegamento interno è stato copiato negli appunti",
59
60
  "Internal_link_desc": "Un collegamento interno è un collegamento a un file o una cartella a cui gli utenti possono accedere con autorizzazione di lettura al file o alla cartella.",
@@ -417,5 +418,11 @@
417
418
  "Freezed": "Freezed",
418
419
  "Callout": "Callout",
419
420
  "The_current_location_does_not_support_pasting": "The current location does not support pasting ",
420
- "Please_enter...": "Please enter..."
421
+ "Please_enter...": "Please enter...",
422
+ "Combine_cell": "Combine cells",
423
+ "Split_cell": "Split cell",
424
+ "Row_number": "Row number",
425
+ "Column_number": "Column number",
426
+ "The_maximum_row_number_is_{number}": "The maximum row number is {number}",
427
+ "The_maximum_column_number_is_{number}": "The maximum column number is {number}"
421
428
  }
@@ -54,6 +54,7 @@
54
54
  "Edit": "Редактировать",
55
55
  "Copy": "Копировать",
56
56
  "Copied": "Скопировано",
57
+ "Cut": "Cut",
57
58
  "Internal_link": "Внутренняя ссылка",
58
59
  "Copy_internal_link": "Внутренняя ссылка скопирована в буфер обмена",
59
60
  "Internal_link_desc": "Внутренняя ссылка - это ссылка на файл или папку, к которым могут обращаться пользователи с правами на чтение файла или папки.",
@@ -415,7 +416,13 @@
415
416
  "Table_template": "Шаблон таблицы",
416
417
  "Jump_to_original_doc": "Перейти к исходному документу",
417
418
  "Freezed": "Заморожено",
418
- "Callout": "Callout",
419
- "The_current_location_does_not_support_pasting": "The current location does not support pasting ",
420
- "Please_enter...": "Please enter..."
419
+ "Callout": "Выноска",
420
+ "The_current_location_does_not_support_pasting": "Текущее местоположение не поддерживает вставку ",
421
+ "Please_enter...": "Пожалуйста, введите...",
422
+ "Combine_cell": "Объединить ячейки",
423
+ "Split_cell": "Разделить ячейку",
424
+ "Row_number": "Номер строки",
425
+ "Column_number": "Номер столбца",
426
+ "The_maximum_row_number_is_{number}": "Максимальное количество строк - {number}",
427
+ "The_maximum_column_number_is_{number}": "Максимальное количество столбцов - {number}"
421
428
  }
@@ -54,6 +54,7 @@
54
54
  "Edit": "编辑",
55
55
  "Copy": "复制",
56
56
  "Copied": "已复制",
57
+ "Cut": "剪切",
57
58
  "Internal_link": "内部链接",
58
59
  "Copy_internal_link": "内部链接已复制到剪贴板",
59
60
  "Internal_link_desc": "内部链接是指向文件或目录的链接,只有对该文件或目录有访问权限的人可以访问。",
@@ -14,24 +14,18 @@
14
14
  />
15
15
  <missing-glyph />
16
16
 
17
- <<<<<<< HEAD
18
- <glyph glyph-name="sdoc-selected-text" unicode="&#58974;" d="M48 480h928c25.6 0 48-22.4 48-48s-22.4-48-48-48h-928C22.4 384 0 406.4 0 432S22.4 480 48 480z m0-352h352c25.6 0 48-22.4 48-48s-22.4-48-48-48h-352C22.4 32 0 54.4 0 80S22.4 128 48 128z m0 704h928c25.6 0 48-22.4 48-48S1001.6 736 976 736h-928C22.4 736 0 758.4 0 784S22.4 832 48 832z m675.2-950.4c-12.8 0-28.8 6.4-38.4 16l-124.8 118.4c-22.4 19.2-22.4 51.2 0 73.6s54.4 19.2 76.8 0l86.4-83.2 211.2 204.8c22.4 19.2 54.4 19.2 76.8 0s22.4-51.2 0-73.6l-249.6-240c-12.8-12.8-25.6-16-38.4-16z" horiz-adv-x="1028" />
17
+ <glyph glyph-name="sdoc-comment-quote" unicode="&#58976;" d="M48 896C73.6 896 96 873.6 96 848v-928c0-25.6-22.4-48-48-48S0-105.6 0-80v928C0 873.6 22.4 896 48 896z m224-665.6c51.2 16 96 48 124.8 92.8 32 41.6 48 118.4 48 163.2-9.6-6.4-22.4-6.4-44.8-6.4-38.4 0-70.4 12.8-99.2 41.6-25.6 28.8-41.6 64-41.6 108.8s16 80 44.8 108.8 70.4 41.6 108.8 41.6c51.2 0 89.6-22.4 124.8-64 32-41.6 48-96 48-160 0-102.4-28.8-220.8-83.2-294.4-54.4-76.8-131.2-128-227.2-153.6l-3.2 121.6z m438.4 6.4c51.2 16 89.6 48 124.8 92.8 35.2 41.6 51.2 118.4 48 163.2-9.6-6.4-22.4-6.4-44.8-6.4-38.4 0-73.6 12.8-99.2 41.6-28.8 28.8-41.6 64-41.6 108.8s16 80 41.6 108.8c32 25.6 70.4 38.4 112 38.4 51.2 0 89.6-22.4 121.6-64s48-96 48-160c0-102.4-28.8-220.8-83.2-294.4-54.4-76.8-131.2-128-227.2-153.6v124.8z" horiz-adv-x="1024" />
18
+
19
+ <glyph glyph-name="sdoc-find-replace" unicode="&#58975;" d="M468.66016 896C260.66016 896 81.46016 761.6 20.66016 566.4s16-409.6 185.6-521.6 396.8-102.4 553.6 25.6l185.6-185.6c19.2-16 48-16 64 0 19.2 19.2 19.2 48 0 64l-185.6 185.6c115.2 140.8 137.6 332.8 60.8 492.8S647.86016 896 468.66016 896zM97.46016 432C97.46016 636.8 260.66016 800 465.46016 800S833.46016 636.8 833.46016 432 670.26016 64 465.46016 64 97.46016 227.2 97.46016 432z" horiz-adv-x="1025" />
19
20
 
20
- =======
21
- <<<<<<< HEAD
22
- >>>>>>> 4ad4d178 (feat: change icon)
23
21
  <glyph glyph-name="sdoc-freezed" unicode="&#58973;" d="M512 384m-512 0a512 512 0 1 1 1024 0 512 512 0 1 1-1024 0ZM316.8 716.8c118.4 70.4 265.6 70.4 384 3.2s192-195.2 192-332.8c0-137.6-73.6-265.6-195.2-332.8-182.4-105.6-416-41.6-521.6 140.8S134.4 608 316.8 716.8z m348.8-604.8c137.6 80 195.2 249.6 131.2 396.8L259.2 195.2c92.8-124.8 268.8-163.2 406.4-83.2zM352 652.8c-137.6-80-192-249.6-128-393.6l537.6 310.4c-96 128-272 163.2-409.6 83.2z" horiz-adv-x="1024" />
24
22
 
25
23
  <glyph glyph-name="sdoc-jump-to" unicode="&#58970;" d="M361.6 896c32 0 54.4-16 54.4-48S393.6 800 361.6 800H96v-832h832v262.4c0 32 16 57.6 48 57.6s48-25.6 48-57.6v-300.8c0-32-28.8-57.6-60.8-57.6H60.8c-32 0-60.8 25.6-60.8 57.6V835.2C0 870.4 25.6 896 60.8 896h300.8zM992 896c19.2 0 32-12.8 32-32v-332.8c0-28.8-19.2-51.2-48-51.2s-48 22.4-48 51.2V729.6L531.2 336c-6.4-9.6-19.2-16-35.2-16-12.8 0-25.6 6.4-35.2 16-19.2 19.2-19.2 51.2 0 70.4L857.6 800h-198.4c-28.8 0-51.2 19.2-51.2 48S630.4 896 656 896H992z" horiz-adv-x="1024" />
26
24
 
27
- =======
28
- >>>>>>> 0183ac39 (feat: change icon)
29
25
  <glyph glyph-name="sdoc-callout" unicode="&#58972;" d="M992 352H32c-19.2 0-32 12.8-32 32V832c0 19.2 12.8 32 32 32h960c19.2 0 32-12.8 32-32v-448c0-19.2-12.8-32-32-32zM96 448h832V768H96v-320z m-96-224v-96h1024v96H0z m0-224v-96h576v96H0z" horiz-adv-x="1024" />
30
26
 
31
27
  <glyph glyph-name="sdoc-chart" unicode="&#58971;" d="M992-128H32c-19.2 0-32 12.8-32 32V864c0 19.2 12.8 32 32 32h960c19.2 0 32-12.8 32-32v-960c0-19.2-12.8-32-32-32zM96-32h832V800H96v-832z m0 464v-96h832v96H96zM560 800h-96v-832h96V800z" horiz-adv-x="1024" />
32
28
 
33
- <glyph glyph-name="sdoc-notification" unicode="&#58970;" d="M931.2 80c-3.2 80-44.8 150.4-105.6 198.4V496c0 124.8-89.6 233.6-208 256v6.4C617.6 816 572.8 864 515.2 864S409.6 816 409.6 758.4v-6.4c-118.4-25.6-208-131.2-208-256v-217.6C137.6 233.6 99.2 160 96 80h835.2zM492.8-96h25.6c67.2 0 124.8 51.2 134.4 118.4H377.6c9.6-67.2 64-118.4 134.4-118.4h-19.2z" horiz-adv-x="1024" />
34
-
35
29
  <glyph glyph-name="sdoc-add" unicode="&#58968;" d="M512-128C227.2-128 0 99.2 0 384S227.2 896 512 896s512-227.2 512-512-227.2-512-512-512z m-51.2 563.2H291.2c-19.2 0-35.2-12.8-35.2-35.2v-35.2c0-19.2 12.8-35.2 35.2-35.2h169.6V160c0-19.2 12.8-35.2 35.2-35.2h35.2c19.2 0 35.2 12.8 35.2 35.2v169.6H736c19.2 0 35.2 12.8 35.2 35.2v35.2c0 19.2-12.8 35.2-35.2 35.2h-169.6V604.8c0 19.2-12.8 35.2-35.2 35.2h-35.2c-19.2 0-35.2-12.8-35.2-35.2v-169.6z" horiz-adv-x="1024" />
36
30
 
37
31
  <glyph glyph-name="sdoc-tag" unicode="&#58969;" d="M521.353986 860.33363l466.979644-466.979644c22.389435-22.389435 35.183398-51.175851 35.183398-83.160758s-12.793963-60.771324-35.183398-83.160759l-323.047562-319.849071c-22.389435-22.389435-51.175851-35.183398-79.962268-35.183398-31.984907 0-60.771324 12.793963-83.160758 35.183398L35.183398 374.163042c-25.587926 25.587926-38.381889 60.771324-31.984907 95.954721l31.984907 291.062655c6.396981 54.374342 47.977361 95.954721 102.351703 102.351703l291.062654 31.984907c31.984907 3.198491 67.168305-9.595472 92.756231-35.183398zM444.590209 767.577399L159.924536 735.592492l-31.984908-281.467182L578.926819-0.060372l316.65058 313.45209L444.590209 767.577399z m12.793963-127.939628c57.572833-57.572833 57.572833-147.130573 0-204.703406-25.587926-25.587926-63.969814-41.580379-102.351703-41.580379-38.381889 0-73.565286 12.793963-102.351703 41.580379-57.572833 57.572833-57.572833 147.130573 0 204.703406 57.572833 57.572833 150.329063 57.572833 204.703406 0z m-102.351703-70.366796c-6.396981 0-15.992454-3.198491-22.389435-9.595472-12.793963-12.793963-12.793963-31.984907 0-44.77887 12.793963-12.793963 31.984907-12.793963 44.77887 0 12.793963 12.793963 12.793963 31.984907 0 44.77887-6.396981 6.396981-12.793963 9.595472-22.389435 9.595472z" horiz-adv-x="1024" />
@@ -1,11 +1,11 @@
1
1
  @font-face {
2
2
  font-family: "sdocfont"; /* Project id 4097705 */
3
- src: url('./sdoc-editor-font/iconfont.eot?t=1700642464361'); /* IE9 */
4
- src: url('./sdoc-editor-font/iconfont.eot?t=1700642464361#iefix') format('embedded-opentype'), /* IE6-IE8 */
5
- url('./sdoc-editor-font/iconfont.woff2?t=1700642464361') format('woff2'),
6
- url('./sdoc-editor-font/iconfont.woff?t=1700642464361') format('woff'),
7
- url('./sdoc-editor-font/iconfont.ttf?t=1700642464361') format('truetype'),
8
- url('./sdoc-editor-font/iconfont.svg?t=1700642464361#sdocfont') format('svg');
3
+ src: url('./sdoc-editor-font/iconfont.eot?t=1702000194437'); /* IE9 */
4
+ src: url('./sdoc-editor-font/iconfont.eot?t=1702000194437#iefix') format('embedded-opentype'), /* IE6-IE8 */
5
+ url('./sdoc-editor-font/iconfont.woff2?t=1702000194437') format('woff2'),
6
+ url('./sdoc-editor-font/iconfont.woff?t=1702000194437') format('woff'),
7
+ url('./sdoc-editor-font/iconfont.ttf?t=1702000194437') format('truetype'),
8
+ url('./sdoc-editor-font/iconfont.svg?t=1702000194437#sdocfont') format('svg');
9
9
  }
10
10
 
11
11
  .sdocfont {
@@ -16,8 +16,12 @@
16
16
  -moz-osx-font-smoothing: grayscale;
17
17
  }
18
18
 
19
- .sdoc-selected-text:before {
20
- content: "\e65e";
19
+ .sdoc-comment-quote:before {
20
+ content: "\e660";
21
+ }
22
+
23
+ .sdoc-find-replace:before {
24
+ content: "\e65f";
21
25
  }
22
26
 
23
27
  .sdoc-freezed:before {
@@ -36,10 +40,6 @@
36
40
  content: "\e65b";
37
41
  }
38
42
 
39
- .sdoc-notification:before {
40
- content: "\e65a";
41
- }
42
-
43
43
  .sdoc-add:before {
44
44
  content: "\e658";
45
45
  }
@@ -391,3 +391,4 @@
391
391
  .sdoc-user:before {
392
392
  content: "\e629";
393
393
  }
394
+