@seafile/sdoc-editor 0.5.3 → 0.5.5

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 (45) hide show
  1. package/dist/assets/css/simple-editor.css +15 -0
  2. package/dist/basic-sdk/assets/css/layout.css +15 -0
  3. package/dist/basic-sdk/comment/components/comment-editor.js +49 -33
  4. package/dist/basic-sdk/comment/components/comment-item-content.js +11 -3
  5. package/dist/basic-sdk/comment/components/comment-item-reply.js +13 -5
  6. package/dist/basic-sdk/comment/components/comment-item-wrapper.js +1 -1
  7. package/dist/basic-sdk/comment/components/comment-list.css +27 -19
  8. package/dist/basic-sdk/comment/components/comment-list.js +0 -1
  9. package/dist/basic-sdk/comment/components/global-comment/index.css +2 -6
  10. package/dist/basic-sdk/comment/utils/index.js +5 -5
  11. package/dist/basic-sdk/constants/index.js +5 -2
  12. package/dist/basic-sdk/editor/comment-article.js +175 -0
  13. package/dist/basic-sdk/editor/editable-article.js +2 -1
  14. package/dist/basic-sdk/editor/sdoc-comment-editor.js +108 -0
  15. package/dist/basic-sdk/extension/commons/insert-element-dialog/index.js +12 -7
  16. package/dist/basic-sdk/extension/commons/menu/menu-item.js +1 -1
  17. package/dist/basic-sdk/extension/constants/element-type.js +3 -1
  18. package/dist/basic-sdk/extension/constants/index.js +2 -2
  19. package/dist/basic-sdk/extension/constants/menus-config.js +2 -2
  20. package/dist/basic-sdk/extension/index.js +11 -1
  21. package/dist/basic-sdk/extension/plugins/image/helpers.js +6 -3
  22. package/dist/basic-sdk/extension/plugins/image/menu/index.js +25 -4
  23. package/dist/basic-sdk/extension/plugins/image/render-elem.js +1 -0
  24. package/dist/basic-sdk/extension/plugins/index.js +3 -1
  25. package/dist/basic-sdk/extension/plugins/link/menu/index.js +22 -3
  26. package/dist/basic-sdk/extension/plugins/markdown/plugin.js +17 -6
  27. package/dist/basic-sdk/extension/plugins/mention/helper.js +142 -0
  28. package/dist/basic-sdk/extension/plugins/mention/index.js +10 -0
  29. package/dist/basic-sdk/extension/plugins/mention/plugin.js +258 -0
  30. package/dist/basic-sdk/{comment/components/comment-input → extension/plugins/mention/render-elem}/comment-participant-item.js +1 -1
  31. package/dist/basic-sdk/{comment/components/comment-input → extension/plugins/mention/render-elem}/index.css +22 -1
  32. package/dist/basic-sdk/extension/plugins/mention/render-elem/index.js +51 -0
  33. package/dist/basic-sdk/extension/plugins/mention/render-elem/participant-popover.js +219 -0
  34. package/dist/basic-sdk/extension/plugins/paragraph/helper.js +10 -0
  35. package/dist/basic-sdk/extension/plugins/paragraph/render-elem.js +9 -3
  36. package/dist/basic-sdk/extension/plugins/text-style/menu/comemnt-editor-menu.js +68 -0
  37. package/dist/basic-sdk/extension/plugins/text-style/menu/index.js +19 -8
  38. package/dist/basic-sdk/extension/render/custom-element.js +12 -2
  39. package/dist/basic-sdk/extension/toolbar/comment-editor-toolbar/index.js +45 -0
  40. package/dist/basic-sdk/utils/event-handler.js +21 -0
  41. package/dist/slate-convert/md-to-slate/transform.js +17 -0
  42. package/dist/slate-convert/slate-to-md/transform.js +28 -2
  43. package/package.json +1 -1
  44. package/dist/basic-sdk/comment/components/comment-input/helpers.js +0 -15
  45. package/dist/basic-sdk/comment/components/comment-input/index.js +0 -306
@@ -7,3 +7,18 @@
7
7
  .sdoc-context-menu .dropdown-item:hover {
8
8
  color: #fff;
9
9
  }
10
+
11
+ /* Used in mention editor, to modify `mention` node */
12
+ a[title^='__sdoc_mention__username'] {
13
+ display: inline-block;
14
+ padding: 0 2px;
15
+ border: none;
16
+ background-color: transparent;
17
+ color: #1677ff !important;
18
+ border-radius: 5px;
19
+ cursor: pointer;
20
+ }
21
+
22
+ a[title^='__sdoc_mention__username']:hover {
23
+ background-color: rgb(221, 236, 253);
24
+ }
@@ -114,3 +114,18 @@
114
114
  font-size: 12px;
115
115
  transform: scale(.75);
116
116
  }
117
+
118
+ .sdoc-comment-editor-toolbar {
119
+ display: flex;
120
+ flex: 1;
121
+ position: relative;
122
+ height: 44px;
123
+ align-items: center;
124
+ user-select: none;
125
+ position: relative;
126
+ z-index: 102;
127
+ }
128
+
129
+ .sdoc-comment-editor-menu-group {
130
+ border-right: none;
131
+ }
@@ -2,12 +2,18 @@ import React, { useCallback, useEffect, useMemo, useRef } from 'react';
2
2
  import { useTranslation } from 'react-i18next';
3
3
  import { Button } from 'reactstrap';
4
4
  import classNames from 'classnames';
5
+ import { Editor, Transforms } from '@seafile/slate';
5
6
  import { useScrollContext } from '../../hooks/use-scroll-context';
6
7
  import context from '../../../context';
7
- import EventBus from '../../utils/event-bus';
8
- import { INTERNAL_EVENT } from '../../constants';
9
8
  import { useParticipantsContext } from '../hooks/use-participants';
10
- import CommentInput from './comment-input';
9
+ import SdocCommentEditor from '../../editor/sdoc-comment-editor';
10
+ import { createCommentEditor } from '../../extension';
11
+ import withNodeId from '../../node-id';
12
+ import { generateEmptyElement } from '../../extension/core';
13
+ import { PARAGRAPH } from '../../extension/constants';
14
+ import slateToMdString from '../../../slate-convert/slate-to-md';
15
+ import mdStringToSlate from '../../../slate-convert/md-to-slate';
16
+ import { COMMENT_EDITOR, COMMENT_EDITOR_EDIT_AREA_WIDTH } from '../../constants';
11
17
  const getSubmitTip = (type, content) => {
12
18
  if (content) return 'Save';
13
19
  return type === 'comment' ? 'Comment' : 'Reply';
@@ -23,7 +29,6 @@ const CommentEditor = _ref => {
23
29
  setIsEditing,
24
30
  hiddenComment
25
31
  } = _ref;
26
- const commentInputRef = useRef();
27
32
  const commentWrapperRef = useRef();
28
33
  const {
29
34
  t
@@ -32,6 +37,30 @@ const CommentEditor = _ref => {
32
37
  const {
33
38
  addParticipants
34
39
  } = useParticipantsContext();
40
+ const submitTip = useMemo(() => getSubmitTip(type, content), [content, type]);
41
+ const userInfo = context.getUserInfo();
42
+ const document = useMemo(() => {
43
+ const cursor = {};
44
+ let children = null;
45
+ children = [generateEmptyElement(PARAGRAPH, {
46
+ placeholder
47
+ })];
48
+ return {
49
+ children,
50
+ cursor
51
+ };
52
+ }, [placeholder]);
53
+ const editor = useMemo(() => {
54
+ const defaultEditor = createCommentEditor();
55
+ const newEditor = withNodeId(defaultEditor);
56
+ const {
57
+ cursors
58
+ } = document;
59
+ newEditor.cursors = cursors || {};
60
+ newEditor.width = COMMENT_EDITOR_EDIT_AREA_WIDTH; // default width
61
+ newEditor.editorType = COMMENT_EDITOR;
62
+ return newEditor;
63
+ }, [document]);
35
64
 
36
65
  // onMount: set scrollLeft
37
66
  useEffect(() => {
@@ -45,42 +74,33 @@ const CommentEditor = _ref => {
45
74
  scrollRef.current.scrollLeft = scrollRef.current.scrollLeft + width;
46
75
  // eslint-disable-next-line react-hooks/exhaustive-deps
47
76
  }, []);
48
-
49
- // onMount: hidden comment
50
- useEffect(() => {
51
- const eventBus = EventBus.getInstance();
52
- const unsubscribe = eventBus.subscribe(INTERNAL_EVENT.ARTICLE_CLICK, hiddenComment);
53
- return () => {
54
- unsubscribe();
55
- };
56
- // eslint-disable-next-line react-hooks/exhaustive-deps
57
- }, []);
58
77
  const updateValue = useCallback(value => {
59
78
  if (!value || value.trim() === '') return;
60
- if (!content) {
61
- insertContent(value);
62
- return;
63
- }
79
+ if (!content) return insertContent(value);
64
80
  updateContent(value);
65
81
  }, [content, insertContent, updateContent]);
66
82
  const onSubmit = useCallback(event => {
67
83
  event && event.stopPropagation();
68
- const value = commentInputRef.current.getValue();
69
- updateValue(value);
70
- const userInfo = context.getUserInfo();
84
+ const mdString = slateToMdString(editor.children);
85
+ updateValue(mdString);
71
86
  addParticipants(userInfo.username);
72
- commentInputRef.current.setValue('');
73
- }, [updateValue, addParticipants, commentInputRef]);
87
+ editor.children = [generateEmptyElement(PARAGRAPH, {
88
+ placeholder
89
+ })];
90
+ Transforms.select(editor, Editor.start(editor, []));
91
+ }, [editor, updateValue, addParticipants, userInfo.username, placeholder]);
74
92
  const onCancel = useCallback(event => {
75
93
  event.stopPropagation();
76
- commentInputRef.current.setValue('');
77
94
  setIsEditing && setIsEditing(false);
78
95
  hiddenComment && hiddenComment(false);
79
96
 
80
97
  // eslint-disable-next-line react-hooks/exhaustive-deps
81
98
  }, [setIsEditing]);
82
- const submitTip = useMemo(() => getSubmitTip(type, content), [content, type]);
83
- const userInfo = context.getUserInfo();
99
+ useEffect(() => {
100
+ const children = mdStringToSlate(content);
101
+ editor.children = children;
102
+ Transforms.select(editor, Editor.end(editor, []));
103
+ }, [editor, content]);
84
104
  return /*#__PURE__*/React.createElement("div", {
85
105
  className: classNames('comment-editor-wrapper', className),
86
106
  ref: commentWrapperRef
@@ -95,13 +115,9 @@ const CommentEditor = _ref => {
95
115
  width: "100%"
96
116
  })), /*#__PURE__*/React.createElement("div", {
97
117
  className: "comment-editor-user-name"
98
- }, userInfo.name)), /*#__PURE__*/React.createElement(CommentInput, {
99
- ref: commentInputRef,
100
- type: type,
101
- placeholder: placeholder,
102
- content: content,
103
- onCancel: onCancel,
104
- onSubmit: onSubmit
118
+ }, userInfo.name)), /*#__PURE__*/React.createElement(SdocCommentEditor, {
119
+ editor: editor,
120
+ document: document
105
121
  }), /*#__PURE__*/React.createElement("div", {
106
122
  className: "comment-operations"
107
123
  }, /*#__PURE__*/React.createElement(Button, {
@@ -1,12 +1,12 @@
1
1
  import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
2
- import React, { useCallback, useMemo, useState } from 'react';
2
+ import React, { useCallback, useEffect, useMemo, useState } from 'react';
3
3
  import { withTranslation } from 'react-i18next';
4
4
  import { Dropdown, DropdownItem, DropdownMenu, DropdownToggle } from 'reactstrap';
5
5
  import dayjs from 'dayjs';
6
6
  import CommentEditor from './comment-editor';
7
7
  import Tooltip from '../../../components/tooltip';
8
- import { textToHtml } from '../utils';
9
8
  import { useNotificationContext } from '../hooks/notification-hooks';
9
+ import processor from '../../../slate-convert/md-to-html';
10
10
  const CommentItem = _ref => {
11
11
  let {
12
12
  isActive,
@@ -23,11 +23,19 @@ const CommentItem = _ref => {
23
23
  const {
24
24
  notificationsInfo
25
25
  } = useNotificationContext();
26
+ const [editorContent, setEditorContent] = useState('');
26
27
  const onEditToggle = useCallback(event => {
27
28
  event.stopPropagation();
28
29
  setIsEditing(true);
29
30
  }, []);
30
31
  const isUnseen = notificationsInfo.notifications_map["sdoc_notification_".concat(comment.id)] ? true : false;
32
+ useEffect(() => {
33
+ transferHtml(comment.comment);
34
+ }, [comment.comment]);
35
+ const transferHtml = async mdString => {
36
+ const htmlString = await processor.process(mdString);
37
+ setEditorContent(String(htmlString));
38
+ };
31
39
  const onDeleteToggle = useCallback(event => {
32
40
  event.stopPropagation();
33
41
  onDeleteComment(true);
@@ -126,7 +134,7 @@ const CommentItem = _ref => {
126
134
  className: "comment-content"
127
135
  }, !isEditing && /*#__PURE__*/React.createElement("div", {
128
136
  dangerouslySetInnerHTML: {
129
- __html: textToHtml(comment.comment)
137
+ __html: editorContent
130
138
  }
131
139
  })), isEditing && /*#__PURE__*/React.createElement(CommentEditor, {
132
140
  className: "pb-3",
@@ -1,12 +1,12 @@
1
- import React, { useCallback, useState, useRef } from 'react';
1
+ import React, { useCallback, useState, useRef, useEffect } from 'react';
2
2
  import { withTranslation } from 'react-i18next';
3
3
  import { Dropdown, DropdownItem, DropdownMenu, DropdownToggle } from 'reactstrap';
4
4
  import dayjs from 'dayjs';
5
5
  import context from '../../../context';
6
6
  import CommentEditor from './comment-editor';
7
- import { textToHtml } from '../utils';
8
7
  import { useNotificationContext } from '../hooks/notification-hooks';
9
8
  import CommentDeletePopover from './comment-delete-popover';
9
+ import processor from '../../../slate-convert/md-to-html';
10
10
  const CommentItemReply = _ref => {
11
11
  let {
12
12
  isActive,
@@ -23,6 +23,7 @@ const CommentItemReply = _ref => {
23
23
  const liRef = useRef(null);
24
24
  const isUnseen = notificationsInfo.notifications_map["sdoc_notification_".concat(reply.comment_id, "_").concat(reply.id)] ? true : false;
25
25
  const [isEditing, setIsEditing] = useState(false);
26
+ const [editorContent, setEditorContent] = useState('');
26
27
  const replyOpToolsId = "replyOpTools_".concat(reply.id);
27
28
  const onEditToggle = useCallback(event => {
28
29
  event.stopPropagation();
@@ -33,6 +34,13 @@ const CommentItemReply = _ref => {
33
34
  event.stopPropagation();
34
35
  setIsShowDeleteDialog(true);
35
36
  }, []);
37
+ const transferHtml = async mdString => {
38
+ const htmlString = await processor.process(mdString);
39
+ setEditorContent(String(htmlString));
40
+ };
41
+ useEffect(() => {
42
+ transferHtml(reply.reply);
43
+ }, [reply.reply]);
36
44
  const _deleteReply = useCallback(() => {
37
45
  deleteReply(reply.id);
38
46
  setIsShowDeleteDialog(false);
@@ -95,12 +103,12 @@ const CommentItemReply = _ref => {
95
103
  className: "comment-content"
96
104
  }, !isEditing && /*#__PURE__*/React.createElement("div", {
97
105
  dangerouslySetInnerHTML: {
98
- __html: textToHtml(reply.reply)
106
+ __html: editorContent
99
107
  }
100
108
  })), isEditing && /*#__PURE__*/React.createElement(CommentEditor, {
101
- className: 'pb-3',
109
+ className: "pb-3",
102
110
  type: "reply",
103
- content: reply.reply,
111
+ content: editorContent,
104
112
  updateContent: updateContent,
105
113
  setIsEditing: setIsEditing
106
114
  }), isShowDeleteDialog && isActive && /*#__PURE__*/React.createElement(CommentDeletePopover, {
@@ -278,7 +278,7 @@ const CommentItemWrapper = _ref => {
278
278
  reply: reply
279
279
  });
280
280
  })), isActive && /*#__PURE__*/React.createElement(CommentEditor, {
281
- className: "mt-4",
281
+ className: "p-3",
282
282
  type: "reply",
283
283
  placeholder: tip,
284
284
  insertContent: insertContent,
@@ -3,6 +3,8 @@
3
3
  }
4
4
 
5
5
  .sdoc-comment-list-container .comment-ui-container {
6
+ min-width: 330px;
7
+ max-width: 400px;
6
8
  background-color: #edf2fa;
7
9
  border-radius: 8px;
8
10
  box-shadow: 0 0 2px rgba(0, 0, 0, .04);
@@ -42,7 +44,6 @@
42
44
  }
43
45
 
44
46
  .sdoc-comment-list-container .comment-item-list {
45
- max-height: 350px;
46
47
  min-width: 280px;
47
48
  overflow-x: hidden;
48
49
  overflow-y: auto;
@@ -51,7 +52,7 @@
51
52
 
52
53
  .sdoc-comment-list-container .comment-item {
53
54
  position: relative;
54
- padding: 16px 16px 0;
55
+ padding: 16px 10px 0;
55
56
  cursor: pointer;
56
57
  }
57
58
 
@@ -79,9 +80,9 @@
79
80
  .sdoc-comment-list-container .comment-item .comment-content {
80
81
  padding-bottom: 10px;
81
82
  margin-top: 10px;
82
- margin-left: 30px;
83
- width: 222px;
84
- word-break: break-all;
83
+ margin-left: 41px;
84
+ word-break: keep-all;
85
+ word-wrap: break-word;
85
86
  }
86
87
 
87
88
  .sdoc-comment-list-container .comment-header .comment-author__avatar {
@@ -200,27 +201,34 @@
200
201
  color: #fff;
201
202
  }
202
203
 
204
+ .sdoc-comment-editor-wrapper {
205
+ border: 1px solid #ececec;
206
+ border-top-left-radius: 3px;
207
+ border-top-right-radius: 3px;
208
+ margin-bottom: 15px;
209
+ border-radius: 3px;
210
+ }
211
+
212
+ .comment-editor-wrapper .sdoc-comment-editor-wrapper .article.sdoc-comment-editor {
213
+ width: 365px;
214
+ padding: 0 5px;
215
+ min-height: 75px;
216
+ max-height: 80px;
217
+ box-shadow: none;
218
+ overflow-y: auto;
219
+ overflow-x: hidden;
220
+ border: none;
221
+ background-color: transparent;
222
+ }
223
+
203
224
  .sdoc-comment-list-container .comment-editor-wrapper {
204
225
  display: flex;
205
226
  flex-direction: column;
206
227
  justify-content: center;
207
- padding: 0 16px;
228
+ padding: 0 10px;
208
229
  cursor: text;
209
230
  }
210
231
 
211
- .sdoc-comment-list-container .comment-editor-wrapper .comment-editor {
212
- margin-bottom: 10px;
213
- min-height: 40px;
214
- max-height: 120px;
215
- min-width: 240px;
216
- overflow: auto;
217
- background: #fff;
218
- border: 1px solid rgba(0, 0, 0, .12);
219
- border-radius: 4px;
220
- padding: 8px;
221
- word-break: break-all;
222
- }
223
-
224
232
  .sdoc-comment-list-container .comment-editor-wrapper .comment-editor:empty:before {
225
233
  content: attr(placeholder);
226
234
  opacity: .6;
@@ -112,7 +112,6 @@ const CommentList = _ref => {
112
112
  }, /*#__PURE__*/React.createElement(CommentEditor, {
113
113
  type: "comment",
114
114
  insertContent: insertContent,
115
- selectionElement: selectionElement,
116
115
  hiddenComment: hiddenComment
117
116
  })));
118
117
  };
@@ -3,7 +3,7 @@
3
3
  right: 10px;
4
4
  top: 50px;
5
5
  z-index: 103;
6
- width: 340px;
6
+ width: 432px;
7
7
  height: 540px;
8
8
  }
9
9
 
@@ -87,7 +87,7 @@
87
87
  flex: 1;
88
88
  display: flex;
89
89
  flex-direction: column;
90
- padding: 16px;
90
+ padding: 10px;
91
91
  overflow: auto;
92
92
  }
93
93
 
@@ -95,10 +95,6 @@
95
95
  position: relative;
96
96
  }
97
97
 
98
- .global-comments-popover .comments-panel-body__content .comment-item-list {
99
- max-width: 308px;
100
- }
101
-
102
98
  .global-comments-popover .comments-panel-body__content .comment-ui-container.active {
103
99
  left: 0;
104
100
  }
@@ -1,7 +1,6 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
2
2
  import { Editor } from '@seafile/slate';
3
3
  import { getEventTransfer } from '../../../utils';
4
- import { COMMENT_URL_CLASSNAME } from '../constants';
5
4
  import { KeyCodes } from '../../../constants';
6
5
  import { createNotify, generatorNotificationKey } from './notification-utils';
7
6
  import { focusEditor, findPath } from '../../extension/core';
@@ -33,10 +32,11 @@ export const searchCollaborators = (collaborators, searchValue) => {
33
32
 
34
33
  // Mailto, file, tel, callto, sms, cid, xmpp, etc. are not support
35
34
  const ALLOWED_URL_REG = /((http|https):\/\/[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|])/g;
36
- export const textToHtml = text => {
37
- if (!text) return '';
38
- return text.replace(ALLOWED_URL_REG, '<a href="$1" target="_blank" class=' + COMMENT_URL_CLASSNAME + '>$1</a>');
39
- };
35
+ // export const textToHtml = (text) => {
36
+ // if (!text) return '';
37
+ // return text.replace(ALLOWED_URL_REG, '<a href="$1" target="_blank" class=' + COMMENT_URL_CLASSNAME + '>$1</a>');
38
+ // };
39
+
40
40
  export const convertComment = value => {
41
41
  return value.replaceAll('<', '&lt;').replaceAll('>', '&gt;');
42
42
  };
@@ -17,12 +17,15 @@ export const INTERNAL_EVENT = {
17
17
  CLOSE_CALLOUT_COLOR_PICKER: 'close_callout_color_picker',
18
18
  OPEN_SEARCH_REPLACE_MODAL: 'open_search_replace_modal',
19
19
  UPDATE_SEARCH_REPLACE_HIGHLIGHT: 'update_search_replace_highlight',
20
- TABLE_CELL_MOUSE_ENTER: 'table_cell_mouse_enter'
20
+ TABLE_CELL_MOUSE_ENTER: 'table_cell_mouse_enter',
21
+ HANDLE_MENTION_TEMP_CHOSEN: 'handle_mention_temp_chosen',
22
+ UPDATE_MENTION_TEMP_CONTENT: 'update_mention_temp_content'
21
23
  };
22
24
  export const REVISION_DIFF_KEY = 'diff';
23
25
  export const REVISION_DIFF_VALUE = '1';
24
26
  export const PAGE_EDIT_AREA_WIDTH = 672; // 672 = 794 - 2[borderLeft + borderRight] - 120[paddingLeft + paddingRight]
25
-
27
+ export const COMMENT_EDITOR_EDIT_AREA_WIDTH = 364;
28
+ export const COMMENT_EDITOR = 'comment_editor';
26
29
  export const MODIFY_TYPE = {
27
30
  ADD: 'add',
28
31
  DELETE: 'delete',
@@ -0,0 +1,175 @@
1
+ import React, { useCallback, useMemo } from 'react';
2
+ import { Editable, ReactEditor, Slate } from '@seafile/slate-react';
3
+ import { Editor, Node, Range } from '@seafile/slate';
4
+ import { renderLeaf, renderElement } from '../extension';
5
+ import { getAboveBlockNode, getNextNode, getPrevNode, isSelectionAtBlockEnd, isSelectionAtBlockStart } from '../extension/core';
6
+ import EventProxy from '../utils/event-handler';
7
+ import { useCursors } from '../cursor/use-cursors';
8
+ import { INTERNAL_EVENT } from '../constants';
9
+ import { usePipDecorate } from '../decorates';
10
+ import { getCursorPosition, getDomHeight, getDomMarginTop } from '../utils/dom-utils';
11
+ import EventBus from '../utils/event-bus';
12
+ import { useScrollContext } from '../hooks/use-scroll-context';
13
+ import { IMAGE } from '../extension/constants';
14
+ const CommentArticle = _ref => {
15
+ let {
16
+ editor,
17
+ slateValue,
18
+ updateSlateValue
19
+ } = _ref;
20
+ const {
21
+ cursors
22
+ } = useCursors(editor);
23
+ const decorate = usePipDecorate(editor);
24
+ // init eventHandler
25
+ // eslint-disable-next-line react-hooks/exhaustive-deps
26
+ const eventProxy = useMemo(() => new EventProxy(editor), []);
27
+ const onMouseDown = useCallback(event => {
28
+ if (event.button === 0) {
29
+ // Compatible with the editor which unload table plugin
30
+ editor.reSetTableSelectedRange && editor.reSetTableSelectedRange();
31
+ const eventBus = EventBus.getInstance();
32
+ eventBus.dispatch(INTERNAL_EVENT.CANCEL_TABLE_SELECT_RANGE);
33
+ }
34
+ // eslint-disable-next-line react-hooks/exhaustive-deps
35
+ }, []);
36
+ const scrollRef = useScrollContext();
37
+ const onKeyDown = useCallback(event => {
38
+ const {
39
+ scrollTop,
40
+ clientHeight
41
+ } = scrollRef.current;
42
+ eventProxy.onKeyDown(event);
43
+ if (event.key === 'ArrowLeft') {
44
+ if (!isSelectionAtBlockStart(editor)) return;
45
+ }
46
+ if (event.key === 'ArrowUp' || event.key === 'ArrowLeft') {
47
+ if (scrollTop === 0) return;
48
+ let prevNode = getPrevNode(editor);
49
+ if (!prevNode) return;
50
+ const domNode = ReactEditor.toDOMNode(editor, prevNode[0]);
51
+ const domHeight = getDomHeight(domNode);
52
+ const isScrollUp = true;
53
+ const {
54
+ y
55
+ } = getCursorPosition(isScrollUp);
56
+ if (y >= domHeight) return;
57
+ scrollRef.current.scroll(0, Math.max(0, scrollTop - domHeight));
58
+ return;
59
+ }
60
+ if (event.key === 'ArrowRight') {
61
+ if (!isSelectionAtBlockEnd(editor)) return;
62
+ }
63
+ if (event.key === 'ArrowDown' || event.key === 'ArrowRight') {
64
+ let nextNode = getNextNode(editor);
65
+ if (!nextNode) return;
66
+ const domNode = ReactEditor.toDOMNode(editor, nextNode[0]);
67
+ const domHeight = getDomHeight(domNode);
68
+ const isScrollUp = false;
69
+ const {
70
+ y
71
+ } = getCursorPosition(isScrollUp);
72
+ if (clientHeight - y >= domHeight) return;
73
+ scrollRef.current.scroll(0, Math.max(0, scrollTop + domHeight));
74
+ return;
75
+ }
76
+ if (event.key === 'Backspace') {
77
+ const {
78
+ y
79
+ } = getCursorPosition();
80
+
81
+ // above viewport
82
+ if (y < 0) {
83
+ const newY = Math.abs(y);
84
+ if (isSelectionAtBlockStart(editor)) {
85
+ const prevNode = getPrevNode(editor);
86
+ if (!prevNode) return;
87
+ const domNode = ReactEditor.toDOMNode(editor, prevNode[0]);
88
+ const domHeight = getDomHeight(domNode);
89
+ const node = getAboveBlockNode(editor);
90
+ if (!node) return;
91
+ const currentDomNode = ReactEditor.toDOMNode(editor, node[0]);
92
+ const marginTop = getDomMarginTop(currentDomNode);
93
+ scrollRef.current.scroll(0, Math.max(0, scrollTop - (newY + domHeight + marginTop)));
94
+ } else {
95
+ scrollRef.current.scroll(0, Math.max(0, scrollTop - newY));
96
+ }
97
+ return;
98
+ }
99
+
100
+ // insider viewport
101
+ if (y >= 0 && y <= clientHeight) {
102
+ if (isSelectionAtBlockStart(editor)) {
103
+ const prevNode = getPrevNode(editor);
104
+ if (!prevNode) return;
105
+ const domNode = ReactEditor.toDOMNode(editor, prevNode[0]);
106
+ const domHeight = getDomHeight(domNode);
107
+ if (y >= domHeight) return;
108
+ // Scroll up the height of the previous block
109
+ scrollRef.current.scroll(0, Math.max(0, scrollTop - domHeight));
110
+ return;
111
+ }
112
+ }
113
+
114
+ // below viewport
115
+ if (y > clientHeight) {
116
+ if (isSelectionAtBlockStart(editor)) {
117
+ // y: text top border
118
+ scrollRef.current.scroll(0, Math.max(0, scrollTop + (y - clientHeight)));
119
+ } else {
120
+ const marginBottom = 11.2;
121
+ const {
122
+ y: newY
123
+ } = getCursorPosition(false);
124
+ const rectBottom = newY + marginBottom; // text bottom border
125
+ scrollRef.current.scroll(0, Math.max(0, scrollTop + (rectBottom - clientHeight)));
126
+ }
127
+ return;
128
+ }
129
+ }
130
+
131
+ // eslint-disable-next-line react-hooks/exhaustive-deps
132
+ }, [scrollRef]);
133
+ const handleScrollIntoView = useCallback((editor, domRange) => {
134
+ try {
135
+ const {
136
+ selection
137
+ } = editor;
138
+ if (Range.isCollapsed(selection)) {
139
+ // Do not scroll into view, when focus on image
140
+ const [imageNodeEntry] = Editor.nodes(editor, {
141
+ match: n => n.type === IMAGE,
142
+ at: selection
143
+ });
144
+ if (imageNodeEntry) return;
145
+ }
146
+ const focusedNode = Node.get(editor, selection.focus.path);
147
+ const domNode = ReactEditor.toDOMNode(editor, focusedNode);
148
+ if (!domNode) return;
149
+ domNode.scrollIntoView({
150
+ block: 'nearest'
151
+ });
152
+ } catch (error) {
153
+ //
154
+ }
155
+ }, []);
156
+ return /*#__PURE__*/React.createElement(Slate, {
157
+ editor: editor,
158
+ value: slateValue,
159
+ onChange: updateSlateValue
160
+ }, /*#__PURE__*/React.createElement(Editable, {
161
+ scrollSelectionIntoView: handleScrollIntoView,
162
+ cursors: cursors,
163
+ renderElement: renderElement,
164
+ renderLeaf: renderLeaf,
165
+ onKeyDown: onKeyDown,
166
+ onMouseDown: onMouseDown,
167
+ decorate: decorate,
168
+ onCut: eventProxy.onCut,
169
+ onCopy: eventProxy.onCopy,
170
+ onCompositionStart: eventProxy.onCompositionStart,
171
+ onCompositionUpdate: eventProxy.onCompositionUpdate,
172
+ onCompositionEnd: eventProxy.onCompositionEnd
173
+ }));
174
+ };
175
+ export default CommentArticle;
@@ -31,7 +31,8 @@ const EditableArticle = _ref => {
31
31
  const eventProxy = useMemo(() => new EventProxy(editor), []);
32
32
  const onMouseDown = useCallback(event => {
33
33
  if (event.button === 0) {
34
- editor.reSetTableSelectedRange();
34
+ // Compatible with the editor which unload table plugin
35
+ editor.reSetTableSelectedRange && editor.reSetTableSelectedRange();
35
36
  const eventBus = EventBus.getInstance();
36
37
  eventBus.dispatch(INTERNAL_EVENT.CANCEL_TABLE_SELECT_RANGE);
37
38
  }