@seafile/sdoc-editor 0.4.15 → 0.4.17
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/editor/editable-article.js +11 -6
- package/dist/basic-sdk/extension/commons/history-files/index.css +65 -0
- package/dist/basic-sdk/extension/commons/history-files/index.js +156 -0
- package/dist/basic-sdk/extension/commons/insert-element-dialog/index.js +9 -1
- package/dist/basic-sdk/extension/commons/select-file-dialog/index.css +2 -37
- package/dist/basic-sdk/extension/commons/select-file-dialog/index.js +1 -9
- package/dist/basic-sdk/extension/commons/select-file-dialog/local-files/index.css +7 -13
- package/dist/basic-sdk/extension/plugins/image/hover-menu/index.js +6 -3
- package/dist/basic-sdk/extension/plugins/sdoc-link/helpers.js +3 -5
- package/dist/basic-sdk/extension/plugins/sdoc-link/plugin.js +2 -1
- package/dist/constants/index.js +2 -1
- package/package.json +1 -1
- package/public/locales/en/sdoc-editor.json +5 -1
- package/public/locales/zh_CN/sdoc-editor.json +5 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { useCallback, useMemo, Fragment } from 'react';
|
|
2
2
|
import { Editable, ReactEditor, Slate } from '@seafile/slate-react';
|
|
3
|
-
import { Editor } from '@seafile/slate';
|
|
3
|
+
import { Editor, Node, Range } from '@seafile/slate';
|
|
4
4
|
import { renderLeaf, renderElement, ContextToolbar, SideToolbar } from '../extension';
|
|
5
5
|
import { getAboveBlockNode, getNextNode, getPrevNode, isSelectionAtBlockEnd, isSelectionAtBlockStart } from '../extension/core';
|
|
6
6
|
import EventProxy from '../utils/event-handler';
|
|
@@ -139,11 +139,16 @@ const EditableArticle = _ref => {
|
|
|
139
139
|
const {
|
|
140
140
|
selection
|
|
141
141
|
} = editor;
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
142
|
+
if (Range.isCollapsed(selection)) {
|
|
143
|
+
// Do not scroll into view, when focus on image
|
|
144
|
+
const [imageNodeEntry] = Editor.nodes(editor, {
|
|
145
|
+
match: n => n.type === IMAGE,
|
|
146
|
+
at: selection
|
|
147
|
+
});
|
|
148
|
+
if (imageNodeEntry) return;
|
|
149
|
+
}
|
|
150
|
+
const focusedNode = Node.get(editor, selection.focus.path);
|
|
151
|
+
const domNode = ReactEditor.toDOMNode(editor, focusedNode);
|
|
147
152
|
if (!domNode) return;
|
|
148
153
|
domNode.scrollIntoView({
|
|
149
154
|
block: 'nearest'
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
.sdoc-history-files-wrapper {
|
|
2
|
+
position: absolute;
|
|
3
|
+
z-index: 101;
|
|
4
|
+
width: 400px;
|
|
5
|
+
cursor: pointer;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.sdoc-history-files-wrapper .sdoc-history-files-search-input {
|
|
9
|
+
border: 0;
|
|
10
|
+
outline: none;
|
|
11
|
+
margin-top: -21px;
|
|
12
|
+
position: absolute;
|
|
13
|
+
background-color: transparent;
|
|
14
|
+
padding: 0px;
|
|
15
|
+
color: #212529;
|
|
16
|
+
font-size: 14px;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.sdoc-history-files-wrapper .sdoc-history-files-content .sdoc-history-files-header {
|
|
20
|
+
color: #999999;
|
|
21
|
+
font-size: 14px;
|
|
22
|
+
margin-top: 8px;
|
|
23
|
+
height: 32px;
|
|
24
|
+
display: flex;
|
|
25
|
+
align-items: center;
|
|
26
|
+
padding: 0px 16px;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.sdoc-history-files-wrapper .sdoc-history-files-content .sdoc-history-files {
|
|
30
|
+
max-height: 306px;
|
|
31
|
+
overflow-y: scroll;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.sdoc-history-files-wrapper .sdoc-history-files-content .sdoc-history-files .sdoc-history-files-item {
|
|
35
|
+
font-size: 14px;
|
|
36
|
+
line-height: 32px;
|
|
37
|
+
height: 32px;
|
|
38
|
+
padding: 0px 16px;
|
|
39
|
+
overflow:hidden;
|
|
40
|
+
text-overflow:ellipsis;
|
|
41
|
+
white-space:nowrap;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.sdoc-history-files-wrapper .sdoc-history-files-content .sdoc-history-files .sdoc-history-files-item :first-child {
|
|
45
|
+
font-size: 12px;
|
|
46
|
+
margin-right: 5px;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.sdoc-history-files-wrapper .sdoc-history-files-content .sdoc-history-files .sdoc-history-files-item:hover {
|
|
50
|
+
background-color: #f5f5f5;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.sdoc-history-files-wrapper .sdoc-history-files-content .sdoc-history-files-add {
|
|
54
|
+
height: 32px;
|
|
55
|
+
padding: 0px 16px;
|
|
56
|
+
border-top: 1px solid #e9ecef;
|
|
57
|
+
font-size: 14px;
|
|
58
|
+
display: flex;
|
|
59
|
+
align-items: center;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.sdoc-history-files-wrapper .sdoc-history-files-content .sdoc-history-files-add :first-child {
|
|
63
|
+
color: #444444;
|
|
64
|
+
margin-right: 10px;
|
|
65
|
+
}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
2
|
+
import React, { useCallback, useEffect, useState, useRef } from 'react';
|
|
3
|
+
import { Editor } from '@seafile/slate';
|
|
4
|
+
import { ReactEditor } from '@seafile/slate-react';
|
|
5
|
+
import { withTranslation } from 'react-i18next';
|
|
6
|
+
import EventBus from '../../../utils/event-bus';
|
|
7
|
+
import { insertSdocFileLink } from '../../plugins/sdoc-link/helpers';
|
|
8
|
+
import { LocalStorage } from '../../../../utils';
|
|
9
|
+
import { INTERNAL_EVENT } from '../../../constants';
|
|
10
|
+
import { EXTERNAL_EVENT } from '../../../../constants';
|
|
11
|
+
import { SDOC_LINK } from '../../constants';
|
|
12
|
+
import './index.css';
|
|
13
|
+
const HistoryFiles = _ref => {
|
|
14
|
+
let {
|
|
15
|
+
editor,
|
|
16
|
+
insertLinkCallback,
|
|
17
|
+
closeDialog,
|
|
18
|
+
t
|
|
19
|
+
} = _ref;
|
|
20
|
+
const historyFilesRef = useRef();
|
|
21
|
+
const historyFilesInputRef = useRef();
|
|
22
|
+
const [files, setFiles] = useState([]);
|
|
23
|
+
const [position, setPosition] = useState({});
|
|
24
|
+
const [header, setHeader] = useState(t('Recent_previews'));
|
|
25
|
+
const [newFileName, setNewFileName] = useState('');
|
|
26
|
+
const getPosition = useCallback(() => {
|
|
27
|
+
const {
|
|
28
|
+
selection
|
|
29
|
+
} = editor;
|
|
30
|
+
const nodeEntry = Editor.node(editor, selection);
|
|
31
|
+
const domNode = ReactEditor.toDOMNode(editor, nodeEntry[0]);
|
|
32
|
+
if (domNode) {
|
|
33
|
+
const {
|
|
34
|
+
top,
|
|
35
|
+
right
|
|
36
|
+
} = domNode.getBoundingClientRect();
|
|
37
|
+
setPosition({
|
|
38
|
+
left: right + 5,
|
|
39
|
+
top: top + 20
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
43
|
+
}, []);
|
|
44
|
+
const onClick = useCallback(e => {
|
|
45
|
+
if (historyFilesRef.current.contains(e.target)) return;
|
|
46
|
+
closeDialog();
|
|
47
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
48
|
+
}, []);
|
|
49
|
+
const onScroll = useCallback(e => {
|
|
50
|
+
getPosition();
|
|
51
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
52
|
+
}, []);
|
|
53
|
+
const getHistoryFiles = useCallback(e => {
|
|
54
|
+
const files = LocalStorage.getItem('sdoc-recent-files') || [];
|
|
55
|
+
setFiles(files);
|
|
56
|
+
}, []);
|
|
57
|
+
useEffect(() => {
|
|
58
|
+
getPosition();
|
|
59
|
+
getHistoryFiles();
|
|
60
|
+
setTimeout(() => {
|
|
61
|
+
historyFilesInputRef.current.focus();
|
|
62
|
+
}, 0);
|
|
63
|
+
const sdocScrollContainer = document.getElementById('sdoc-scroll-container');
|
|
64
|
+
sdocScrollContainer.addEventListener('scroll', onScroll);
|
|
65
|
+
document.addEventListener('click', onClick);
|
|
66
|
+
return () => {
|
|
67
|
+
sdocScrollContainer.removeEventListener('scroll', onScroll);
|
|
68
|
+
document.removeEventListener('click', onClick);
|
|
69
|
+
};
|
|
70
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
71
|
+
}, []);
|
|
72
|
+
const onSearch = useCallback(e => {
|
|
73
|
+
let newFiles = LocalStorage.getItem('sdoc-recent-files') || [];
|
|
74
|
+
if (e.target.value) {
|
|
75
|
+
newFiles = newFiles.filter(item => item.file_name.includes(e.target.value));
|
|
76
|
+
if (newFiles.length === 0) {
|
|
77
|
+
setHeader(t('The_document_does_not_exist'));
|
|
78
|
+
setNewFileName(e.target.value);
|
|
79
|
+
} else {
|
|
80
|
+
setHeader(t('Recent_previews'));
|
|
81
|
+
setNewFileName('');
|
|
82
|
+
}
|
|
83
|
+
setFiles(newFiles);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
setHeader(t('Recent_previews'));
|
|
87
|
+
setNewFileName('');
|
|
88
|
+
setFiles(newFiles);
|
|
89
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
90
|
+
}, []);
|
|
91
|
+
const onSelect = useCallback(fileInfo => {
|
|
92
|
+
const {
|
|
93
|
+
file_uuid,
|
|
94
|
+
file_name
|
|
95
|
+
} = fileInfo;
|
|
96
|
+
const {
|
|
97
|
+
insertSdocFileLinkCallback
|
|
98
|
+
} = insertLinkCallback;
|
|
99
|
+
insertSdocFileLinkCallback(editor, file_name, file_uuid);
|
|
100
|
+
closeDialog();
|
|
101
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
102
|
+
}, []);
|
|
103
|
+
const onShowMore = useCallback(() => {
|
|
104
|
+
const eventBus = EventBus.getInstance();
|
|
105
|
+
eventBus.dispatch(INTERNAL_EVENT.INSERT_ELEMENT, {
|
|
106
|
+
type: SDOC_LINK,
|
|
107
|
+
insertSdocFileLinkCallback: insertSdocFileLink
|
|
108
|
+
});
|
|
109
|
+
}, []);
|
|
110
|
+
const onCreateFile = useCallback(() => {
|
|
111
|
+
const eventBus = EventBus.getInstance();
|
|
112
|
+
eventBus.dispatch(EXTERNAL_EVENT.CREATE_SDOC_FILE, {
|
|
113
|
+
newFileName: newFileName.trim()
|
|
114
|
+
});
|
|
115
|
+
closeDialog();
|
|
116
|
+
}, [closeDialog, newFileName]);
|
|
117
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
118
|
+
ref: historyFilesRef,
|
|
119
|
+
className: "sdoc-history-files-wrapper popover",
|
|
120
|
+
style: _objectSpread({}, position)
|
|
121
|
+
}, /*#__PURE__*/React.createElement("input", {
|
|
122
|
+
id: "sdoc-history-files-search-input",
|
|
123
|
+
className: "sdoc-history-files-search-input",
|
|
124
|
+
ref: historyFilesInputRef,
|
|
125
|
+
autoComplete: "off",
|
|
126
|
+
onChange: onSearch,
|
|
127
|
+
onCompositionStart: e => {
|
|
128
|
+
e.stopPropagation();
|
|
129
|
+
}
|
|
130
|
+
}), /*#__PURE__*/React.createElement("div", {
|
|
131
|
+
className: "sdoc-history-files-content"
|
|
132
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
133
|
+
className: "sdoc-history-files-header"
|
|
134
|
+
}, header), /*#__PURE__*/React.createElement("div", {
|
|
135
|
+
className: "sdoc-history-files"
|
|
136
|
+
}, files.map(item => {
|
|
137
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
138
|
+
key: item.file_uuid,
|
|
139
|
+
className: "sdoc-history-files-item",
|
|
140
|
+
onClick: () => {
|
|
141
|
+
onSelect(item);
|
|
142
|
+
}
|
|
143
|
+
}, /*#__PURE__*/React.createElement("i", {
|
|
144
|
+
className: "sdocfont sdoc-document"
|
|
145
|
+
}), /*#__PURE__*/React.createElement("span", null, item.file_name));
|
|
146
|
+
}), /*#__PURE__*/React.createElement("div", {
|
|
147
|
+
className: "sdoc-history-files-item",
|
|
148
|
+
onClick: onShowMore
|
|
149
|
+
}, "...", t('More'))), /*#__PURE__*/React.createElement("div", {
|
|
150
|
+
className: "sdoc-history-files-add",
|
|
151
|
+
onClick: onCreateFile
|
|
152
|
+
}, /*#__PURE__*/React.createElement("i", {
|
|
153
|
+
className: "sdocfont sdoc-append"
|
|
154
|
+
}), /*#__PURE__*/React.createElement("span", null, newFileName ? t("Create ".concat(newFileName, ".sdoc")) : t('Create_a_new_sdoc_file')))));
|
|
155
|
+
};
|
|
156
|
+
export default withTranslation('sdoc-editor')(HistoryFiles);
|
|
@@ -2,6 +2,7 @@ import React, { useCallback, useEffect, useState, useRef } from 'react';
|
|
|
2
2
|
import { CustomTableSizeDialog, SplitCellSettingDialog } from '../../plugins/table/dialogs';
|
|
3
3
|
import AddLinkDialog from '../../plugins/link/dialog/add-link-dialog';
|
|
4
4
|
import SelectFileDialog from '../select-file-dialog/index.js';
|
|
5
|
+
import HistoryFiles from '../history-files';
|
|
5
6
|
import EventBus from '../../../utils/event-bus';
|
|
6
7
|
import { INTERNAL_EVENT } from '../../../constants';
|
|
7
8
|
import { ELEMENT_TYPE, INSERT_POSITION, LOCAL_IMAGE } from '../../constants';
|
|
@@ -16,6 +17,7 @@ const InsertElementDialog = _ref => {
|
|
|
16
17
|
const [insertPosition, setInsertPosition] = useState(INSERT_POSITION.CURRENT);
|
|
17
18
|
const [slateNode, setSlateNode] = useState(null);
|
|
18
19
|
const [insertLinkCallback, setInsertLinkCallback] = useState(null);
|
|
20
|
+
const [isShowHistoryFiles, setIsShowHistoryFiles] = useState(false);
|
|
19
21
|
const uploadLocalImageInputRef = useRef();
|
|
20
22
|
const onFileChanged = useCallback(event => {
|
|
21
23
|
const files = event.target.files;
|
|
@@ -42,7 +44,8 @@ const InsertElementDialog = _ref => {
|
|
|
42
44
|
insertPosition = INSERT_POSITION.CURRENT,
|
|
43
45
|
slateNode,
|
|
44
46
|
insertFileLinkCallback,
|
|
45
|
-
insertSdocFileLinkCallback
|
|
47
|
+
insertSdocFileLinkCallback,
|
|
48
|
+
isShowHistoryFiles
|
|
46
49
|
} = _ref2;
|
|
47
50
|
setInsertPosition(insertPosition);
|
|
48
51
|
setSlateNode(slateNode);
|
|
@@ -52,6 +55,7 @@ const InsertElementDialog = _ref => {
|
|
|
52
55
|
insertSdocFileLinkCallback,
|
|
53
56
|
insertFileLinkCallback
|
|
54
57
|
});
|
|
58
|
+
setIsShowHistoryFiles(isShowHistoryFiles);
|
|
55
59
|
if (type === LOCAL_IMAGE) {
|
|
56
60
|
setTimeout(() => {
|
|
57
61
|
uploadLocalImageInputRef.current && uploadLocalImageInputRef.current.click();
|
|
@@ -64,6 +68,7 @@ const InsertElementDialog = _ref => {
|
|
|
64
68
|
setElement('');
|
|
65
69
|
setDialogType('');
|
|
66
70
|
setInsertLinkCallback(null);
|
|
71
|
+
setIsShowHistoryFiles(false);
|
|
67
72
|
}, []);
|
|
68
73
|
const props = {
|
|
69
74
|
insertPosition,
|
|
@@ -93,6 +98,9 @@ const InsertElementDialog = _ref => {
|
|
|
93
98
|
insertLinkCallback,
|
|
94
99
|
closeDialog
|
|
95
100
|
};
|
|
101
|
+
if (isShowHistoryFiles) {
|
|
102
|
+
return /*#__PURE__*/React.createElement(HistoryFiles, sdocLinkProps);
|
|
103
|
+
}
|
|
96
104
|
return /*#__PURE__*/React.createElement(SelectFileDialog, sdocLinkProps);
|
|
97
105
|
}
|
|
98
106
|
case ELEMENT_TYPE.FILE_LINK:
|
|
@@ -1,44 +1,9 @@
|
|
|
1
1
|
.sdoc-file-select-dialog {
|
|
2
|
-
max-width:
|
|
2
|
+
max-width: 520px;
|
|
3
3
|
}
|
|
4
4
|
|
|
5
5
|
.sdoc-file-select-dialog .sdoc-file-select-modal {
|
|
6
|
-
width:
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
.sdoc-file-select-dialog .sdoc-file-select-container {
|
|
10
|
-
display: flex;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
.sdoc-file-select-dialog .sdoc-file-select-left {
|
|
14
|
-
border-right: 1px solid #e9ecef;
|
|
15
|
-
width: 150px;
|
|
16
|
-
padding: 12px 8px;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
.sdoc-file-select-dialog .sdoc-file-select-left .sdoc-file-select-nav-item {
|
|
20
|
-
padding: 5px 0 5px 8px;
|
|
21
|
-
border-radius: 3px;
|
|
22
|
-
display: inline-block;
|
|
23
|
-
cursor: pointer;
|
|
24
|
-
width: 100%;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
.sdoc-file-select-dialog .sdoc-file-select-left .sdoc-file-select-nav-item:hover {
|
|
28
|
-
background-color: #f5f5f5;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
.sdoc-file-select-dialog .sdoc-file-select-container .sdoc-file-select-left .selected-sdoc-file-select-nav-item {
|
|
32
|
-
background-color: #ff8000;
|
|
33
|
-
color: #fff;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
.sdoc-file-select-dialog .sdoc-file-select-right {
|
|
37
|
-
height: 440px;
|
|
38
|
-
width: 468px;
|
|
39
|
-
display: flex;
|
|
40
|
-
padding: 0;
|
|
41
|
-
flex-direction: column;
|
|
6
|
+
width: 520px;
|
|
42
7
|
}
|
|
43
8
|
|
|
44
9
|
.sdoc-file-select-dialog .sdoc-file-select-footer {
|
|
@@ -73,14 +73,6 @@ const SelectSdocFileDialog = _ref => {
|
|
|
73
73
|
className: "p-0"
|
|
74
74
|
}, /*#__PURE__*/React.createElement("div", {
|
|
75
75
|
className: "sdoc-file-select-container"
|
|
76
|
-
}, /*#__PURE__*/React.createElement("div", {
|
|
77
|
-
className: "sdoc-file-select-left"
|
|
78
|
-
}, /*#__PURE__*/React.createElement("div", {
|
|
79
|
-
className: "sdoc-file-select-nav"
|
|
80
|
-
}, /*#__PURE__*/React.createElement("div", {
|
|
81
|
-
className: "sdoc-file-select-nav-item selected-sdoc-file-select-nav-item"
|
|
82
|
-
}, t('Local_file')))), /*#__PURE__*/React.createElement("div", {
|
|
83
|
-
className: "sdoc-file-select-right"
|
|
84
76
|
}, /*#__PURE__*/React.createElement(LocalFiles, {
|
|
85
77
|
fileType: FILE_TYPE[dialogType],
|
|
86
78
|
onSelectedFile: onSelectedFile,
|
|
@@ -96,6 +88,6 @@ const SelectSdocFileDialog = _ref => {
|
|
|
96
88
|
className: "highlight-bg-color",
|
|
97
89
|
disabled: !currentSelectedFile,
|
|
98
90
|
onClick: onSubmit
|
|
99
|
-
}, t('Confirm'))))))
|
|
91
|
+
}, t('Confirm'))))));
|
|
100
92
|
};
|
|
101
93
|
export default SelectSdocFileDialog;
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
.sdoc-files-tree {
|
|
2
2
|
flex: 1;
|
|
3
|
-
padding: 16px;
|
|
4
|
-
overflow: auto;
|
|
3
|
+
padding: 8px 16px;
|
|
5
4
|
width: 100%;
|
|
5
|
+
height: 400px;
|
|
6
|
+
overflow-y: auto;
|
|
6
7
|
display: flex;
|
|
7
8
|
flex-direction: column;
|
|
8
9
|
}
|
|
9
10
|
|
|
10
11
|
.sdoc-files-tree .sdoc-file-info {
|
|
11
12
|
border-radius: 2px;
|
|
12
|
-
height:
|
|
13
|
-
line-height:
|
|
13
|
+
height: 32px;
|
|
14
|
+
line-height: 32px;
|
|
14
15
|
overflow: hidden;
|
|
15
16
|
text-overflow: ellipsis;
|
|
16
17
|
white-space: nowrap;
|
|
@@ -20,8 +21,7 @@
|
|
|
20
21
|
|
|
21
22
|
.sdoc-files-tree .sdoc-file-info:hover {
|
|
22
23
|
cursor: pointer;
|
|
23
|
-
background: #
|
|
24
|
-
box-shadow: inset 0 0 1px #999;
|
|
24
|
+
background-color: #f5f5f5;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
.sdoc-files-tree .sdoc-file-info .sdoc-file-icon-container {
|
|
@@ -37,13 +37,7 @@
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
.sdoc-files-tree .sdoc-file-info.active {
|
|
40
|
-
background: #
|
|
41
|
-
box-shadow: inset 0 0 1px #999;
|
|
42
|
-
color: #fff;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
.sdoc-files-tree .sdoc-file-info.active .sdoc-file-icon {
|
|
46
|
-
color: #fff;
|
|
40
|
+
background-color: #f5f5f5;
|
|
47
41
|
}
|
|
48
42
|
|
|
49
43
|
.sdoc-files-tree .sdoc-file-icon-toggle {
|
|
@@ -75,7 +75,10 @@ const ImageHoverMenu = _ref => {
|
|
|
75
75
|
centerNode = null,
|
|
76
76
|
afterNode = null;
|
|
77
77
|
let p = path[0];
|
|
78
|
-
if (!beforeLeaf.every(item =>
|
|
78
|
+
if (!beforeLeaf.every(item => {
|
|
79
|
+
var _item$text;
|
|
80
|
+
return (item === null || item === void 0 ? void 0 : (_item$text = item.text) === null || _item$text === void 0 ? void 0 : _item$text.length) === 0;
|
|
81
|
+
})) {
|
|
79
82
|
beforeNode = generateEmptyElement(PARAGRAPH);
|
|
80
83
|
beforeNode.children = beforeLeaf;
|
|
81
84
|
Transforms.insertNodes(editor, beforeNode, {
|
|
@@ -90,8 +93,8 @@ const ImageHoverMenu = _ref => {
|
|
|
90
93
|
});
|
|
91
94
|
p = p + 1;
|
|
92
95
|
if (!afterLeaf.every(item => {
|
|
93
|
-
var _item$
|
|
94
|
-
return (item === null || item === void 0 ? void 0 : (_item$
|
|
96
|
+
var _item$text2;
|
|
97
|
+
return (item === null || item === void 0 ? void 0 : (_item$text2 = item.text) === null || _item$text2 === void 0 ? void 0 : _item$text2.length) === 0;
|
|
95
98
|
})) {
|
|
96
99
|
afterNode = generateEmptyElement(PARAGRAPH);
|
|
97
100
|
afterNode.children = afterLeaf;
|
|
@@ -4,8 +4,9 @@ import { Editor, Transforms, Range, Text } 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 { SDOC_LINK, LINK, INSERT_FILE_DISPLAY_TYPE, CODE_BLOCK, CODE_LINE, PARAGRAPH } from '../../constants';
|
|
8
7
|
import { focusEditor, getNodeType, getSelectedElems } from '../../core';
|
|
8
|
+
import { LocalStorage } from '../../../../utils';
|
|
9
|
+
import { SDOC_LINK, LINK, INSERT_FILE_DISPLAY_TYPE, CODE_BLOCK, CODE_LINE, PARAGRAPH } from '../../constants';
|
|
9
10
|
export const isMenuDisabled = (editor, readonly) => {
|
|
10
11
|
if (readonly) return true;
|
|
11
12
|
if (editor.selection == null) return true;
|
|
@@ -55,12 +56,11 @@ export const insertSdocFileLink = (editor, text, uuid) => {
|
|
|
55
56
|
|
|
56
57
|
// Remove shortcut symbol,if trigger by shortcut
|
|
57
58
|
removeShortCutSymbol(editor);
|
|
59
|
+
const sdocFileNode = generateSdocFileNode(uuid, text);
|
|
58
60
|
if (isCollapsed) {
|
|
59
61
|
// Insert Spaces before and after sdoclinks for easy operation
|
|
60
62
|
editor.insertText(' ');
|
|
61
|
-
const sdocFileNode = generateSdocFileNode(uuid, text);
|
|
62
63
|
Transforms.insertNodes(editor, sdocFileNode);
|
|
63
|
-
|
|
64
64
|
// Not being able to use insertText directly causes the added Spaces to be added to the linked text, as in the issue above, replaced by insertFragment
|
|
65
65
|
editor.insertFragment([{
|
|
66
66
|
id: slugid.nice(),
|
|
@@ -71,11 +71,9 @@ export const insertSdocFileLink = (editor, text, uuid) => {
|
|
|
71
71
|
if (selectedText !== text) {
|
|
72
72
|
// If the selected text is different from the typed text, delete the text and insert the link
|
|
73
73
|
editor.deleteFragment();
|
|
74
|
-
const sdocFileNode = generateSdocFileNode(uuid, text);
|
|
75
74
|
Transforms.insertNodes(editor, sdocFileNode);
|
|
76
75
|
} else {
|
|
77
76
|
// If the selected text is the same as the entered text, only the link can be wrapped
|
|
78
|
-
const sdocFileNode = generateSdocFileNode(uuid, text);
|
|
79
77
|
Transforms.wrapNodes(editor, sdocFileNode, {
|
|
80
78
|
split: true
|
|
81
79
|
});
|
|
@@ -55,7 +55,8 @@ const withSdocLink = editor => {
|
|
|
55
55
|
if (isTriggeredByShortCut(newEditor)) {
|
|
56
56
|
eventBus.dispatch(INTERNAL_EVENT.INSERT_ELEMENT, {
|
|
57
57
|
type: ELEMENT_TYPE.SDOC_LINK,
|
|
58
|
-
insertSdocFileLinkCallback: insertSdocFileLink
|
|
58
|
+
insertSdocFileLinkCallback: insertSdocFileLink,
|
|
59
|
+
isShowHistoryFiles: true
|
|
59
60
|
});
|
|
60
61
|
}
|
|
61
62
|
return onHotKeyDown && onHotKeyDown(event);
|
package/dist/constants/index.js
CHANGED
|
@@ -16,7 +16,8 @@ export const EXTERNAL_EVENT = {
|
|
|
16
16
|
REMOVE_DOCUMENT_ERROR: 'remove_document_error',
|
|
17
17
|
NEW_NOTIFICATION: 'new_notification',
|
|
18
18
|
PARTICIPANT_ADDED: 'participant-added',
|
|
19
|
-
PARTICIPANT_REMOVED: 'participant-removed'
|
|
19
|
+
PARTICIPANT_REMOVED: 'participant-removed',
|
|
20
|
+
CREATE_SDOC_FILE: 'create_sdoc_file'
|
|
20
21
|
};
|
|
21
22
|
export const TIP_TYPE = {
|
|
22
23
|
DELETE_NO_CHANGES_REVISION: 'delete_no_changes_revision',
|
package/package.json
CHANGED
|
@@ -440,5 +440,9 @@
|
|
|
440
440
|
"Replace_all": "Replace all",
|
|
441
441
|
"Are_you_sure_to_replace_all_number_xxx_in_this_document_with_yyy": "Are you sure to replace all {{number}} '{{originalWord}}' in this document with '{{replacedWord}}'?",
|
|
442
442
|
"Are_you_sure_to_clear_all_number_xxx_in_this_document": "Are you sure to clear all {{number}} '{{originalWord}}' in this document?",
|
|
443
|
-
"Search_not_found": "Not found"
|
|
443
|
+
"Search_not_found": "Not found",
|
|
444
|
+
"Recent_previews": "Recent previews",
|
|
445
|
+
"The_document_does_not_exist": "The document does not exist",
|
|
446
|
+
"Create_a_new_sdoc_file": "Create a new sdoc file",
|
|
447
|
+
"Create": "Create"
|
|
444
448
|
}
|
|
@@ -440,5 +440,9 @@
|
|
|
440
440
|
"Replace_all": "替换全部",
|
|
441
441
|
"Are_you_sure_to_replace_all_number_xxx_in_this_document_with_yyy": "确定要将此文档内的 {{number}} 处 \"{{originalWord}} \" 替换为 \"{{replacedWord}} \" 吗?",
|
|
442
442
|
"Are_you_sure_to_clear_all_number_xxx_in_this_document": "确定将此文档内的 {{number}} 处 \"{{originalWord}}\" 全部清除吗?",
|
|
443
|
-
"Search_not_found": "未找到"
|
|
443
|
+
"Search_not_found": "未找到",
|
|
444
|
+
"Recent_previews": "最近浏览",
|
|
445
|
+
"The_document_does_not_exist": "不存在该文档",
|
|
446
|
+
"Create_a_new_sdoc_file": "新建sdoc文件",
|
|
447
|
+
"Create": "新建"
|
|
444
448
|
}
|