@seafile/sdoc-editor 0.5.68 → 0.5.70

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.
@@ -25,8 +25,7 @@ const SdocEditor = forwardRef((_ref, ref) => {
25
25
  isReloading,
26
26
  showComment,
27
27
  isShowHeaderToolbar = true,
28
- showOutline = true,
29
- isWikiReadOnly
28
+ showOutline = true
30
29
  } = _ref;
31
30
  const validEditor = propsEditor || useMemo(() => {
32
31
  const defaultEditor = createDefaultEditor();
@@ -167,22 +166,6 @@ const SdocEditor = forwardRef((_ref, ref) => {
167
166
  }
168
167
  const isShowComment = typeof showComment === 'boolean' ? showComment : true;
169
168
  const Provider = isShowComment ? CollaboratorsProvider : Fragment;
170
- if (isWikiReadOnly) {
171
- return /*#__PURE__*/React.createElement(EditorContainer, {
172
- editor: validEditor,
173
- readonly: isWikiReadOnly
174
- }, /*#__PURE__*/React.createElement(ColorProvider, null, /*#__PURE__*/React.createElement(EditorContent, {
175
- docValue: slateValue,
176
- showOutline: showOutline !== null && showOutline !== void 0 ? showOutline : true,
177
- readonly: isWikiReadOnly,
178
- editor: validEditor,
179
- showComment: isShowComment
180
- }, /*#__PURE__*/React.createElement(ReadOnlyArticle, {
181
- editor: validEditor,
182
- slateValue: slateValue,
183
- showComment: isShowComment
184
- }))));
185
- }
186
169
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(EditorContainer, {
187
170
  editor: validEditor
188
171
  }, /*#__PURE__*/React.createElement(Provider, null, /*#__PURE__*/React.createElement(ColorProvider, null, isShowHeaderToolbar && /*#__PURE__*/React.createElement(HeaderToolbar, {
@@ -0,0 +1,161 @@
1
+ import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
2
+ import React, { useEffect, useState, useImperativeHandle, forwardRef, useMemo, useCallback } from 'react';
3
+ import { Editor } from '@seafile/slate';
4
+ import deepCopy from 'deep-copy';
5
+ import context from '../../context';
6
+ import CommonLoading from '../../components/common-loading';
7
+ import { INTERNAL_EVENT, PAGE_EDIT_AREA_WIDTH } from '../constants';
8
+ import { createDefaultEditor } from '../extension';
9
+ import withNodeId from '../node-id';
10
+ import { withSocketIO } from '../socket';
11
+ import { focusEditor } from '../extension/core';
12
+ import InsertElementDialog from '../extension/commons/insert-element-dialog';
13
+ import { EditorContainer, EditorContent } from '../layout';
14
+ import EditableArticle from './editable-article';
15
+ import { ColorProvider } from '../hooks/use-color-context';
16
+ import ReadOnlyArticle from '../views/readonly-article';
17
+ import { isMobile } from '../../utils';
18
+ import { EventBus } from '../../basic-sdk';
19
+ import { EXTERNAL_EVENT } from '../../constants';
20
+ const WikiEditor = forwardRef((_ref, ref) => {
21
+ let {
22
+ editor: propsEditor,
23
+ document,
24
+ isReloading,
25
+ isWikiReadOnly,
26
+ topSlot
27
+ } = _ref;
28
+ const validEditor = propsEditor || useMemo(() => {
29
+ const defaultEditor = createDefaultEditor();
30
+ const editorConfig = context.getEditorConfig();
31
+ const newEditor = withNodeId(withSocketIO(defaultEditor, {
32
+ document,
33
+ config: editorConfig
34
+ }));
35
+ const {
36
+ cursors
37
+ } = document;
38
+ newEditor.cursors = cursors || {};
39
+ newEditor.width = PAGE_EDIT_AREA_WIDTH; // default width
40
+ return newEditor;
41
+
42
+ // eslint-disable-next-line react-hooks/exhaustive-deps
43
+ }, []);
44
+ const [slateValue, setSlateValue] = useState(document.children);
45
+
46
+ // Fix: The editor's children are not updated when the document is updated in revision
47
+ // In revision mode, the document is updated, but the editor's children are not updated,as onValueChange override the new document.children. This unexpected action cause the editor to display the old content
48
+ useEffect(() => {
49
+ setSlateValue(document.children);
50
+ }, [document.children]);
51
+ useEffect(() => {
52
+ validEditor.readonly = false;
53
+ return () => {
54
+ validEditor.selection = null;
55
+ };
56
+
57
+ // eslint-disable-next-line react-hooks/exhaustive-deps
58
+ }, []);
59
+ // useMount: init socket connection
60
+ useEffect(() => {
61
+ if (propsEditor) return;
62
+ validEditor.openConnection();
63
+ return () => {
64
+ validEditor.closeConnection();
65
+ };
66
+ // eslint-disable-next-line react-hooks/exhaustive-deps
67
+ }, []);
68
+
69
+ // useMount: focus editor
70
+ useEffect(() => {
71
+ const timer = setTimeout(() => {
72
+ const [firstNode] = validEditor.children;
73
+ if (firstNode) {
74
+ const [firstNodeFirstChild] = firstNode.children;
75
+ if (firstNodeFirstChild) {
76
+ const endOfFirstNode = Editor.end(validEditor, [0, 0]);
77
+ const range = {
78
+ anchor: endOfFirstNode,
79
+ focus: endOfFirstNode
80
+ };
81
+ focusEditor(validEditor, range);
82
+ }
83
+ }
84
+ }, 300);
85
+ return () => {
86
+ clearTimeout(timer);
87
+ };
88
+ // eslint-disable-next-line react-hooks/exhaustive-deps
89
+ }, []);
90
+ const onRefreshDocument = useCallback(() => {
91
+ window.location.reload();
92
+ }, []);
93
+
94
+ // useMount: refresh document
95
+ useEffect(() => {
96
+ const eventBus = EventBus.getInstance();
97
+ eventBus.subscribe(EXTERNAL_EVENT.REFRESH_DOCUMENT, onRefreshDocument);
98
+ }, [onRefreshDocument]);
99
+
100
+ // The parent component can call the method of this component through ref
101
+ useImperativeHandle(ref, () => ({
102
+ setSlateValue: document => {
103
+ // Force update of editor's child elements
104
+ validEditor.children = document.children;
105
+ setSlateValue([...document.children]);
106
+ },
107
+ updateDocumentVersion: document => {
108
+ validEditor.updateDocumentVersion(document);
109
+ },
110
+ // get value
111
+ getSlateValue: () => {
112
+ return deepCopy(_objectSpread(_objectSpread({}, document), {}, {
113
+ children: slateValue
114
+ }));
115
+ }
116
+
117
+ // eslint-disable-next-line react-hooks/exhaustive-deps
118
+ }), [document, validEditor, slateValue]);
119
+ const onValueChange = value => {
120
+ const eventBus = EventBus.getInstance();
121
+ eventBus.dispatch(INTERNAL_EVENT.UPDATE_SEARCH_REPLACE_HIGHLIGHT, value);
122
+ setSlateValue(value);
123
+ };
124
+ if (isReloading) {
125
+ return /*#__PURE__*/React.createElement("div", {
126
+ className: "h-100 w-100 d-flex align-items-center justify-content-center"
127
+ }, /*#__PURE__*/React.createElement(CommonLoading, null));
128
+ }
129
+ if (isMobile || isWikiReadOnly) {
130
+ return /*#__PURE__*/React.createElement(EditorContainer, {
131
+ editor: validEditor,
132
+ readonly: true
133
+ }, /*#__PURE__*/React.createElement(ColorProvider, null, /*#__PURE__*/React.createElement(EditorContent, {
134
+ docValue: slateValue,
135
+ readonly: true,
136
+ showOutline: false,
137
+ editor: validEditor,
138
+ showComment: false
139
+ }, topSlot, /*#__PURE__*/React.createElement(ReadOnlyArticle, {
140
+ editor: validEditor,
141
+ slateValue: slateValue,
142
+ showComment: false
143
+ }))));
144
+ }
145
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(EditorContainer, {
146
+ editor: validEditor
147
+ }, /*#__PURE__*/React.createElement(ColorProvider, null, /*#__PURE__*/React.createElement(EditorContent, {
148
+ docValue: slateValue,
149
+ showOutline: false,
150
+ editor: validEditor,
151
+ showComment: false
152
+ }, topSlot, /*#__PURE__*/React.createElement(EditableArticle, {
153
+ editor: validEditor,
154
+ slateValue: slateValue,
155
+ updateSlateValue: onValueChange,
156
+ showComment: false
157
+ })))), /*#__PURE__*/React.createElement(InsertElementDialog, {
158
+ editor: validEditor
159
+ }));
160
+ });
161
+ export default WikiEditor;
@@ -81,7 +81,7 @@ class HeaderMenu extends React.Component {
81
81
  this.menu = ref;
82
82
  });
83
83
  _defineProperty(this, "getToolTip", type => {
84
- return isMac ? MAC_HOTKEYS[type] : WIN_HOTKEYS[type];
84
+ return isMac() ? MAC_HOTKEYS[type] : WIN_HOTKEYS[type];
85
85
  });
86
86
  this.state = {
87
87
  isShowHeaderPopover: false
@@ -42,15 +42,15 @@ const LinkMenu = _ref => {
42
42
  }
43
43
 
44
44
  // eslint-disable-next-line react-hooks/rules-of-hooks
45
- const printShortCutTexts = useMemo(() => {
46
- const printTexts = isMac ? ['⌘', 'k'] : ['Ctrl', 'k'];
45
+ const linkShortCutTexts = useMemo(() => {
46
+ const printTexts = isMac() ? ['⌘', 'k'] : ['Ctrl', 'k'];
47
47
  return printTexts;
48
48
  }, []);
49
49
  return /*#__PURE__*/React.createElement(DropdownMenuItem, {
50
50
  disabled: disabled,
51
51
  menuConfig: menuConfig,
52
52
  onClick: openLinkDialog,
53
- shortcut: printShortCutTexts
53
+ shortcut: linkShortCutTexts
54
54
  });
55
55
  };
56
56
  export default LinkMenu;
@@ -73,6 +73,8 @@ const withLink = editor => {
73
73
  } = newEditor;
74
74
  const isCollapsed = Range.isCollapsed(selection);
75
75
  if (isHotkey('mod+k', e) && isCollapsed) {
76
+ // Prevent edge behavior
77
+ e.preventDefault();
76
78
  const eventBus = EventBus.getInstance();
77
79
  eventBus.dispatch(INTERNAL_EVENT.INSERT_ELEMENT, {
78
80
  type: ELEMENT_TYPE.LINK,
@@ -2,7 +2,7 @@ import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
2
2
  import isHotkey from 'is-hotkey';
3
3
  import { Editor, Transforms, Path, Element } from '@seafile/slate';
4
4
  import { ReactEditor } from '@seafile/slate-react';
5
- import { getNodeType, getParentNode, getSelectedNodeByType, isLastNode, generateEmptyElement, focusEditor } from '../../core';
5
+ import { getNodeType, getParentNode, getSelectedNodeByType, isLastNode, generateEmptyElement, focusEditor, getAboveBlockNode } from '../../core';
6
6
  import { ELEMENT_TYPE, KEYBOARD, PARAGRAPH, CLIPBOARD_FORMAT_KEY, CHECK_LIST_ITEM, ORDERED_LIST, UNORDERED_LIST, TABLE_ROW, TABLE, TABLE_CELL } from '../../constants';
7
7
  import { TABLE_MAX_ROWS, EMPTY_SELECTED_RANGE, TABLE_ELEMENT, TABLE_ELEMENT_POSITION, TABLE_CELL_MIN_WIDTH, TABLE_ROW_MIN_HEIGHT } from './constants';
8
8
  import ObjectUtils from '../../../utils/object-utils';
@@ -58,6 +58,13 @@ const withTable = editor => {
58
58
  if (isHotkey('tab', event)) {
59
59
  event.preventDefault();
60
60
  }
61
+ if (isHotkey('shift+enter', event)) {
62
+ event.preventDefault();
63
+ const [, tablePath] = getAboveBlockNode(newEditor);
64
+ const focusPath = [tablePath[0] + 1];
65
+ const focusPoint = Editor.start(newEditor, focusPath);
66
+ focusEditor(newEditor, focusPoint);
67
+ }
61
68
  };
62
69
  newEditor.insertBreak = () => {
63
70
  const selectedNode = getSelectedNodeByType(newEditor, ELEMENT_TYPE.TABLE);
@@ -58,8 +58,7 @@ export const getHeaderHeight = editor => {
58
58
  } = editor;
59
59
  switch (editorType) {
60
60
  case WIKI_EDITOR:
61
- // sdoc-editor-page-header height = 49
62
- return 49;
61
+ return 113.2;
63
62
  default:
64
63
  // sdoc-editor-page-header height = 56
65
64
  // sdoc-editor-toolbar height = 37
@@ -56,8 +56,8 @@ const MoreOperations = _ref => {
56
56
  event.nativeEvent.stopImmediatePropagation();
57
57
  window.location.href = historyURL;
58
58
  }, [docPerm, historyURL, isSdocRevision]);
59
- const printShortCutTexts = useMemo(() => {
60
- const printTexts = isMac ? ['⌘', 'P'] : ['Ctrl', 'P'];
59
+ const printShortcutTexts = useMemo(() => {
60
+ const printTexts = isMac() ? ['⌘', 'P'] : ['Ctrl', 'P'];
61
61
  return printTexts;
62
62
  }, []);
63
63
  return /*#__PURE__*/React.createElement(Dropdown, {
@@ -78,7 +78,7 @@ const MoreOperations = _ref => {
78
78
  }, /*#__PURE__*/React.createElement("div", {
79
79
  className: "sdoc-dropdown-print-container"
80
80
  }, /*#__PURE__*/React.createElement("div", null, t('Print')), /*#__PURE__*/React.createElement(MenuShortcutPrompt, {
81
- shortcuts: printShortCutTexts
81
+ shortcuts: printShortcutTexts
82
82
  }))), isPro && isFreezed && /*#__PURE__*/React.createElement(DropdownItem, {
83
83
  className: "sdoc-dropdown-menu-item",
84
84
  onClick: unFreeze
@@ -2,21 +2,25 @@ import React, { useEffect, useMemo } from 'react';
2
2
  import { withTranslation } from 'react-i18next';
3
3
  import context from '../context';
4
4
  import ErrorBoundary from './error-boundary';
5
- import { SDocEditor } from '../basic-sdk';
6
5
  import { PAGE_EDIT_AREA_WIDTH, WIKI_EDITOR } from '../basic-sdk/constants';
7
6
  import { createWikiEditor } from '../basic-sdk/extension';
8
7
  import withNodeId from '../basic-sdk/node-id';
9
8
  import { withSocketIO } from '../basic-sdk/socket';
9
+ import { TITLE } from '../basic-sdk/extension/constants';
10
+ import WikiEditor from '../basic-sdk/editor/wiki-editor';
10
11
  import '../assets/css/simple-viewer.css';
11
12
  const SdocWikiViewer = _ref => {
12
13
  let {
13
14
  document,
14
- showOutline,
15
- scrollRef,
16
15
  docUuid,
17
- isWikiReadOnly
16
+ isWikiReadOnly,
17
+ topSlot
18
18
  } = _ref;
19
19
  context.initApi();
20
+
21
+ // Wiki editor need filter initialized title node
22
+ const [firstNode, ...restNodes] = document.children;
23
+ if (firstNode.type === TITLE) document.children = restNodes;
20
24
  const validEditor = useMemo(() => {
21
25
  const defaultEditor = createWikiEditor();
22
26
  // getEditorConfig cashe the config, so we need to update the uuid,for wiki editor
@@ -42,15 +46,12 @@ const SdocWikiViewer = _ref => {
42
46
  validEditor.closeConnection();
43
47
  };
44
48
  }, [validEditor]);
45
- return /*#__PURE__*/React.createElement(ErrorBoundary, null, /*#__PURE__*/React.createElement(SDocEditor, {
46
- showComment: false,
49
+ return /*#__PURE__*/React.createElement(ErrorBoundary, null, /*#__PURE__*/React.createElement(WikiEditor, {
47
50
  document: document,
48
- showOutline: showOutline,
49
- scrollRef: scrollRef,
50
51
  docUuid: docUuid,
51
- isShowHeaderToolbar: false,
52
52
  editor: validEditor,
53
- isWikiReadOnly: isWikiReadOnly
53
+ isWikiReadOnly: isWikiReadOnly,
54
+ topSlot: topSlot
54
55
  }));
55
56
  };
56
57
  export default withTranslation('sdoc-editor')(SdocWikiViewer);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seafile/sdoc-editor",
3
- "version": "0.5.68",
3
+ "version": "0.5.70",
4
4
  "private": false,
5
5
  "description": "This is a sdoc editor",
6
6
  "main": "dist/index.js",