@seafile/sdoc-editor 0.5.41 → 0.5.43

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 (32) hide show
  1. package/dist/basic-sdk/constants/index.js +2 -1
  2. package/dist/basic-sdk/editor/comment-article.js +9 -10
  3. package/dist/basic-sdk/editor/editable-article.js +8 -9
  4. package/dist/basic-sdk/extension/commons/{history-files → file-insert-dialog}/index.js +115 -95
  5. package/dist/basic-sdk/extension/commons/file-insert-dialog/style.css +76 -0
  6. package/dist/basic-sdk/extension/commons/insert-element-dialog/index.js +9 -8
  7. package/dist/basic-sdk/extension/commons/menu-shortcut-indicator/style.css +5 -7
  8. package/dist/basic-sdk/extension/constants/element-type.js +1 -0
  9. package/dist/basic-sdk/extension/constants/index.js +2 -2
  10. package/dist/basic-sdk/extension/plugins/code-block/hover-menu/index.css +9 -0
  11. package/dist/basic-sdk/extension/plugins/code-block/hover-menu/index.js +41 -24
  12. package/dist/basic-sdk/extension/plugins/image/helpers.js +26 -2
  13. package/dist/basic-sdk/extension/plugins/image/render-elem.js +10 -4
  14. package/dist/basic-sdk/extension/plugins/sdoc-link/helpers.js +62 -13
  15. package/dist/basic-sdk/extension/plugins/sdoc-link/index.js +3 -2
  16. package/dist/basic-sdk/extension/plugins/sdoc-link/plugin.js +33 -23
  17. package/dist/basic-sdk/extension/plugins/sdoc-link/{render-elem.css → render/render-elem.css} +5 -1
  18. package/dist/basic-sdk/extension/plugins/sdoc-link/{render-elem.js → render/render-elem.js} +6 -6
  19. package/dist/basic-sdk/extension/plugins/sdoc-link/render/render-file-link-temp-input.js +26 -0
  20. package/dist/basic-sdk/extension/render/custom-element.js +6 -1
  21. package/dist/basic-sdk/extension/toolbar/context-toolbar/index.js +9 -1
  22. package/dist/basic-sdk/utils/diff.js +24 -0
  23. package/dist/components/doc-operations/more-operations.js +13 -10
  24. package/dist/components/doc-operations/revision-operations/changes-count/index.js +16 -15
  25. package/dist/components/doc-operations/revision-operations/index.js +1 -1
  26. package/dist/components/doc-operations/style.css +15 -0
  27. package/dist/pages/published-revision-viewer.js +1 -1
  28. package/dist/pages/simple-editor.js +1 -1
  29. package/package.json +1 -1
  30. package/public/locales/en/sdoc-editor.json +3 -1
  31. package/public/locales/zh_CN/sdoc-editor.json +3 -1
  32. package/dist/basic-sdk/extension/commons/history-files/index.css +0 -70
@@ -1,12 +1,43 @@
1
- import React, { useCallback, useEffect, useState } from 'react';
1
+ import React, { useCallback, useEffect, useMemo, useState } from 'react';
2
2
  import { Input } from 'reactstrap';
3
- import { withTranslation } from 'react-i18next';
3
+ import { useTranslation, withTranslation } from 'react-i18next';
4
4
  import Tooltip from '../../../../../components/tooltip';
5
5
  import { ElementPopover } from '../../../commons/';
6
6
  import { genCodeLangs } from '../prismjs';
7
7
  import { getSelectedLangOption } from '../helpers';
8
8
  import './index.css';
9
- const CodeBlockHoverMenu = _ref => {
9
+ const LangList = _ref => {
10
+ let {
11
+ langsData,
12
+ onSelectLang,
13
+ selectedLanguageText
14
+ } = _ref;
15
+ const {
16
+ t
17
+ } = useTranslation();
18
+ if (!langsData.length) {
19
+ return /*#__PURE__*/React.createElement("div", {
20
+ className: "langs-list-empty"
21
+ }, /*#__PURE__*/React.createElement("span", null, t('Search_not_found')));
22
+ }
23
+ return /*#__PURE__*/React.createElement("ul", {
24
+ className: "langs-list-ul"
25
+ }, langsData.map(item => {
26
+ return /*#__PURE__*/React.createElement("li", {
27
+ className: "langs-list-li ".concat(selectedLanguageText === item.text ? 'active' : ''),
28
+ id: item.value,
29
+ key: item.value,
30
+ onClick: () => {
31
+ onSelectLang(item);
32
+ }
33
+ }, item.text, /*#__PURE__*/React.createElement("span", {
34
+ className: "li-check-mark ".concat(selectedLanguageText === item.text ? 'li-checked' : '')
35
+ }, /*#__PURE__*/React.createElement("i", {
36
+ className: "sdocfont sdoc-check-mark icon-font"
37
+ })));
38
+ }));
39
+ };
40
+ const CodeBlockHoverMenu = _ref2 => {
10
41
  let {
11
42
  style,
12
43
  language,
@@ -16,7 +47,7 @@ const CodeBlockHoverMenu = _ref => {
16
47
  onCopyCodeBlock,
17
48
  onDeleteCodeBlock,
18
49
  t
19
- } = _ref;
50
+ } = _ref2;
20
51
  const {
21
52
  white_space = 'nowrap'
22
53
  } = style;
@@ -74,15 +105,12 @@ const CodeBlockHoverMenu = _ref => {
74
105
  }, [language]);
75
106
  const onChange = useCallback(e => {
76
107
  const filterData = [];
77
- const restData = [];
78
108
  genCodeLangs().forEach(item => {
79
109
  if (item.value.startsWith(e.currentTarget.value.toLowerCase())) {
80
110
  filterData.push(item);
81
- } else {
82
- restData.push(item);
83
111
  }
84
112
  });
85
- setLangsData([...filterData, ...restData]);
113
+ setLangsData(filterData);
86
114
  // eslint-disable-next-line react-hooks/exhaustive-deps
87
115
  }, []);
88
116
  return /*#__PURE__*/React.createElement(ElementPopover, null, /*#__PURE__*/React.createElement("div", {
@@ -150,21 +178,10 @@ const CodeBlockHoverMenu = _ref => {
150
178
  }, /*#__PURE__*/React.createElement(Input, {
151
179
  placeholder: t('Search_language'),
152
180
  onChange: onChange
153
- })), /*#__PURE__*/React.createElement("ul", {
154
- className: "langs-list-ul"
155
- }, langsData.map(item => {
156
- return /*#__PURE__*/React.createElement("li", {
157
- className: "langs-list-li ".concat(selectedLanguageText === item.text ? 'active' : ''),
158
- id: item.value,
159
- key: item.value,
160
- onClick: () => {
161
- onSelectLang(item);
162
- }
163
- }, item.text, /*#__PURE__*/React.createElement("span", {
164
- className: "li-check-mark ".concat(selectedLanguageText === item.text ? 'li-checked' : '')
165
- }, /*#__PURE__*/React.createElement("i", {
166
- className: "sdocfont sdoc-check-mark icon-font"
167
- })));
168
- }))))));
181
+ })), /*#__PURE__*/React.createElement(LangList, {
182
+ langsData: langsData,
183
+ onSelectLang: onSelectLang,
184
+ selectedLanguageText: selectedLanguageText
185
+ })))));
169
186
  };
170
187
  export default withTranslation('sdoc-editor')(CodeBlockHoverMenu);
@@ -1,12 +1,13 @@
1
1
  import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
2
2
  import urlJoin from 'url-join';
3
3
  import { Editor, Range, Transforms, Path, Node } from '@seafile/slate';
4
+ import { ReactEditor } from '@seafile/slate-react';
4
5
  import context from '../../../../context';
5
6
  import EventBus from '../../../utils/event-bus';
6
- import { generateEmptyElement, getNodeType, isTextNode, getParentNode, focusEditor } from '../../core';
7
+ import { generateEmptyElement, getNodeType, isTextNode, getParentNode, focusEditor, getSelectedElems } from '../../core';
7
8
  import { isList } from '../../toolbar/side-toolbar/helpers';
8
9
  import { COMMENT_EDITOR, INTERNAL_EVENT } from '../../../constants';
9
- import { CODE_BLOCK, ELEMENT_TYPE, IMAGE, INSERT_POSITION } from '../../constants';
10
+ import { CODE_BLOCK, ELEMENT_TYPE, IMAGE, IMAGE_BLOCK, INSERT_POSITION } from '../../constants';
10
11
  export const isInsertImageMenuDisabled = (editor, readonly) => {
11
12
  if (readonly) return true;
12
13
  const {
@@ -154,4 +155,27 @@ export const insertImageFiles = (files, editor, targetPath) => {
154
155
  context.uploadLocalImage(files).then(fileUrl => {
155
156
  insertImage(editor, fileUrl, targetPath, INSERT_POSITION.AFTER);
156
157
  });
158
+ };
159
+ export const selectImageWhenSelectPartial = (event, editor, imageNode, isImageSelected) => {
160
+ if (isImageSelected) return;
161
+ const isMouseLeftDown = event.buttons === 1;
162
+ if (!isMouseLeftDown) return;
163
+ const {
164
+ selection
165
+ } = editor;
166
+ if (Range.isCollapsed(selection)) return;
167
+ let imagePath = ReactEditor.findPath(editor, imageNode);
168
+ if (imageNode.type === IMAGE_BLOCK) {
169
+ const imageIndex = imageNode.children.findIndex(item => item.type === IMAGE);
170
+ imagePath = imagePath.concat([imageIndex]);
171
+ }
172
+ const isIncludedSelection = Range.includes(selection, imagePath);
173
+ if (isIncludedSelection) return;
174
+ const focusRange = _objectSpread(_objectSpread({}, selection), {}, {
175
+ focus: {
176
+ offset: 0,
177
+ path: imagePath
178
+ }
179
+ });
180
+ focusEditor(editor, focusRange);
157
181
  };
@@ -4,7 +4,7 @@ import { ReactEditor, useSelected, useReadOnly } from '@seafile/slate-react';
4
4
  import { Transforms, Editor } from '@seafile/slate';
5
5
  import classNames from 'classnames';
6
6
  import { withTranslation } from 'react-i18next';
7
- import { getImageURL, updateImage } from './helpers';
7
+ import { getImageURL, selectImageWhenSelectPartial, updateImage } from './helpers';
8
8
  import EventBus from '../../../utils/event-bus';
9
9
  import { INTERNAL_EVENT } from '../../../constants';
10
10
  import ImageHoverMenu from './hover-menu';
@@ -195,7 +195,8 @@ const Image = _ref => {
195
195
  return /*#__PURE__*/React.createElement(React.Fragment, null, isShowImagePlaceholder && /*#__PURE__*/React.createElement("span", Object.assign({
196
196
  className: classNames('sdoc-image-wrapper', className)
197
197
  }, attributes, {
198
- style: _objectSpread({}, style)
198
+ style: _objectSpread({}, style),
199
+ onMouseOver: e => selectImageWhenSelectPartial(e, editor, element, isSelected)
199
200
  }), /*#__PURE__*/React.createElement("img", {
200
201
  ref: imageRef,
201
202
  src: imagePlaceholder,
@@ -206,7 +207,8 @@ const Image = _ref => {
206
207
  "data-id": element.id,
207
208
  className: classNames('sdoc-image-wrapper', className)
208
209
  }, attributes, {
209
- style: _objectSpread({}, style)
210
+ style: _objectSpread({}, style),
211
+ onMouseOver: e => selectImageWhenSelectPartial(e, editor, element, isSelected)
210
212
  }), /*#__PURE__*/React.createElement("span", {
211
213
  className: "sdoc-image-inner"
212
214
  }, /*#__PURE__*/React.createElement("span", {
@@ -294,6 +296,8 @@ export function renderImageBlock(props, editor) {
294
296
  const {
295
297
  align
296
298
  } = element;
299
+ // eslint-disable-next-line react-hooks/rules-of-hooks
300
+ const isSelected = useSelected();
297
301
  let justifyContent = '';
298
302
  if (align) {
299
303
  justifyContent = align === 'left' ? 'start' : align === 'right' ? 'end' : align;
@@ -305,5 +309,7 @@ export function renderImageBlock(props, editor) {
305
309
  padding: '5px 0px',
306
310
  justifyContent: "".concat(justifyContent)
307
311
  }
308
- }, attributes), children);
312
+ }, attributes, {
313
+ onMouseOver: e => selectImageWhenSelectPartial(e, editor, element, isSelected)
314
+ }), children);
309
315
  }
@@ -1,11 +1,11 @@
1
1
  import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
2
2
  import { ReactEditor } from '@seafile/slate-react';
3
- import { Editor, Transforms, Range, Text } from '@seafile/slate';
3
+ import { Editor, Transforms, Range, Text, Path, Node } from '@seafile/slate';
4
4
  import slugid from 'slugid';
5
5
  import copy from 'copy-to-clipboard';
6
6
  import context from '../../../../context';
7
- import { focusEditor, getNodeType, getSelectedElems } from '../../core';
8
- import { SDOC_LINK, LINK, INSERT_FILE_DISPLAY_TYPE, CODE_BLOCK, CODE_LINE, PARAGRAPH } from '../../constants';
7
+ import { focusEditor, generateEmptyElement, getNodeType, getSelectedElems } from '../../core';
8
+ import { SDOC_LINK, LINK, INSERT_FILE_DISPLAY_TYPE, CODE_BLOCK, CODE_LINE, PARAGRAPH, FILE_LINK_INSET_INPUT_TEMP } from '../../constants';
9
9
  export const isMenuDisabled = (editor, readonly) => {
10
10
  if (readonly) return true;
11
11
  if (editor.selection == null) return true;
@@ -149,17 +149,13 @@ export const getBeforeText = editor => {
149
149
  range
150
150
  };
151
151
  };
152
- export const isTriggeredByShortCut = editor => {
153
- const {
154
- selection
155
- } = editor;
156
- const {
157
- anchor
158
- } = selection;
152
+ export const isTriggeredByShortcut = editor => {
159
153
  const {
160
154
  beforeText
161
155
  } = getBeforeText(editor);
162
- return beforeText.slice(-1) === '[' && Editor.isEnd(editor, anchor, anchor.path);
156
+ const fileSearchInput = getFileSearchInputEntry(editor);
157
+ if (fileSearchInput) return false;
158
+ return beforeText.endsWith('[');
163
159
  };
164
160
 
165
161
  // If insert operation is triggered by shortcut, remove the '[[' symbol
@@ -172,8 +168,8 @@ export const removeShortCutSymbol = editor => {
172
168
  beforeText,
173
169
  range: beforeRange
174
170
  } = getBeforeText(editor);
175
- const isTrrigeredByShortCut = beforeText.slice(-2) === '[[';
176
- isTrrigeredByShortCut && Transforms.delete(editor, {
171
+ const isTriggeredByShortCut = beforeText.slice(-2) === '[[';
172
+ isTriggeredByShortCut && Transforms.delete(editor, {
177
173
  at: {
178
174
  anchor: {
179
175
  path: beforeRange.focus.path,
@@ -184,4 +180,57 @@ export const removeShortCutSymbol = editor => {
184
180
  voids: true
185
181
  });
186
182
  focusEditor(editor);
183
+ };
184
+
185
+ // Generate temp input for collecting file name
186
+ const generateFileLinkInput = () => {
187
+ const input = generateEmptyElement(FILE_LINK_INSET_INPUT_TEMP);
188
+ return input;
189
+ };
190
+
191
+ // Insert temp input collecting file name
192
+ export const insertTempInput = editor => {
193
+ const {
194
+ selection
195
+ } = editor;
196
+ if (!Range.isCollapsed(selection)) return;
197
+ const tempInput = generateFileLinkInput();
198
+ const insertPoint = Editor.start(editor, selection);
199
+ Transforms.insertNodes(editor, tempInput, {
200
+ at: insertPoint
201
+ });
202
+ const path = Editor.path(editor, insertPoint);
203
+ const insertPath = Path.next(path);
204
+ const focusPoint = insertPath.concat(0);
205
+ focusEditor(editor, focusPoint);
206
+ };
207
+
208
+ // Remove temp input collecting file name
209
+ export const removeTempInput = (editor, element) => {
210
+ const path = ReactEditor.findPath(editor, element);
211
+ Transforms.delete(editor, {
212
+ at: path
213
+ });
214
+ };
215
+ export const getFileSearchInputEntry = editor => {
216
+ const [searchInputNodeEntry] = Editor.nodes(editor, {
217
+ match: n => n.type === FILE_LINK_INSET_INPUT_TEMP
218
+ });
219
+ return searchInputNodeEntry;
220
+ };
221
+
222
+ // Insert text when remove file name collector, such as inserting 'filename' into prevNode when close collector entered '[[filename'
223
+ export const insertTextWhenRemoveFileNameCollector = (editor, searchInputNode) => {
224
+ const inputNodePath = ReactEditor.findPath(editor, searchInputNode);
225
+ if (!inputNodePath) return;
226
+ const prevNodeEntry = Editor.previous(editor, {
227
+ at: inputNodePath
228
+ });
229
+ if (!prevNodeEntry) return;
230
+ const searchContent = Node.string(searchInputNode);
231
+ const insertPoint = Editor.end(editor, prevNodeEntry[1]);
232
+ Transforms.insertText(editor, searchContent, {
233
+ at: insertPoint
234
+ });
235
+ removeTempInput(editor, searchInputNode);
187
236
  };
@@ -1,11 +1,12 @@
1
1
  import { SDOC_LINK } from '../../constants';
2
2
  import SdocLinkMenu from './menu';
3
3
  import withSdocLink from './plugin';
4
- import renderSdocLink from './render-elem';
4
+ import renderSdocLink from './render/render-elem';
5
+ import renderFileLinkTempInput from './render/render-file-link-temp-input';
5
6
  const SdocLinkPlugin = {
6
7
  type: SDOC_LINK,
7
8
  editorMenus: [SdocLinkMenu],
8
9
  editorPlugin: withSdocLink,
9
- renderElements: [renderSdocLink]
10
+ renderElements: [renderSdocLink, renderFileLinkTempInput]
10
11
  };
11
12
  export default SdocLinkPlugin;
@@ -1,13 +1,14 @@
1
1
  import { Transforms, Node, Editor } from '@seafile/slate';
2
- import { ELEMENT_TYPE, SDOC_LINK } from '../../constants';
3
- import EventBus from '../../../utils/event-bus';
4
- import { INTERNAL_EVENT } from '../../../constants';
5
- import { insertSdocFileLink, isTriggeredByShortCut } from './helpers';
2
+ import { ReactEditor } from '@seafile/slate-react';
3
+ import { FILE_LINK_INSET_INPUT_TEMP, SDOC_LINK } from '../../constants';
4
+ import { getFileSearchInputEntry, insertTempInput, isTriggeredByShortcut } from './helpers';
5
+ import { getSelectedElems } from '../../core';
6
6
  const withSdocLink = editor => {
7
7
  const {
8
8
  isInline,
9
9
  deleteBackward,
10
- onHotKeyDown
10
+ insertText,
11
+ onCompositionStart
11
12
  } = editor;
12
13
  const newEditor = editor;
13
14
 
@@ -16,9 +17,8 @@ const withSdocLink = editor => {
16
17
  const {
17
18
  type
18
19
  } = elem;
19
- if (type === SDOC_LINK) {
20
- return true;
21
- }
20
+ const isInlineElem = [SDOC_LINK, FILE_LINK_INSET_INPUT_TEMP].includes(type);
21
+ if (isInlineElem) return true;
22
22
  return isInline(elem);
23
23
  };
24
24
  newEditor.deleteBackward = unit => {
@@ -29,13 +29,21 @@ const withSdocLink = editor => {
29
29
  return deleteBackward(unit);
30
30
  }
31
31
 
32
- // Delete file link node
32
+ // Delete file link node when the input is empty
33
+ const selectedElems = getSelectedElems(newEditor);
34
+ const fileLinkSearchInputNode = selectedElems.find(elem => elem.type === FILE_LINK_INSET_INPUT_TEMP);
35
+ if (fileLinkSearchInputNode) {
36
+ const path = ReactEditor.findPath(editor, fileLinkSearchInputNode);
37
+ if (Node.string(fileLinkSearchInputNode).length === 0) return Transforms.delete(newEditor, {
38
+ at: path
39
+ });
40
+ }
33
41
  const nodeEntry = Editor.node(newEditor, newEditor.selection);
34
42
  if (nodeEntry && Node.string(nodeEntry[0]).length === 0) {
35
43
  const beforePath = nodeEntry[1];
36
44
  beforePath.splice(-1, 1, Math.max(nodeEntry[1].at(-1) - 1, 0));
37
45
  const beforeNodeEntry = Editor.node(newEditor, beforePath);
38
- if (beforeNodeEntry && beforeNodeEntry[0].type === SDOC_LINK) {
46
+ if (beforeNodeEntry && [SDOC_LINK, FILE_LINK_INSET_INPUT_TEMP].includes(beforeNodeEntry[0].type)) {
39
47
  Transforms.delete(newEditor, {
40
48
  at: beforeNodeEntry[1]
41
49
  });
@@ -45,21 +53,23 @@ const withSdocLink = editor => {
45
53
  }
46
54
  return deleteBackward(unit);
47
55
  };
48
- newEditor.onHotKeyDown = event => {
49
- const {
50
- key
51
- } = event;
52
- if (key !== '[') return onHotKeyDown && onHotKeyDown(event);
56
+ newEditor.insertText = text => {
57
+ if (text !== '[') return insertText(text);
53
58
  // If user press '[[', open file modal
54
- const eventBus = EventBus.getInstance();
55
- if (isTriggeredByShortCut(newEditor)) {
56
- eventBus.dispatch(INTERNAL_EVENT.INSERT_ELEMENT, {
57
- type: ELEMENT_TYPE.SDOC_LINK,
58
- insertSdocFileLinkCallback: insertSdocFileLink,
59
- isShowHistoryFiles: true
60
- });
59
+ if (isTriggeredByShortcut(newEditor)) {
60
+ insertText(text);
61
+ insertTempInput(newEditor);
62
+ return;
63
+ }
64
+ return insertText(text);
65
+ };
66
+ newEditor.onCompositionStart = event => {
67
+ const fileSearchInputNodeEntry = getFileSearchInputEntry(newEditor);
68
+ if (fileSearchInputNodeEntry) {
69
+ event.preventDefault();
70
+ return true;
61
71
  }
62
- return onHotKeyDown && onHotKeyDown(event);
72
+ return onCompositionStart && onCompositionStart(event);
63
73
  };
64
74
  return newEditor;
65
75
  };
@@ -20,7 +20,7 @@
20
20
  }
21
21
 
22
22
  .sdoc-file-card-link .sdoc-file-link-icon :first-child {
23
- font-size: 24px;
23
+ font-size: 24px;
24
24
  }
25
25
 
26
26
  .sdoc-file-card-link .sdoc-file-link-icon {
@@ -39,3 +39,7 @@
39
39
  text-decoration: none;
40
40
  color: #333;
41
41
  }
42
+
43
+ .sdoc-file-name-insert-collector {
44
+ padding: 0 .25em;
45
+ }
@@ -2,12 +2,12 @@ import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
2
2
  import React, { useCallback, useEffect, useState, useRef } from 'react';
3
3
  import { Editor, Range } from '@seafile/slate';
4
4
  import { ReactEditor, useReadOnly } from '@seafile/slate-react';
5
- import { useScrollContext } from '../../../hooks/use-scroll-context';
6
- import { unwrapLinkNode, getUrl } from './helpers';
7
- import HoverMenu from './hover-menu';
8
- import { DELETED_STYLE, ADDED_STYLE } from '../../constants';
9
- import { SDOC_LINK_TYPE } from './constants';
10
- import { focusEditor } from '../../core';
5
+ import { useScrollContext } from '../../../../hooks/use-scroll-context';
6
+ import { unwrapLinkNode, getUrl } from '../helpers';
7
+ import HoverMenu from '../hover-menu';
8
+ import { DELETED_STYLE, ADDED_STYLE } from '../../../constants';
9
+ import { SDOC_LINK_TYPE } from '../constants';
10
+ import { focusEditor } from '../../../core';
11
11
  import './render-elem.css';
12
12
  const SdocFileLink = _ref => {
13
13
  let {
@@ -0,0 +1,26 @@
1
+ import React, { useEffect } from 'react';
2
+ import EventBus from '../../../../utils/event-bus';
3
+ import { INTERNAL_EVENT } from '../../../../constants';
4
+ import { FILE_LINK_INSET_INPUT_TEMP } from '../../../constants';
5
+ import './render-elem.css';
6
+ const RenderFileLinkTempInput = _ref => {
7
+ let {
8
+ element,
9
+ attributes,
10
+ children
11
+ } = _ref;
12
+ const eventBus = EventBus.getInstance();
13
+ useEffect(() => {
14
+ eventBus.dispatch(INTERNAL_EVENT.INSERT_ELEMENT, {
15
+ type: FILE_LINK_INSET_INPUT_TEMP,
16
+ slateNode: element
17
+ });
18
+ return () => {
19
+ eventBus.dispatch(INTERNAL_EVENT.CLOSE_FILE_INSET_DIALOG);
20
+ };
21
+ }, [element, eventBus]);
22
+ return /*#__PURE__*/React.createElement("span", Object.assign({}, attributes, {
23
+ className: "sdoc-file-name-insert-collector"
24
+ }), children);
25
+ };
26
+ export default RenderFileLinkTempInput;
@@ -1,6 +1,6 @@
1
1
  import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
2
2
  import { useReadOnly, useSlateStatic } from '@seafile/slate-react';
3
- import { BLOCKQUOTE, LINK, CHECK_LIST_ITEM, HEADER1, HEADER2, HEADER3, HEADER4, HEADER5, HEADER6, LIST_ITEM, ORDERED_LIST, PARAGRAPH, UNORDERED_LIST, CODE_BLOCK, CODE_LINE, IMAGE, IMAGE_BLOCK, ELEMENT_TYPE, SDOC_LINK, FILE_LINK, TITLE, SUBTITLE, CALL_OUT, SUPPORTED_SIDE_OPERATION_TYPE, MENTION, MENTION_TEMP } from '../constants';
3
+ import { BLOCKQUOTE, LINK, CHECK_LIST_ITEM, HEADER1, HEADER2, HEADER3, HEADER4, HEADER5, HEADER6, LIST_ITEM, ORDERED_LIST, PARAGRAPH, UNORDERED_LIST, CODE_BLOCK, CODE_LINE, IMAGE, IMAGE_BLOCK, ELEMENT_TYPE, SDOC_LINK, FILE_LINK, TITLE, SUBTITLE, CALL_OUT, SUPPORTED_SIDE_OPERATION_TYPE, MENTION, MENTION_TEMP, FILE_LINK_INSET_INPUT_TEMP } from '../constants';
4
4
  import { BlockquotePlugin, LinkPlugin, CheckListPlugin, HeaderPlugin, ListPlugin, CodeBlockPlugin, ImagePlugin, TablePlugin, SdocLinkPlugin, ParagraphPlugin, FileLinkPlugin, CalloutPlugin, MentionPlugin } from '../plugins';
5
5
  import { onDragOver, onDragLeave, onDrop } from '../toolbar/side-toolbar/event';
6
6
  import { getParentNode } from '../core';
@@ -134,6 +134,11 @@ const CustomRenderElement = props => {
134
134
  const [renderFileLink] = FileLinkPlugin.renderElements;
135
135
  return renderFileLink(props, editor);
136
136
  }
137
+ case FILE_LINK_INSET_INPUT_TEMP:
138
+ {
139
+ const [, renderFileLinkFileSearchInput] = SdocLinkPlugin.renderElements;
140
+ return renderFileLinkFileSearchInput(props, editor);
141
+ }
137
142
  case CALL_OUT:
138
143
  {
139
144
  const [renderCallout] = CalloutPlugin.renderElements;
@@ -47,10 +47,18 @@ const ContextToolbar = () => {
47
47
  const onMouseDown = useCallback(event => {
48
48
  event.preventDefault(); // prevent toolbar from taking focus away from editor
49
49
  }, []);
50
+ const onMouseMove = useCallback(e => {
51
+ const isMouseLeftDown = e.buttons === 1;
52
+ if (isMouseLeftDown) {
53
+ const el = ref.current;
54
+ el.removeAttribute('style');
55
+ }
56
+ }, []);
50
57
  return createPortal( /*#__PURE__*/React.createElement("div", {
51
58
  ref: ref,
52
59
  className: "sdoc-context-toolbar",
53
- onMouseDown: onMouseDown
60
+ onMouseDown: onMouseDown,
61
+ onMouseOver: onMouseMove
54
62
  }, /*#__PURE__*/React.createElement(MenuGroup, null, /*#__PURE__*/React.createElement(TextStyleMenuList, {
55
63
  editor: editor,
56
64
  idPrefix: 'sdoc_context_toolbar'
@@ -37,6 +37,30 @@ export const getTopLevelChanges = changes => {
37
37
  return Array.from(new Set(topLevelChanges));
38
38
  };
39
39
 
40
+ // Merge consecutive added areas or deleted areas
41
+ export const getMergedChanges = (topLevelChanges, diffValue) => {
42
+ const topLevelChangesValue = [];
43
+ const changes = [];
44
+ diffValue.forEach(item => {
45
+ if (topLevelChanges.includes(item.id)) {
46
+ const obj = {
47
+ id: item.id,
48
+ value: item
49
+ };
50
+ topLevelChangesValue.push(obj);
51
+ }
52
+ });
53
+ topLevelChangesValue.forEach(item => {
54
+ var _changes;
55
+ const preChange = (_changes = changes[changes.length - 1]) === null || _changes === void 0 ? void 0 : _changes.value;
56
+ const curChange = item.value;
57
+ if ((curChange === null || curChange === void 0 ? void 0 : curChange.add) && (preChange === null || preChange === void 0 ? void 0 : preChange.add)) return;
58
+ if ((curChange === null || curChange === void 0 ? void 0 : curChange.delete) && (preChange === null || preChange === void 0 ? void 0 : preChange.delete)) return;
59
+ changes.push(item);
60
+ });
61
+ return changes.map(item => item.id);
62
+ };
63
+
40
64
  // Depth facilitates each child node, adding diffType to each end node
41
65
  const generatorDiffElement = function (element, diffType) {
42
66
  let style = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
@@ -62,6 +62,7 @@ const MoreOperations = _ref => {
62
62
  return printTexts;
63
63
  }, []);
64
64
  return /*#__PURE__*/React.createElement(Dropdown, {
65
+ className: "sdoc-operator-folder",
65
66
  isOpen: isDropdownOpen,
66
67
  toggle: () => toggleDropdown(isDropdownOpen)
67
68
  }, /*#__PURE__*/React.createElement(DropdownToggle, {
@@ -72,26 +73,28 @@ const MoreOperations = _ref => {
72
73
  })), /*#__PURE__*/React.createElement(DropdownMenu, {
73
74
  className: "sdoc-dropdown-menu",
74
75
  right: true
75
- }, parentFolderURL && /*#__PURE__*/React.createElement(DropdownItem, {
76
- className: "sdoc-dropdown-menu-item",
77
- tag: "a",
78
- href: parentFolderURL
79
- }, t('Open_parent_folder')), isPro && isFreezed && /*#__PURE__*/React.createElement(DropdownItem, {
80
- className: "sdoc-dropdown-menu-item",
81
- onClick: unFreeze
82
- }, t('Unfreeze')), /*#__PURE__*/React.createElement(DropdownItem, {
76
+ }, /*#__PURE__*/React.createElement(DropdownItem, {
83
77
  className: "sdoc-dropdown-menu-item",
84
78
  onClick: handlePrint
85
79
  }, /*#__PURE__*/React.createElement("div", {
86
80
  className: "sdoc-dropdown-print-container"
87
81
  }, /*#__PURE__*/React.createElement("div", null, t('Print')), /*#__PURE__*/React.createElement(MenuShortcutPrompt, {
88
82
  shortcuts: printShortCutTexts
89
- }))), isPro && !isFreezed && /*#__PURE__*/React.createElement(DropdownItem, {
83
+ }))), isPro && isFreezed && /*#__PURE__*/React.createElement(DropdownItem, {
84
+ className: "sdoc-dropdown-menu-item",
85
+ onClick: unFreeze
86
+ }, t('Unfreeze')), isPro && !isFreezed && /*#__PURE__*/React.createElement(DropdownItem, {
90
87
  className: "sdoc-dropdown-menu-item",
91
88
  onClick: onFreezeDocument
92
89
  }, t('Freeze_document')), /*#__PURE__*/React.createElement(DropdownItem, {
93
90
  className: "sdoc-dropdown-menu-item",
94
91
  onClick: handleClickHistory
95
- }, t('Document_history'))));
92
+ }, t('Document_history')), parentFolderURL && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
93
+ className: "sdoc-operator-folder-divider"
94
+ }), /*#__PURE__*/React.createElement(DropdownItem, {
95
+ className: "sdoc-dropdown-menu-item",
96
+ tag: "a",
97
+ href: parentFolderURL
98
+ }, t('Open_parent_folder')))));
96
99
  };
97
100
  export default withTranslation('sdoc-editor')(MoreOperations);