@seafile/sdoc-editor 0.5.30 → 0.5.31

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 (31) hide show
  1. package/dist/basic-sdk/assets/css/layout.css +11 -15
  2. package/dist/basic-sdk/assets/css/simple-viewer.css +0 -10
  3. package/dist/basic-sdk/comment/components/comment-all-participants/index.css +8 -8
  4. package/dist/basic-sdk/comment/components/comment-editor.js +18 -18
  5. package/dist/basic-sdk/comment/components/comment-item-wrapper.js +4 -2
  6. package/dist/basic-sdk/comment/components/comment-list.css +22 -8
  7. package/dist/basic-sdk/comment/components/comment-list.js +7 -2
  8. package/dist/basic-sdk/comment/components/editor-comment.js +12 -10
  9. package/dist/basic-sdk/comment/components/elements-comment-count/element-comment-count.js +4 -8
  10. package/dist/basic-sdk/comment/components/elements-comment-count/index.js +4 -2
  11. package/dist/basic-sdk/comment/components/global-comment/global-comment-editor.js +2 -18
  12. package/dist/basic-sdk/comment/components/global-comment/index.css +56 -30
  13. package/dist/basic-sdk/comment/components/global-comment/index.js +95 -30
  14. package/dist/basic-sdk/comment/index.js +11 -10
  15. package/dist/basic-sdk/comment/provider/comment-context-provider.js +2 -3
  16. package/dist/basic-sdk/comment/provider/index.js +7 -2
  17. package/dist/basic-sdk/comment/provider/notification-context-provider.js +2 -3
  18. package/dist/basic-sdk/editor/comment-article.js +0 -101
  19. package/dist/basic-sdk/editor/editable-article.js +4 -1
  20. package/dist/basic-sdk/editor/sdoc-editor.js +6 -3
  21. package/dist/basic-sdk/extension/plugins/image/plugin.js +1 -1
  22. package/dist/basic-sdk/extension/plugins/list/plugin/index.js +17 -10
  23. package/dist/basic-sdk/hooks/use-selection-element.js +4 -3
  24. package/dist/basic-sdk/layout/article-container.js +10 -1
  25. package/dist/basic-sdk/layout/editor-content.js +18 -11
  26. package/dist/basic-sdk/outline/index.js +4 -1
  27. package/dist/basic-sdk/outline/style.css +12 -6
  28. package/dist/basic-sdk/views/readonly-article.js +4 -1
  29. package/dist/basic-sdk/views/sdoc-viewer.js +5 -3
  30. package/dist/layout/layout.css +0 -5
  31. package/package.json +1 -1
@@ -1,8 +1,6 @@
1
1
  import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
2
2
  import React, { useCallback, useEffect, useRef, useState } from 'react';
3
3
  import dayjs from 'dayjs';
4
- import { useSlateStatic, ReactEditor } from '@seafile/slate-react';
5
- import { ElementPopover } from '../../../extension/commons';
6
4
  import EventBus from '../../../utils/event-bus';
7
5
  import useCommentList from '../../hooks/comment-hooks/use-comment-list';
8
6
  import CommentItemWrapper from '../comment-item-wrapper';
@@ -14,25 +12,37 @@ import { useCommentContext } from '../../hooks/comment-hooks/use-comment-context
14
12
  import GlobalCommentEditor from './global-comment-editor';
15
13
  import { INTERNAL_EVENT } from '../../../constants';
16
14
  import { getNodeById } from '../../../extension/core';
17
- import { useScrollContext } from '../../../hooks/use-scroll-context';
18
- import { focusToCommentElement } from '../../utils';
19
15
  import './index.css';
20
16
  const GlobalComment = _ref => {
21
17
  let {
22
- deleteUnseenNotifications
18
+ deleteUnseenNotifications,
19
+ editor
23
20
  } = _ref;
24
21
  const [activeComment, setActiveComment] = useState(null);
22
+ const [isShowCommentList, setShowCommentList] = useState(false);
23
+ const [showEditor, setShowEditor] = useState(false);
24
+ const [draggerStyle, setDraggerStyle] = useState({});
25
25
  const commentRef = useRef(null);
26
26
  const contentRef = useRef(null);
27
+ const commentDrawerRef = useRef(null);
28
+ const isResizingRef = useRef(false);
29
+ const commentResizeHandler = useRef(null);
27
30
  const {
28
31
  commentList,
29
32
  commentType,
30
33
  setCommentType
31
34
  } = useCommentList();
32
- const [isShowCommentList, setShowCommentList] = useState(false);
33
- const [showEditor, setShowEditor] = useState(false);
34
- const editor = useSlateStatic();
35
- const scrollRef = useScrollContext();
35
+ const setArticleContainerStyle = useCallback(() => {
36
+ const eventBus = EventBus.getInstance();
37
+ eventBus.dispatch(INTERNAL_EVENT.OUTLINE_STATE_CHANGED, {
38
+ scrollIntoArticle: true
39
+ });
40
+ }, []);
41
+ useEffect(() => {
42
+ if (isShowCommentList) {
43
+ setArticleContainerStyle();
44
+ }
45
+ }, [isShowCommentList, setArticleContainerStyle]);
36
46
  const toggle = useCallback(() => {
37
47
  if (isShowCommentList) {
38
48
  setActiveComment(null);
@@ -42,26 +52,52 @@ const GlobalComment = _ref => {
42
52
  }
43
53
  setShowCommentList(true);
44
54
  }, [isShowCommentList]);
45
- useEffect(() => {
46
- if (!isShowCommentList) return;
47
- const toggleOuterSide = e => {
48
- const commentWrapper = commentRef.current;
49
- const clickIsInComment = commentWrapper && commentWrapper.contains(e.target) && commentWrapper !== e.target;
50
- if (clickIsInComment) return;
51
- toggle();
52
- };
53
- document.addEventListener('click', toggleOuterSide);
54
- return () => {
55
- document.removeEventListener('click', toggleOuterSide);
56
- };
57
- }, [isShowCommentList, toggle]);
55
+ const handleHideDragger = useCallback(event => {
56
+ if (isResizingRef.current) return;
57
+ setDraggerStyle({
58
+ display: 'none'
59
+ });
60
+ }, []);
61
+ const handleResizeEnd = useCallback(e => {
62
+ e.preventDefault();
63
+ e.stopPropagation();
64
+ isResizingRef.current = false;
65
+ document.removeEventListener('mouseup', handleResizeEnd);
66
+ handleHideDragger();
67
+ }, [handleHideDragger]);
68
+ const handleResizing = useCallback(e => {
69
+ e.preventDefault();
70
+ e.stopPropagation();
71
+ const commentDrawer = commentDrawerRef.current;
72
+ if (isResizingRef.current && commentDrawer) {
73
+ let width = commentDrawer.offsetWidth - e.movementX;
74
+ // Limit the width of the comment drawer
75
+ width = Math.min(width, 620);
76
+ width = Math.max(width, 360);
77
+ commentDrawer.style.width = "".concat(width, "px");
78
+ const isShrink = e.movementX > 0;
79
+ setArticleContainerStyle({
80
+ width,
81
+ isShrink
82
+ });
83
+ }
84
+ }, [setArticleContainerStyle]);
85
+ const handleResizeStart = useCallback(e => {
86
+ e.preventDefault();
87
+ e.stopPropagation();
88
+ isResizingRef.current = true;
89
+ document.addEventListener('mouseup', handleResizeEnd);
90
+ document.addEventListener('mousemove', handleResizing);
91
+ }, [handleResizeEnd, handleResizing]);
58
92
  useEffect(() => {
59
93
  const eventBus = EventBus.getInstance();
60
94
  const unsubscribe = eventBus.subscribe(INTERNAL_EVENT.COMMENT_LIST_CLICK, toggle);
61
95
  return () => {
62
96
  unsubscribe();
97
+ document.removeEventListener('mousemove', handleResizing);
98
+ eventBus.dispatch(INTERNAL_EVENT.OUTLINE_STATE_CHANGED);
63
99
  };
64
- }, [toggle]);
100
+ }, [handleResizing, toggle]);
65
101
  const updateScrollPosition = useCallback(() => {
66
102
  const resolvedDom = document.querySelector('.sdoc-resolved');
67
103
  contentRef.current.scrollTo({
@@ -78,10 +114,7 @@ const GlobalComment = _ref => {
78
114
  deleteUnseenNotifications && deleteUnseenNotifications(comment);
79
115
  if (comment.detail.element_id === DOC_COMMENT_ELEMENT_ID) return;
80
116
  if (!element) return;
81
- const elementDom = ReactEditor.toDOMNode(editor, element, scrollRef);
82
- scrollRef.current.scrollTop = elementDom.offsetTop - scrollRef.current.clientHeight / 3;
83
- focusToCommentElement(editor, element);
84
- }, [activeComment, deleteUnseenNotifications, editor, scrollRef]);
117
+ }, [activeComment, deleteUnseenNotifications]);
85
118
  const {
86
119
  dispatch
87
120
  } = useCommentContext();
@@ -127,10 +160,40 @@ const GlobalComment = _ref => {
127
160
  const hiddenCommentEditor = useCallback(() => {
128
161
  setShowEditor(false);
129
162
  }, []);
163
+ const handleDisplayDragger = useCallback(event => {
164
+ if (isShowCommentList) {
165
+ const {
166
+ pageY
167
+ } = event;
168
+ const {
169
+ top
170
+ } = commentResizeHandler.current.getBoundingClientRect();
171
+ // 15 is the half height of the dragger
172
+ const topSize = pageY - top - 15;
173
+ setDraggerStyle({
174
+ top: "".concat(topSize, "px"),
175
+ display: 'block'
176
+ });
177
+ }
178
+ }, [isShowCommentList]);
179
+ const isClickCommentPanelBody = useCallback(event => {
180
+ if (contentRef.current && contentRef.current.contains(event.target)) return true;
181
+ return false;
182
+ }, []);
130
183
  if (!isShowCommentList) return null;
131
- return /*#__PURE__*/React.createElement(ElementPopover, {
132
- className: "global-comments-popover"
184
+ return /*#__PURE__*/React.createElement("div", {
185
+ className: "sdoc-comment-drawer",
186
+ ref: commentDrawerRef
187
+ }, /*#__PURE__*/React.createElement("div", {
188
+ ref: commentResizeHandler,
189
+ className: "sdoc-comment-resize-handler",
190
+ onMouseDown: handleResizeStart,
191
+ onMouseLeave: handleHideDragger,
192
+ onMouseMove: handleDisplayDragger
133
193
  }, /*#__PURE__*/React.createElement("div", {
194
+ style: draggerStyle,
195
+ className: "sdoc-comment-move-dragger"
196
+ })), /*#__PURE__*/React.createElement("div", {
134
197
  ref: commentRef,
135
198
  className: "comments-panel-wrapper"
136
199
  }, /*#__PURE__*/React.createElement(GlobalCommentHeader, {
@@ -160,9 +223,11 @@ const GlobalComment = _ref => {
160
223
  isActive: isActive,
161
224
  onCommentClick: comment => onCommentClick(comment, element),
162
225
  hiddenComment: hiddenComment,
163
- updateScrollPosition: updateScrollPosition
226
+ updateScrollPosition: updateScrollPosition,
227
+ isClickCommentPanelBody: isClickCommentPanelBody
164
228
  });
165
229
  }))), showEditor && /*#__PURE__*/React.createElement(GlobalCommentEditor, {
230
+ isClickCommentPanelBody: isClickCommentPanelBody,
166
231
  hiddenCommentEditor: hiddenCommentEditor,
167
232
  insertDocComment: insertDocComment
168
233
  }))));
@@ -2,12 +2,14 @@ import React, { useCallback } from 'react';
2
2
  import { useCommentContext } from './hooks/comment-hooks/use-comment-context';
3
3
  import { useNotificationContext } from './hooks/notification-hooks';
4
4
  import { EditorComment, GlobalComment } from './components';
5
- import { ParticipantsProvider } from './hooks/use-participants';
6
- import Provider from './provider';
7
5
  import { generatorNotificationKey } from './utils';
8
6
  import context from '../../context';
9
7
  import { DOC_NOTIFICATION_REDUCER_TYPE } from './constants';
10
- const CommentWrapperContainer = () => {
8
+ const CommentWrapper = _ref => {
9
+ let {
10
+ type,
11
+ editor
12
+ } = _ref;
11
13
  const {
12
14
  commentsInfo
13
15
  } = useCommentContext();
@@ -45,13 +47,12 @@ const CommentWrapperContainer = () => {
45
47
  isFreezed
46
48
  } = context.getSettings('isFreezed');
47
49
  if (commentsInfo.isFetching) return null;
48
- return /*#__PURE__*/React.createElement(React.Fragment, null, !isFreezed && /*#__PURE__*/React.createElement(EditorComment, {
49
- deleteUnseenNotifications: deleteUnseenNotifications
50
- }), /*#__PURE__*/React.createElement(GlobalComment, {
51
- deleteUnseenNotifications: deleteUnseenNotifications
50
+ return /*#__PURE__*/React.createElement(React.Fragment, null, type === 'editor' && !isFreezed && /*#__PURE__*/React.createElement(EditorComment, {
51
+ deleteUnseenNotifications: deleteUnseenNotifications,
52
+ editor: editor
53
+ }), type === 'global' && /*#__PURE__*/React.createElement(GlobalComment, {
54
+ deleteUnseenNotifications: deleteUnseenNotifications,
55
+ editor: editor
52
56
  }));
53
57
  };
54
- const CommentWrapper = () => {
55
- return /*#__PURE__*/React.createElement(Provider, null, /*#__PURE__*/React.createElement(ParticipantsProvider, null, /*#__PURE__*/React.createElement(CommentWrapperContainer, null)));
56
- };
57
58
  export default CommentWrapper;
@@ -1,16 +1,15 @@
1
1
  import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
2
2
  import React, { useEffect, useReducer } from 'react';
3
- import { useSlateStatic } from '@seafile/slate-react';
4
3
  import { commentReducer, initCommentsInfo } from '../reducer/comment-reducer';
5
4
  import { useCommentsMount } from '../hooks/comment-hooks/use-comment-mount';
6
5
  import { CommentContext } from '../hooks/comment-hooks/use-comment-context';
7
6
  const CommentContextProvider = _ref => {
8
7
  let {
9
- children
8
+ children,
9
+ editor
10
10
  } = _ref;
11
11
  const [commentsInfo, dispatch] = useReducer(commentReducer, initCommentsInfo);
12
12
  useCommentsMount(dispatch);
13
- const editor = useSlateStatic();
14
13
  useEffect(() => {
15
14
  editor.element_comments_map = _objectSpread({}, commentsInfo.element_comments_map);
16
15
  // eslint-disable-next-line react-hooks/exhaustive-deps
@@ -3,8 +3,13 @@ import CommentContextProvider from './comment-context-provider';
3
3
  import NotificationContextProvider from './notification-context-provider';
4
4
  const Provider = _ref => {
5
5
  let {
6
- children
6
+ children,
7
+ editor
7
8
  } = _ref;
8
- return /*#__PURE__*/React.createElement(NotificationContextProvider, null, /*#__PURE__*/React.createElement(CommentContextProvider, null, children));
9
+ return /*#__PURE__*/React.createElement(NotificationContextProvider, {
10
+ editor: editor
11
+ }, /*#__PURE__*/React.createElement(CommentContextProvider, {
12
+ editor: editor
13
+ }, children));
9
14
  };
10
15
  export default Provider;
@@ -1,15 +1,14 @@
1
1
  import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
2
2
  import React, { useEffect, useReducer } from 'react';
3
- import { useSlateStatic } from '@seafile/slate-react';
4
3
  import { notificationReducer, initNotificationsInfo } from '../reducer/notification-reducer';
5
4
  import { useNotificationsMount, NotificationContext } from '../hooks/notification-hooks';
6
5
  const NotificationContextProvider = _ref => {
7
6
  let {
8
- children
7
+ children,
8
+ editor
9
9
  } = _ref;
10
10
  const [notificationsInfo, dispatch] = useReducer(notificationReducer, initNotificationsInfo);
11
11
  useNotificationsMount(dispatch);
12
- const editor = useSlateStatic();
13
12
  useEffect(() => {
14
13
  editor.notifications_map = _objectSpread({}, notificationsInfo.notifications_map);
15
14
  // eslint-disable-next-line react-hooks/exhaustive-deps
@@ -3,14 +3,11 @@ import React, { useCallback, useMemo } from 'react';
3
3
  import { Editable, ReactEditor, Slate } from '@seafile/slate-react';
4
4
  import { Editor, Node, Range } from '@seafile/slate';
5
5
  import { renderLeaf } from '../extension';
6
- import { getAboveBlockNode, getNextNode, getPrevNode, isSelectionAtBlockEnd, isSelectionAtBlockStart } from '../extension/core';
7
6
  import EventProxy from '../utils/event-handler';
8
7
  import { useCursors } from '../cursor/use-cursors';
9
8
  import { INTERNAL_EVENT } from '../constants';
10
9
  import { usePipDecorate } from '../decorates';
11
- import { getCursorPosition, getDomHeight, getDomMarginTop } from '../utils/dom-utils';
12
10
  import EventBus from '../utils/event-bus';
13
- import { useScrollContext } from '../hooks/use-scroll-context';
14
11
  import { IMAGE } from '../extension/constants';
15
12
  import RenderCommentEditorCustomRenderElement from '../extension/render/render-comment-editor-element';
16
13
  const CommentArticle = _ref => {
@@ -36,103 +33,6 @@ const CommentArticle = _ref => {
36
33
  }
37
34
  // eslint-disable-next-line react-hooks/exhaustive-deps
38
35
  }, []);
39
- const scrollRef = useScrollContext();
40
- const onKeyDown = useCallback(event => {
41
- const {
42
- scrollTop,
43
- clientHeight
44
- } = scrollRef.current;
45
- eventProxy.onKeyDown(event);
46
- if (event.key === 'ArrowLeft') {
47
- if (!isSelectionAtBlockStart(editor)) return;
48
- }
49
- if (event.key === 'ArrowUp' || event.key === 'ArrowLeft') {
50
- if (scrollTop === 0) return;
51
- let prevNode = getPrevNode(editor);
52
- if (!prevNode) return;
53
- const domNode = ReactEditor.toDOMNode(editor, prevNode[0]);
54
- const domHeight = getDomHeight(domNode);
55
- const isScrollUp = true;
56
- const {
57
- y
58
- } = getCursorPosition(isScrollUp);
59
- if (y >= domHeight) return;
60
- scrollRef.current.scroll(0, Math.max(0, scrollTop - domHeight));
61
- return;
62
- }
63
- if (event.key === 'ArrowRight') {
64
- if (!isSelectionAtBlockEnd(editor)) return;
65
- }
66
- if (event.key === 'ArrowDown' || event.key === 'ArrowRight') {
67
- let nextNode = getNextNode(editor);
68
- if (!nextNode) return;
69
- const domNode = ReactEditor.toDOMNode(editor, nextNode[0]);
70
- const domHeight = getDomHeight(domNode);
71
- const isScrollUp = false;
72
- const {
73
- y
74
- } = getCursorPosition(isScrollUp);
75
- if (clientHeight - y >= domHeight) return;
76
- scrollRef.current.scroll(0, Math.max(0, scrollTop + domHeight));
77
- return;
78
- }
79
- if (event.key === 'Backspace') {
80
- const {
81
- y
82
- } = getCursorPosition();
83
-
84
- // above viewport
85
- if (y < 0) {
86
- const newY = Math.abs(y);
87
- if (isSelectionAtBlockStart(editor)) {
88
- const prevNode = getPrevNode(editor);
89
- if (!prevNode) return;
90
- const domNode = ReactEditor.toDOMNode(editor, prevNode[0]);
91
- const domHeight = getDomHeight(domNode);
92
- const node = getAboveBlockNode(editor);
93
- if (!node) return;
94
- const currentDomNode = ReactEditor.toDOMNode(editor, node[0]);
95
- const marginTop = getDomMarginTop(currentDomNode);
96
- scrollRef.current.scroll(0, Math.max(0, scrollTop - (newY + domHeight + marginTop)));
97
- } else {
98
- scrollRef.current.scroll(0, Math.max(0, scrollTop - newY));
99
- }
100
- return;
101
- }
102
-
103
- // insider viewport
104
- if (y >= 0 && y <= clientHeight) {
105
- if (isSelectionAtBlockStart(editor)) {
106
- const prevNode = getPrevNode(editor);
107
- if (!prevNode) return;
108
- const domNode = ReactEditor.toDOMNode(editor, prevNode[0]);
109
- const domHeight = getDomHeight(domNode);
110
- if (y >= domHeight) return;
111
- // Scroll up the height of the previous block
112
- scrollRef.current.scroll(0, Math.max(0, scrollTop - domHeight));
113
- return;
114
- }
115
- }
116
-
117
- // below viewport
118
- if (y > clientHeight) {
119
- if (isSelectionAtBlockStart(editor)) {
120
- // y: text top border
121
- scrollRef.current.scroll(0, Math.max(0, scrollTop + (y - clientHeight)));
122
- } else {
123
- const marginBottom = 11.2;
124
- const {
125
- y: newY
126
- } = getCursorPosition(false);
127
- const rectBottom = newY + marginBottom; // text bottom border
128
- scrollRef.current.scroll(0, Math.max(0, scrollTop + (rectBottom - clientHeight)));
129
- }
130
- return;
131
- }
132
- }
133
-
134
- // eslint-disable-next-line react-hooks/exhaustive-deps
135
- }, [scrollRef]);
136
36
  const handleScrollIntoView = useCallback((editor, domRange) => {
137
37
  try {
138
38
  const {
@@ -167,7 +67,6 @@ const CommentArticle = _ref => {
167
67
  commentType: type
168
68
  })),
169
69
  renderLeaf: renderLeaf,
170
- onKeyDown: onKeyDown,
171
70
  onMouseDown: onMouseDown,
172
71
  decorate: decorate,
173
72
  onCut: eventProxy.onCut,
@@ -177,7 +177,10 @@ const EditableArticle = _ref => {
177
177
  decorate: decorate,
178
178
  onCut: eventProxy.onCut,
179
179
  onCopy: eventProxy.onCopy
180
- })), /*#__PURE__*/React.createElement(SideToolbar, null), isShowComment && /*#__PURE__*/React.createElement(CommentWrapper, null)));
180
+ })), /*#__PURE__*/React.createElement(SideToolbar, null), isShowComment && /*#__PURE__*/React.createElement(CommentWrapper, {
181
+ editor: editor,
182
+ type: "editor"
183
+ })));
181
184
  };
182
185
  EditableArticle.defaultProps = {
183
186
  isShowComment: true
@@ -128,7 +128,8 @@ const SdocEditor = forwardRef((_ref, ref) => {
128
128
  }, /*#__PURE__*/React.createElement(ColorProvider, null, /*#__PURE__*/React.createElement(EditorContent, {
129
129
  docValue: slateValue,
130
130
  readonly: true,
131
- showOutline: false
131
+ showOutline: false,
132
+ editor: validEditor
132
133
  }, /*#__PURE__*/React.createElement(ReadOnlyArticle, {
133
134
  editor: validEditor,
134
135
  slateValue: slateValue
@@ -144,7 +145,8 @@ const SdocEditor = forwardRef((_ref, ref) => {
144
145
  }), /*#__PURE__*/React.createElement(EditorContent, {
145
146
  docValue: slateValue,
146
147
  showOutline: true,
147
- readonly: isFreezed
148
+ readonly: isFreezed,
149
+ editor: validEditor
148
150
  }, /*#__PURE__*/React.createElement(ReadOnlyArticle, {
149
151
  editor: validEditor,
150
152
  slateValue: slateValue,
@@ -162,7 +164,8 @@ const SdocEditor = forwardRef((_ref, ref) => {
162
164
  editor: validEditor
163
165
  }), /*#__PURE__*/React.createElement(EditorContent, {
164
166
  docValue: slateValue,
165
- showOutline: true
167
+ showOutline: true,
168
+ editor: validEditor
166
169
  }, /*#__PURE__*/React.createElement(EditableArticle, {
167
170
  editor: validEditor,
168
171
  slateValue: slateValue,
@@ -114,7 +114,7 @@ const withImage = editor => {
114
114
  const point = Editor.before(editor, selection, {
115
115
  distance: 1
116
116
  });
117
- if (!point) return;
117
+ if (!point) return deleteBackward(unit);
118
118
  const [node, path] = Editor.node(editor, [point.path[0], point.path[1]]);
119
119
  const isPerviousNodeImage = node.type === IMAGE;
120
120
  if (isPerviousNodeImage && Range.isCollapsed(selection) && isBlockAboveEmpty(editor) && !Path.isCommon(path, selection.anchor.path)) {
@@ -1,12 +1,13 @@
1
- import { Editor, Transforms } from '@seafile/slate';
1
+ import { Editor, Range } from '@seafile/slate';
2
2
  import { insertBreakList } from './insert-break-list';
3
3
  import { onTabHandle } from './on-tab-handle';
4
4
  import { normalizeList } from './normalize-list';
5
5
  import { insertFragmentList } from './insert-fragment-list';
6
6
  import { handleShortcut } from './shortcut';
7
- import { getSelectedNodeEntryByType } from '../../../core';
8
- import { BLOCKQUOTE, LIST_ITEM } from '../../../constants';
7
+ import { focusEditor, getSelectedNodeEntryByType } from '../../../core';
8
+ import { LIST_ITEM } from '../../../constants';
9
9
  import { isList } from '../../../toolbar/side-toolbar/helpers';
10
+ import { unwrapList } from '../transforms';
10
11
  const withList = editor => {
11
12
  const {
12
13
  insertBreak,
@@ -31,15 +32,21 @@ const withList = editor => {
31
32
  const listItemEntry = getSelectedNodeEntryByType(editor, LIST_ITEM);
32
33
  if (listItemEntry) {
33
34
  const [, listItemPath] = listItemEntry;
34
- const blockQuoteEntry = getSelectedNodeEntryByType(editor, BLOCKQUOTE);
35
- if (blockQuoteEntry) {
36
- const isStart = Editor.isStart(editor, editor.selection.anchor, listItemPath);
37
- if (isStart) {
38
- // This is a tricky way to delete the blockquote and create a new paragraph
39
- Transforms.removeNodes(editor, {
35
+
36
+ // Transforms to paragraph when press backspace at the start of the list item, and the list item is the first child of the list
37
+ const isAtStartOfListItem = Editor.isStart(editor, selection.anchor, listItemPath);
38
+ const isCollapsed = Range.isCollapsed(selection);
39
+ if (isCollapsed && isAtStartOfListItem) {
40
+ const previous = Editor.previous(editor, {
41
+ at: listItemPath
42
+ });
43
+ // previous is undefined when the list item is the first child of the list
44
+ if (!previous) {
45
+ unwrapList(newEditor, {
40
46
  at: listItemPath
41
47
  });
42
- insertBreak();
48
+ const focusPoint = Editor.start(newEditor, listItemPath);
49
+ focusEditor(newEditor, focusPoint);
43
50
  return;
44
51
  }
45
52
  }
@@ -1,8 +1,9 @@
1
1
  import { Editor, Element } from '@seafile/slate';
2
- import { useSlateStatic } from '@seafile/slate-react';
3
2
  import { useMemo } from 'react';
4
- export const useSelectionElement = () => {
5
- const editor = useSlateStatic();
3
+ export const useSelectionElement = _ref => {
4
+ let {
5
+ editor
6
+ } = _ref;
6
7
  const nodeEntry = useMemo(() => {
7
8
  const nodeEntry = Editor.above(editor, {
8
9
  mode: 'lowest',
@@ -15,7 +15,10 @@ export default function ArticleContainer(_ref) {
15
15
  }, []);
16
16
  const scrollRef = useScrollContext();
17
17
  const [containerStyle, setContainerStyle] = useState({});
18
- const handleWindowResize = useCallback(() => {
18
+ const handleWindowResize = useCallback(function () {
19
+ let {
20
+ scrollIntoArticle = false
21
+ } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
19
22
  const rect = scrollRef.current.getBoundingClientRect();
20
23
  const articleRect = articleRef.current.getBoundingClientRect();
21
24
  // get state from local storage
@@ -27,6 +30,12 @@ export default function ArticleContainer(_ref) {
27
30
  } else {
28
31
  setContainerStyle({});
29
32
  }
33
+ if (scrollIntoArticle) {
34
+ articleRef.current.scrollIntoView({
35
+ inline: 'start',
36
+ block: 'nearest'
37
+ });
38
+ }
30
39
  }, [scrollRef]);
31
40
  const handelArticleClick = useCallback(event => {
32
41
  if (!articleRef.current.contains(event.target)) return;
@@ -2,12 +2,16 @@ import React, { useRef, useState, useCallback } from 'react';
2
2
  import { ScrollContext } from '../hooks/use-scroll-context';
3
3
  import SDocOutline from '../outline';
4
4
  import classNames from 'classnames';
5
+ import CommentWrapper from '../comment';
6
+ import CommentProvider from '../comment/provider';
7
+ import { ParticipantsProvider } from '../comment/hooks/use-participants';
5
8
  const EditorContent = _ref => {
6
9
  let {
7
10
  readonly,
8
11
  showOutline,
9
12
  children,
10
- docValue
13
+ docValue,
14
+ editor
11
15
  } = _ref;
12
16
  const scrollRef = useRef(null);
13
17
  const [scrollLeft, setScrollLeft] = useState(0);
@@ -22,15 +26,10 @@ const EditorContent = _ref => {
22
26
  'no-outline': !showOutline
23
27
  });
24
28
  return /*#__PURE__*/React.createElement("div", {
25
- className: className
26
- }, showOutline && /*#__PURE__*/React.createElement("div", {
27
- className: "sdoc-absolute-wrapper"
28
- }, /*#__PURE__*/React.createElement(SDocOutline, {
29
- scrollLeft: scrollLeft,
30
- doc: docValue
31
- })), /*#__PURE__*/React.createElement("div", {
32
- className: "sdoc-absolute-wrapper"
33
- }, /*#__PURE__*/React.createElement("div", {
29
+ className: "sdoc-content-wrapper"
30
+ }, /*#__PURE__*/React.createElement(CommentProvider, {
31
+ editor: editor
32
+ }, /*#__PURE__*/React.createElement(ParticipantsProvider, null, /*#__PURE__*/React.createElement("div", {
34
33
  ref: scrollRef,
35
34
  className: "sdoc-scroll-container",
36
35
  onScroll: onWrapperScroll,
@@ -39,7 +38,15 @@ const EditorContent = _ref => {
39
38
  value: {
40
39
  scrollRef
41
40
  }
42
- }, children))));
41
+ }, /*#__PURE__*/React.createElement("div", {
42
+ className: className
43
+ }, showOutline && /*#__PURE__*/React.createElement(SDocOutline, {
44
+ scrollLeft: scrollLeft,
45
+ doc: docValue
46
+ }), children))), /*#__PURE__*/React.createElement(CommentWrapper, {
47
+ editor: editor,
48
+ type: "global"
49
+ }))));
43
50
  };
44
51
  EditorContent.defaultProps = {
45
52
  readonly: false,
@@ -1,4 +1,5 @@
1
1
  import React, { useCallback, useEffect, useMemo, useState } from 'react';
2
+ import classNames from 'classnames';
2
3
  import { withTranslation } from 'react-i18next';
3
4
  import { INTERNAL_EVENT } from '../constants';
4
5
  import EventBus from '../utils/event-bus';
@@ -43,7 +44,9 @@ const SDocOutline = _ref => {
43
44
  return doc.filter(item => ['header1', 'header2', 'header3'].includes(item.type));
44
45
  }, [doc]);
45
46
  return /*#__PURE__*/React.createElement("div", {
46
- className: "sdoc-outline-wrapper",
47
+ className: classNames('sdoc-outline-wrapper', {
48
+ active: isShown
49
+ }),
47
50
  style: {
48
51
  left: -scrollLeft
49
52
  }
@@ -1,16 +1,21 @@
1
1
  .sdoc-outline-wrapper {
2
- position: absolute;
3
- top: 0;
2
+ position: fixed;
3
+ top: 100px;
4
4
  bottom: 0;
5
5
  display: flex;
6
6
  margin: 20px 30px 20px 16px;
7
7
  min-height: 0;
8
8
  z-index: 101;
9
+ pointer-events: none;
10
+ }
11
+
12
+ .sdoc-outline-wrapper.active {
13
+ pointer-events: all;
9
14
  }
10
15
 
11
16
  .sdoc-outline {
12
17
  flex: 1;
13
- width: 220px;
18
+ width: 220px;
14
19
  display: flex;
15
20
  min-height: 0;
16
21
  flex-direction: column;
@@ -18,7 +23,7 @@
18
23
  position: relative;
19
24
  }
20
25
 
21
- .sdoc-outline-header {
26
+ .sdoc-outline-header {
22
27
  display: flex;
23
28
  justify-content: space-between;
24
29
  align-items: center;
@@ -74,13 +79,14 @@
74
79
  height: 28px;
75
80
  background: #fff;
76
81
  border-radius: 0 50% 50% 0;
77
- box-shadow: 0 0 6px rgba(0,0,0, 0.12);
82
+ box-shadow: 0 0 6px rgba(0, 0, 0, 0.12);
78
83
  display: flex;
79
84
  align-items: center;
80
85
  justify-content: center;
81
86
  position: absolute;
82
87
  top: 20px;
83
- left: -16px;
88
+ left: -15px;
89
+ pointer-events: all;
84
90
  }
85
91
 
86
92
  .sdoc-outline-menu.disabled {