@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.
- package/dist/basic-sdk/assets/css/layout.css +11 -15
- package/dist/basic-sdk/assets/css/simple-viewer.css +0 -10
- package/dist/basic-sdk/comment/components/comment-all-participants/index.css +8 -8
- package/dist/basic-sdk/comment/components/comment-editor.js +18 -18
- package/dist/basic-sdk/comment/components/comment-item-wrapper.js +4 -2
- package/dist/basic-sdk/comment/components/comment-list.css +22 -8
- package/dist/basic-sdk/comment/components/comment-list.js +7 -2
- package/dist/basic-sdk/comment/components/editor-comment.js +12 -10
- package/dist/basic-sdk/comment/components/elements-comment-count/element-comment-count.js +4 -8
- package/dist/basic-sdk/comment/components/elements-comment-count/index.js +4 -2
- package/dist/basic-sdk/comment/components/global-comment/global-comment-editor.js +2 -18
- package/dist/basic-sdk/comment/components/global-comment/index.css +56 -30
- package/dist/basic-sdk/comment/components/global-comment/index.js +95 -30
- package/dist/basic-sdk/comment/index.js +11 -10
- package/dist/basic-sdk/comment/provider/comment-context-provider.js +2 -3
- package/dist/basic-sdk/comment/provider/index.js +7 -2
- package/dist/basic-sdk/comment/provider/notification-context-provider.js +2 -3
- package/dist/basic-sdk/editor/comment-article.js +0 -101
- package/dist/basic-sdk/editor/editable-article.js +4 -1
- package/dist/basic-sdk/editor/sdoc-editor.js +6 -3
- package/dist/basic-sdk/extension/plugins/image/plugin.js +1 -1
- package/dist/basic-sdk/extension/plugins/list/plugin/index.js +17 -10
- package/dist/basic-sdk/hooks/use-selection-element.js +4 -3
- package/dist/basic-sdk/layout/article-container.js +10 -1
- package/dist/basic-sdk/layout/editor-content.js +18 -11
- package/dist/basic-sdk/outline/index.js +4 -1
- package/dist/basic-sdk/outline/style.css +12 -6
- package/dist/basic-sdk/views/readonly-article.js +4 -1
- package/dist/basic-sdk/views/sdoc-viewer.js +5 -3
- package/dist/layout/layout.css +0 -5
- 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
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
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
|
-
|
|
46
|
-
if (
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}, [
|
|
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
|
-
|
|
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(
|
|
132
|
-
className: "
|
|
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
|
|
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
|
-
|
|
51
|
-
|
|
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,
|
|
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,
|
|
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,
|
|
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 {
|
|
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
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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:
|
|
26
|
-
},
|
|
27
|
-
|
|
28
|
-
}, /*#__PURE__*/React.createElement(
|
|
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
|
-
},
|
|
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:
|
|
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:
|
|
3
|
-
top:
|
|
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: -
|
|
88
|
+
left: -15px;
|
|
89
|
+
pointer-events: all;
|
|
84
90
|
}
|
|
85
91
|
|
|
86
92
|
.sdoc-outline-menu.disabled {
|