@seafile/sdoc-editor 1.0.170 → 1.0.172-alpha-3
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/api/seafile-api.js +2 -2
- package/dist/basic-sdk/extension/commons/file-insert-dialog/index.js +50 -48
- package/dist/basic-sdk/extension/commons/file-insert-dialog/style.css +20 -8
- package/dist/basic-sdk/extension/commons/insert-element-dialog/index.js +15 -6
- package/dist/basic-sdk/extension/commons/select-file-dialog/index.css +68 -0
- package/dist/basic-sdk/extension/commons/select-file-dialog/index.js +63 -2
- package/dist/basic-sdk/extension/commons/select-file-dialog/local-files/index.js +21 -4
- package/dist/basic-sdk/extension/commons/wiki-file-insert-dialog/index.js +274 -0
- package/dist/basic-sdk/extension/commons/wiki-file-insert-dialog/style.css +116 -0
- package/dist/basic-sdk/extension/plugins/file-link/helpers.js +1 -1
- package/dist/basic-sdk/extension/plugins/header/helpers.js +17 -1
- package/dist/basic-sdk/extension/plugins/quick-insert/helper.js +13 -2
- package/dist/basic-sdk/extension/plugins/quick-insert/render-elem.js +4 -3
- package/dist/basic-sdk/extension/plugins/sdoc-link/helpers.js +26 -1
- package/dist/basic-sdk/extension/plugins/sdoc-link/render/render-elem.js +10 -2
- package/dist/basic-sdk/extension/plugins/wiki-link/helpers.js +11 -9
- package/dist/context.js +4 -0
- package/dist/utils/index.js +20 -2
- package/package.json +1 -1
- package/public/locales/cs/sdoc-editor.json +4 -1
- package/public/locales/de/sdoc-editor.json +4 -1
- package/public/locales/en/sdoc-editor.json +4 -1
- package/public/locales/es/sdoc-editor.json +4 -1
- package/public/locales/es_AR/sdoc-editor.json +4 -1
- package/public/locales/es_MX/sdoc-editor.json +4 -1
- package/public/locales/fr/sdoc-editor.json +4 -1
- package/public/locales/it/sdoc-editor.json +4 -1
- package/public/locales/ru/sdoc-editor.json +4 -1
- package/public/locales/zh_CN/sdoc-editor.json +5 -2
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
|
|
4
|
+
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
|
|
5
|
+
Object.defineProperty(exports, "__esModule", {
|
|
6
|
+
value: true
|
|
7
|
+
});
|
|
8
|
+
exports.default = void 0;
|
|
9
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
10
|
+
var _slateReact = require("@seafile/slate-react");
|
|
11
|
+
var _reactI18next = require("react-i18next");
|
|
12
|
+
var _slate = require("@seafile/slate");
|
|
13
|
+
var _lodash = _interopRequireDefault(require("lodash.throttle"));
|
|
14
|
+
var _classnames = _interopRequireDefault(require("classnames"));
|
|
15
|
+
var _utils = require("../../../../utils");
|
|
16
|
+
var _constants = require("../../../../constants");
|
|
17
|
+
var _eventBus = _interopRequireDefault(require("../../../utils/event-bus"));
|
|
18
|
+
var _constants2 = require("../../../constants");
|
|
19
|
+
var _helpers = require("../../plugins/sdoc-link/helpers");
|
|
20
|
+
var _helpers2 = require("../../plugins/wiki-link/helpers");
|
|
21
|
+
require("./style.css");
|
|
22
|
+
const WikiFileLinkInsertDialog = _ref => {
|
|
23
|
+
let {
|
|
24
|
+
editor,
|
|
25
|
+
element,
|
|
26
|
+
closeDialog
|
|
27
|
+
} = _ref;
|
|
28
|
+
const {
|
|
29
|
+
t
|
|
30
|
+
} = (0, _reactI18next.useTranslation)();
|
|
31
|
+
const eventBus = _eventBus.default.getInstance();
|
|
32
|
+
const fileLinkInsertRef = (0, _react.useRef)(null);
|
|
33
|
+
const historyFileWrapperRef = (0, _react.useRef)(document.querySelector('.sdoc-history-files-wrapper'));
|
|
34
|
+
const [files, setFiles] = (0, _react.useState)([]);
|
|
35
|
+
const [position, setPosition] = (0, _react.useState)({});
|
|
36
|
+
const [newFileName, setNewFileName] = (0, _react.useState)('');
|
|
37
|
+
const [header, setHeader] = (0, _react.useState)(t('Link_to_page'));
|
|
38
|
+
const [hiddenMoreMenu, setHiddenMoreMenu] = (0, _react.useState)(false);
|
|
39
|
+
const deleteInputAndInsertText = (0, _react.useCallback)(function () {
|
|
40
|
+
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
41
|
+
args[_key] = arguments[_key];
|
|
42
|
+
}
|
|
43
|
+
return (0, _helpers.insertTextWhenRemoveFileNameCollector)(editor, element, ...args);
|
|
44
|
+
}, [editor, element]);
|
|
45
|
+
const getPosition = (0, _react.useCallback)(() => {
|
|
46
|
+
queueMicrotask(() => {
|
|
47
|
+
const {
|
|
48
|
+
selection
|
|
49
|
+
} = editor;
|
|
50
|
+
const nodeEntry = _slate.Editor.node(editor, selection);
|
|
51
|
+
const domNode = _slateReact.ReactEditor.toDOMNode(editor, nodeEntry[0]);
|
|
52
|
+
if (domNode) {
|
|
53
|
+
const topGap = 20;
|
|
54
|
+
const leftGap = 16;
|
|
55
|
+
const outlineWidth = 300;
|
|
56
|
+
const {
|
|
57
|
+
top: domNodeTop,
|
|
58
|
+
left: domNodeLeft
|
|
59
|
+
} = domNode.getBoundingClientRect();
|
|
60
|
+
let popoverTop = domNodeTop - topGap;
|
|
61
|
+
let popoverLeft = domNodeLeft - leftGap - outlineWidth;
|
|
62
|
+
const {
|
|
63
|
+
height
|
|
64
|
+
} = fileLinkInsertRef.current.getBoundingClientRect();
|
|
65
|
+
const popoverBottomY = popoverTop + height;
|
|
66
|
+
const viewportHeight = window.innerHeight;
|
|
67
|
+
if (popoverBottomY > viewportHeight) {
|
|
68
|
+
// 8px for the gap between the popover and the bottom of the viewport
|
|
69
|
+
const counterTopGap = 8;
|
|
70
|
+
popoverTop = popoverTop - height - topGap - counterTopGap;
|
|
71
|
+
}
|
|
72
|
+
setPosition({
|
|
73
|
+
top: popoverTop,
|
|
74
|
+
left: popoverLeft
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
}, [editor]);
|
|
79
|
+
const onClick = (0, _react.useCallback)(e => {
|
|
80
|
+
var _historyFileWrapperRe, _historyFileWrapperRe2;
|
|
81
|
+
const isClickInside = (_historyFileWrapperRe = historyFileWrapperRef.current) === null || _historyFileWrapperRe === void 0 ? void 0 : (_historyFileWrapperRe2 = _historyFileWrapperRe.contains) === null || _historyFileWrapperRe2 === void 0 ? void 0 : _historyFileWrapperRe2.call(_historyFileWrapperRe, e.target);
|
|
82
|
+
if (isClickInside) return;
|
|
83
|
+
|
|
84
|
+
// Click on the insertion position without closing
|
|
85
|
+
const insertCollectorEl = document.querySelector('.sdoc-file-name-insert-collector');
|
|
86
|
+
if (insertCollectorEl && insertCollectorEl.className === e.target.className) return;
|
|
87
|
+
deleteInputAndInsertText();
|
|
88
|
+
closeDialog();
|
|
89
|
+
}, [closeDialog, deleteInputAndInsertText]);
|
|
90
|
+
const onScroll = (0, _lodash.default)(() => {
|
|
91
|
+
getPosition();
|
|
92
|
+
}, 100);
|
|
93
|
+
const getHistoryFiles = (0, _react.useCallback)(isCalculatedByFiles => {
|
|
94
|
+
let files = _utils.LocalStorage.getItem('wiki-recent-files') || [];
|
|
95
|
+
if (isCalculatedByFiles) {
|
|
96
|
+
const newFiles = (0, _utils.getMaximumCapacity)(files);
|
|
97
|
+
// Can accommodate all without showing more operations
|
|
98
|
+
if (files.length <= newFiles.length) {
|
|
99
|
+
setHiddenMoreMenu(true);
|
|
100
|
+
}
|
|
101
|
+
files = newFiles;
|
|
102
|
+
}
|
|
103
|
+
setFiles(files);
|
|
104
|
+
}, []);
|
|
105
|
+
(0, _react.useEffect)(() => {
|
|
106
|
+
fileLinkInsertRef.current['isFirstMount'] = true;
|
|
107
|
+
getHistoryFiles(true);
|
|
108
|
+
getPosition();
|
|
109
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
110
|
+
}, []);
|
|
111
|
+
const onKeydown = (0, _react.useCallback)(e => {
|
|
112
|
+
const {
|
|
113
|
+
key
|
|
114
|
+
} = e;
|
|
115
|
+
switch (key) {
|
|
116
|
+
case 'Escape':
|
|
117
|
+
deleteInputAndInsertText();
|
|
118
|
+
closeDialog();
|
|
119
|
+
break;
|
|
120
|
+
case 'ArrowRight':
|
|
121
|
+
case 'ArrowLeft':
|
|
122
|
+
deleteInputAndInsertText();
|
|
123
|
+
closeDialog();
|
|
124
|
+
break;
|
|
125
|
+
case 'ArrowUp':
|
|
126
|
+
case 'ArrowDown':
|
|
127
|
+
deleteInputAndInsertText();
|
|
128
|
+
closeDialog();
|
|
129
|
+
break;
|
|
130
|
+
default:
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
133
|
+
}, [closeDialog, deleteInputAndInsertText]);
|
|
134
|
+
(0, _react.useEffect)(() => {
|
|
135
|
+
const sdocScrollContainer = document.getElementById('sdoc-scroll-container');
|
|
136
|
+
document.addEventListener('click', onClick);
|
|
137
|
+
document.addEventListener('keydown', onKeydown);
|
|
138
|
+
sdocScrollContainer.addEventListener('scroll', onScroll);
|
|
139
|
+
const unsubscribeCloseDialog = eventBus.subscribe(_constants2.INTERNAL_EVENT.CLOSE_FILE_INSET_DIALOG, closeDialog);
|
|
140
|
+
return () => {
|
|
141
|
+
sdocScrollContainer.removeEventListener('scroll', onScroll);
|
|
142
|
+
document.removeEventListener('click', onClick);
|
|
143
|
+
document.removeEventListener('keydown', onKeydown);
|
|
144
|
+
unsubscribeCloseDialog();
|
|
145
|
+
};
|
|
146
|
+
}, [closeDialog, editor, eventBus, files, getPosition, onClick, onKeydown, onScroll]);
|
|
147
|
+
const onSearch = (0, _react.useCallback)(searchText => {
|
|
148
|
+
if (searchText.trim().length === 0) {
|
|
149
|
+
getHistoryFiles();
|
|
150
|
+
setHiddenMoreMenu(true);
|
|
151
|
+
setHeader(t('Link_to_page'));
|
|
152
|
+
setNewFileName('');
|
|
153
|
+
getPosition();
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
const {
|
|
157
|
+
navConfig
|
|
158
|
+
} = window.wiki.config;
|
|
159
|
+
const {
|
|
160
|
+
pages
|
|
161
|
+
} = navConfig;
|
|
162
|
+
const newFiles = [];
|
|
163
|
+
pages.forEach(page => {
|
|
164
|
+
if (page.name.includes(searchText.trim())) {
|
|
165
|
+
newFiles.push(page);
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
// No results found
|
|
169
|
+
if (newFiles.length === 0) {
|
|
170
|
+
setHeader(t('No_page_results'));
|
|
171
|
+
setNewFileName(searchText);
|
|
172
|
+
} else {
|
|
173
|
+
setHeader(t('Link_to_page'));
|
|
174
|
+
setNewFileName('');
|
|
175
|
+
}
|
|
176
|
+
setHiddenMoreMenu(true);
|
|
177
|
+
setFiles(newFiles);
|
|
178
|
+
getPosition();
|
|
179
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
180
|
+
}, []);
|
|
181
|
+
(0, _react.useEffect)(() => {
|
|
182
|
+
if (!(element !== null && element !== void 0 && element.children)) return;
|
|
183
|
+
// No search on first load
|
|
184
|
+
if (fileLinkInsertRef.current['isFirstMount']) {
|
|
185
|
+
fileLinkInsertRef.current['isFirstMount'] = false;
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
const searchText = _slate.Node.string(element);
|
|
189
|
+
onSearch(searchText);
|
|
190
|
+
}, [element, onSearch]);
|
|
191
|
+
const onSelect = (0, _react.useCallback)(fileInfo => {
|
|
192
|
+
const {
|
|
193
|
+
name,
|
|
194
|
+
wikiRepoId,
|
|
195
|
+
pageId,
|
|
196
|
+
icon,
|
|
197
|
+
isDir
|
|
198
|
+
} = fileInfo;
|
|
199
|
+
(0, _helpers.removeTempInput)(editor, element);
|
|
200
|
+
closeDialog();
|
|
201
|
+
(0, _helpers2.insertWikiPageLink)(editor, name, wikiRepoId, pageId, icon, isDir);
|
|
202
|
+
}, [closeDialog, editor, element]);
|
|
203
|
+
const onShowMoreWiki = (0, _react.useCallback)(e => {
|
|
204
|
+
e.stopPropagation();
|
|
205
|
+
const recentFiles = _utils.LocalStorage.getItem('wiki-recent-files') || [];
|
|
206
|
+
setFiles(recentFiles);
|
|
207
|
+
setHiddenMoreMenu(true);
|
|
208
|
+
}, []);
|
|
209
|
+
const onCreateFile = (0, _react.useCallback)(e => {
|
|
210
|
+
e.stopPropagation();
|
|
211
|
+
(0, _helpers.removeTempInput)(editor, element);
|
|
212
|
+
const eventBus = _eventBus.default.getInstance();
|
|
213
|
+
const createName = newFileName.trim() || t('New_page');
|
|
214
|
+
eventBus.dispatch(_constants.EXTERNAL_EVENT.CREATE_WIKI_PAGE, {
|
|
215
|
+
newFileName: createName
|
|
216
|
+
});
|
|
217
|
+
}, [editor, element, newFileName, t]);
|
|
218
|
+
const createFileTipDefault = (0, _react.useMemo)(() => {
|
|
219
|
+
return 'New_page';
|
|
220
|
+
}, []);
|
|
221
|
+
const createFileName = (0, _react.useMemo)(() => {
|
|
222
|
+
return `"${newFileName}" ${t('Page')}`;
|
|
223
|
+
}, [newFileName, t]);
|
|
224
|
+
return /*#__PURE__*/_react.default.createElement("div", {
|
|
225
|
+
ref: fileLinkInsertRef,
|
|
226
|
+
className: (0, _classnames.default)('wiki-history-files-content popover'),
|
|
227
|
+
style: {
|
|
228
|
+
...position,
|
|
229
|
+
position: 'absolute',
|
|
230
|
+
opacity: Object.keys(position).length ? 1 : 0
|
|
231
|
+
}
|
|
232
|
+
}, header.length !== 0 && /*#__PURE__*/_react.default.createElement("div", {
|
|
233
|
+
className: "wiki-history-files-header"
|
|
234
|
+
}, header), /*#__PURE__*/_react.default.createElement("div", {
|
|
235
|
+
className: (0, _classnames.default)('sdoc-history-files', {
|
|
236
|
+
'no-header': header.length === 0
|
|
237
|
+
})
|
|
238
|
+
}, files.map(item => {
|
|
239
|
+
return /*#__PURE__*/_react.default.createElement("div", {
|
|
240
|
+
key: item.doc_uuid,
|
|
241
|
+
className: (0, _classnames.default)('sdoc-history-files-item', {
|
|
242
|
+
'files-item-has-dir': item === null || item === void 0 ? void 0 : item.path
|
|
243
|
+
}),
|
|
244
|
+
onClick: () => {
|
|
245
|
+
onSelect(item);
|
|
246
|
+
}
|
|
247
|
+
}, (item === null || item === void 0 ? void 0 : item.icon) && /*#__PURE__*/_react.default.createElement("span", {
|
|
248
|
+
className: "file-item-emoticons"
|
|
249
|
+
}, item.icon), !(item !== null && item !== void 0 && item.icon) && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, item !== null && item !== void 0 && item.isDir ? /*#__PURE__*/_react.default.createElement("span", {
|
|
250
|
+
className: "file-item-icon sf3-font sf3-font-files2"
|
|
251
|
+
}) : /*#__PURE__*/_react.default.createElement("span", {
|
|
252
|
+
className: "file-item-icon sf3-font sf3-font-file"
|
|
253
|
+
})), /*#__PURE__*/_react.default.createElement("span", {
|
|
254
|
+
className: "file-item-name-wrapper"
|
|
255
|
+
}, /*#__PURE__*/_react.default.createElement("span", {
|
|
256
|
+
className: "file-item-name"
|
|
257
|
+
}, item.name), (item === null || item === void 0 ? void 0 : item.path) && /*#__PURE__*/_react.default.createElement("span", {
|
|
258
|
+
className: "name-dir"
|
|
259
|
+
}, item.path)));
|
|
260
|
+
}), !hiddenMoreMenu && /*#__PURE__*/_react.default.createElement("div", {
|
|
261
|
+
className: "sdoc-history-files-item",
|
|
262
|
+
onClick: onShowMoreWiki
|
|
263
|
+
}, "...", t('More'))), /*#__PURE__*/_react.default.createElement("div", {
|
|
264
|
+
className: "sdoc-history-files-add",
|
|
265
|
+
onClick: onCreateFile
|
|
266
|
+
}, /*#__PURE__*/_react.default.createElement("i", {
|
|
267
|
+
className: "sdocfont sdoc-append"
|
|
268
|
+
}), /*#__PURE__*/_react.default.createElement("span", {
|
|
269
|
+
className: "new-file-name"
|
|
270
|
+
}, newFileName ? t('Create_file_name_sdoc', {
|
|
271
|
+
file_name_sdoc: createFileName
|
|
272
|
+
}) : t(createFileTipDefault))));
|
|
273
|
+
};
|
|
274
|
+
var _default = exports.default = WikiFileLinkInsertDialog;
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
.wiki-history-files-content {
|
|
2
|
+
display: flex;
|
|
3
|
+
flex-direction: column;
|
|
4
|
+
position: absolute;
|
|
5
|
+
width: 400px;
|
|
6
|
+
max-width: 400px;
|
|
7
|
+
max-height: 350px;
|
|
8
|
+
/* The same as hierarchy of comment drawer */
|
|
9
|
+
z-index: 103;
|
|
10
|
+
box-shadow: 0 1px 3px rgba(0, 0, 0, .15), 0 4px 8px 3px rgba(0, 0, 0, .15);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.wiki-history-files-content .wiki-history-files-header {
|
|
14
|
+
display: flex;
|
|
15
|
+
flex-shrink: 0;
|
|
16
|
+
align-items: center;
|
|
17
|
+
margin-top: 8px;
|
|
18
|
+
padding: 0px 16px;
|
|
19
|
+
height: 32px;
|
|
20
|
+
width: 100%;
|
|
21
|
+
color: #999999;
|
|
22
|
+
font-size: 14px;
|
|
23
|
+
user-select: none;
|
|
24
|
+
cursor: default;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.wiki-history-files-content .sdoc-history-files {
|
|
28
|
+
flex-grow: 1;
|
|
29
|
+
overflow-y: auto;
|
|
30
|
+
cursor: pointer;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.wiki-history-files-content .no-header {
|
|
34
|
+
margin-top: 8px;
|
|
35
|
+
width: 100%;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.wiki-history-files-content .sdoc-history-files .sdoc-history-files-item {
|
|
39
|
+
padding: 6px 16px;
|
|
40
|
+
height: 32px;
|
|
41
|
+
font-size: 14px;
|
|
42
|
+
display: flex;
|
|
43
|
+
align-items: flex-start;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.wiki-history-files-content .sdoc-history-files .sdoc-history-files-item .file-item-icon {
|
|
47
|
+
font-size: 16px;
|
|
48
|
+
margin-right: 8px;
|
|
49
|
+
color: #666666;
|
|
50
|
+
width: 20px;
|
|
51
|
+
height: 20px;
|
|
52
|
+
display: flex;
|
|
53
|
+
justify-content: center;
|
|
54
|
+
align-items: center;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.wiki-history-files-content .sdoc-history-files .sdoc-history-files-item .file-item-name {
|
|
58
|
+
white-space: nowrap;
|
|
59
|
+
text-overflow: ellipsis;
|
|
60
|
+
overflow: hidden;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.wiki-history-files-content .sdoc-history-files .sdoc-history-files-item:hover {
|
|
64
|
+
background-color: #f5f5f5;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.wiki-history-files-content .sdoc-history-files-add {
|
|
68
|
+
display: flex;
|
|
69
|
+
flex-shrink: 0;
|
|
70
|
+
align-items: center;
|
|
71
|
+
padding: 0px 16px;
|
|
72
|
+
height: 32px;
|
|
73
|
+
width: 100%;
|
|
74
|
+
border-top: 1px solid #e9ecef;
|
|
75
|
+
font-size: 14px;
|
|
76
|
+
cursor: pointer;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.wiki-history-files-content .sdoc-history-files-add :first-child {
|
|
80
|
+
color: #444444;
|
|
81
|
+
margin-right: 10px;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.wiki-history-files-content .sdoc-history-files-add .new-file-name {
|
|
85
|
+
text-wrap: nowrap;
|
|
86
|
+
text-overflow: ellipsis;
|
|
87
|
+
overflow: hidden;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.wiki-history-files-content .sdoc-history-files .sdoc-history-files-item.files-item-has-dir {
|
|
91
|
+
height: 51px;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.wiki-history-files-content .sdoc-history-files .sdoc-history-files-item .file-item-emoticons {
|
|
95
|
+
font-size: 14px;
|
|
96
|
+
margin-right: 8px;
|
|
97
|
+
width: 20px;
|
|
98
|
+
height: 20px;
|
|
99
|
+
display: flex;
|
|
100
|
+
justify-content: center;
|
|
101
|
+
align-items: center;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.wiki-history-files-content .sdoc-history-files .sdoc-history-files-item .file-item-name-wrapper {
|
|
105
|
+
display: flex;
|
|
106
|
+
flex-direction: column;
|
|
107
|
+
overflow: hidden;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
.wiki-history-files-content .sdoc-history-files .sdoc-history-files-item .file-item-name-wrapper .name-dir {
|
|
111
|
+
color: #666;
|
|
112
|
+
font-size: 12px;
|
|
113
|
+
white-space: nowrap;
|
|
114
|
+
text-overflow: ellipsis;
|
|
115
|
+
overflow: hidden;
|
|
116
|
+
}
|
|
@@ -21,7 +21,7 @@ const isMenuDisabled = (editor, readonly) => {
|
|
|
21
21
|
type
|
|
22
22
|
} = elem;
|
|
23
23
|
if (editor.isVoid(elem)) return true;
|
|
24
|
-
if ([_constants.CODE_BLOCK, _constants.CODE_LINE, _constants.LINK].includes(type)) return true;
|
|
24
|
+
if ([_constants.CODE_BLOCK, _constants.CODE_LINE, _constants.LINK, ..._constants.HEADERS].includes(type)) return true;
|
|
25
25
|
return false;
|
|
26
26
|
});
|
|
27
27
|
if (notMatch) return true; // disabled
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.setHeaderType = exports.isMenuDisabled = exports.getHeaderType = void 0;
|
|
6
|
+
exports.setHeaderType = exports.isSelectionInHeader = exports.isMenuDisabled = exports.getHeaderType = void 0;
|
|
7
7
|
var _slate = require("@seafile/slate");
|
|
8
8
|
var _core = require("../../core");
|
|
9
9
|
var _constants = require("../../constants");
|
|
@@ -44,6 +44,22 @@ const getHeaderType = editor => {
|
|
|
44
44
|
return (0, _core.getNodeType)(n);
|
|
45
45
|
};
|
|
46
46
|
exports.getHeaderType = getHeaderType;
|
|
47
|
+
const isSelectionInHeader = editor => {
|
|
48
|
+
const [match] = _slate.Editor.nodes(editor, {
|
|
49
|
+
match: n => {
|
|
50
|
+
if (!_slate.Element.isElement(n)) return false;
|
|
51
|
+
if (!n.type) return false;
|
|
52
|
+
if (n.type.startsWith(_constants.HEADER)) return true;
|
|
53
|
+
if (n.type === _constants.TITLE) return true;
|
|
54
|
+
if (n.type === _constants.SUBTITLE) return true;
|
|
55
|
+
return false;
|
|
56
|
+
},
|
|
57
|
+
// Matches nodes whose node.type starts with header
|
|
58
|
+
universal: true
|
|
59
|
+
});
|
|
60
|
+
return match;
|
|
61
|
+
};
|
|
62
|
+
exports.isSelectionInHeader = isSelectionInHeader;
|
|
47
63
|
const setHeaderType = (editor, type) => {
|
|
48
64
|
if (!type) return;
|
|
49
65
|
_slate.Transforms.setNodes(editor, {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.transformToText = exports.getQuickInsertEntity = exports.genQuickInsert = void 0;
|
|
6
|
+
exports.transformToText = exports.isSelectionSameWithInsert = exports.getQuickInsertEntity = exports.genQuickInsert = void 0;
|
|
7
7
|
var _slate = require("@seafile/slate");
|
|
8
8
|
var _constants = require("../../constants");
|
|
9
9
|
var _core = require("../../core");
|
|
@@ -37,4 +37,15 @@ const transformToText = (editor, quickInsertNode) => {
|
|
|
37
37
|
});
|
|
38
38
|
return insertPathRef.unref();
|
|
39
39
|
};
|
|
40
|
-
exports.transformToText = transformToText;
|
|
40
|
+
exports.transformToText = transformToText;
|
|
41
|
+
const isSelectionSameWithInsert = (editor, element) => {
|
|
42
|
+
if (!editor.selection) return;
|
|
43
|
+
if (!_slate.Range.isCollapsed(editor.selection)) return;
|
|
44
|
+
const {
|
|
45
|
+
anchor
|
|
46
|
+
} = editor.selection;
|
|
47
|
+
const path = _slateReact.ReactEditor.findPath(editor, element);
|
|
48
|
+
const lastPoint = _slate.Editor.end(editor, path);
|
|
49
|
+
return _slate.Point.equals(anchor, lastPoint);
|
|
50
|
+
};
|
|
51
|
+
exports.isSelectionSameWithInsert = isSelectionSameWithInsert;
|
|
@@ -32,6 +32,7 @@ const RenderQuickInsert = (_ref, editor, readonly) => {
|
|
|
32
32
|
const insertElmRef = (0, _react.useRef)(null);
|
|
33
33
|
const aboveBlockNode = (0, _core.getAboveBlockNode)(editor);
|
|
34
34
|
const isEmptyNode = (0, _helpers.isVoidNode)(aboveBlockNode === null || aboveBlockNode === void 0 ? void 0 : aboveBlockNode[0]);
|
|
35
|
+
const [isShowPopover] = (0, _react.useState)((0, _helper.isSelectionSameWithInsert)(editor, element));
|
|
35
36
|
const handleClick = (0, _react.useCallback)(e => {
|
|
36
37
|
// Click the search input
|
|
37
38
|
if (sideMenuRef.current.contains(e.target) && e.target.tagName === 'INPUT') return;
|
|
@@ -40,7 +41,6 @@ const RenderQuickInsert = (_ref, editor, readonly) => {
|
|
|
40
41
|
}
|
|
41
42
|
}, [editor, element]);
|
|
42
43
|
const genStyle = (0, _react.useCallback)((top, left) => {
|
|
43
|
-
if (editor.isRemote) return null;
|
|
44
44
|
const overflowY = top + sideMenuRef.current.offsetHeight - document.body.clientHeight;
|
|
45
45
|
if (overflowY > 0) {
|
|
46
46
|
top = top - overflowY - 10;
|
|
@@ -50,7 +50,7 @@ const RenderQuickInsert = (_ref, editor, readonly) => {
|
|
|
50
50
|
left = sideMenuRef.current.offsetWidth + 10;
|
|
51
51
|
}
|
|
52
52
|
return `top: ${top}px; left: ${left}px`;
|
|
53
|
-
}, [
|
|
53
|
+
}, []);
|
|
54
54
|
const handleInsertMenuStyle = (0, _react.useCallback)(() => {
|
|
55
55
|
const currentDom = _slateReact.ReactEditor.toDOMNode(editor, element);
|
|
56
56
|
const {
|
|
@@ -65,6 +65,7 @@ const RenderQuickInsert = (_ref, editor, readonly) => {
|
|
|
65
65
|
}, [handleInsertMenuStyle]);
|
|
66
66
|
(0, _react.useEffect)(() => {
|
|
67
67
|
if (readonly) return;
|
|
68
|
+
if (!sideMenuRef.current) return;
|
|
68
69
|
const scrollDom = scrollRef.current;
|
|
69
70
|
handleInsertMenuStyle();
|
|
70
71
|
document.addEventListener('click', handleClick);
|
|
@@ -83,7 +84,7 @@ const RenderQuickInsert = (_ref, editor, readonly) => {
|
|
|
83
84
|
ref: insertElmRef
|
|
84
85
|
}, /*#__PURE__*/_react.default.createElement("span", Object.assign({}, attributes, {
|
|
85
86
|
className: ""
|
|
86
|
-
}), /*#__PURE__*/_react.default.createElement(_InlineBugFixWrapper.default, null), /*#__PURE__*/_react.default.createElement("span", null, "/", children), /*#__PURE__*/_react.default.createElement(_InlineBugFixWrapper.default, null), !readonly && /*#__PURE__*/_react.default.createElement(_commons.ElementPopover, {
|
|
87
|
+
}), /*#__PURE__*/_react.default.createElement(_InlineBugFixWrapper.default, null), /*#__PURE__*/_react.default.createElement("span", null, "/", children), /*#__PURE__*/_react.default.createElement(_InlineBugFixWrapper.default, null), !readonly && isShowPopover && /*#__PURE__*/_react.default.createElement(_commons.ElementPopover, {
|
|
87
88
|
className: "sdoc-side-menu-popover",
|
|
88
89
|
style: menuStyle
|
|
89
90
|
}, /*#__PURE__*/_react.default.createElement("div", {
|
|
@@ -12,6 +12,7 @@ var _copyToClipboard = _interopRequireDefault(require("copy-to-clipboard"));
|
|
|
12
12
|
var _context = _interopRequireDefault(require("../../../../context"));
|
|
13
13
|
var _core = require("../../core");
|
|
14
14
|
var _constants = require("../../constants");
|
|
15
|
+
var _helpers = require("../header/helpers");
|
|
15
16
|
const isMenuDisabled = (editor, readonly) => {
|
|
16
17
|
if (readonly) return true;
|
|
17
18
|
if (editor.selection == null) return true;
|
|
@@ -21,7 +22,7 @@ const isMenuDisabled = (editor, readonly) => {
|
|
|
21
22
|
type
|
|
22
23
|
} = elem;
|
|
23
24
|
if (editor.isVoid(elem)) return true;
|
|
24
|
-
if ([_constants.CODE_BLOCK, _constants.CODE_LINE, _constants.LINK].includes(type)) return true;
|
|
25
|
+
if ([_constants.CODE_BLOCK, _constants.CODE_LINE, _constants.LINK, ..._constants.HEADERS].includes(type)) return true;
|
|
25
26
|
return false;
|
|
26
27
|
});
|
|
27
28
|
if (notMatch) return true; // disabled
|
|
@@ -68,6 +69,27 @@ const insertSdocFileLink = (editor, text, uuid) => {
|
|
|
68
69
|
removeShortCutSymbol(editor);
|
|
69
70
|
const sdocFileNode = generateSdocFileNode(uuid, text);
|
|
70
71
|
if (isCollapsed) {
|
|
72
|
+
const {
|
|
73
|
+
anchor,
|
|
74
|
+
focus
|
|
75
|
+
} = editor.selection;
|
|
76
|
+
const [targetNode] = _slate.Editor.node(editor, editor.selection, {
|
|
77
|
+
depth: 2
|
|
78
|
+
}) || [];
|
|
79
|
+
|
|
80
|
+
// When the current cursor position is on a link, change the position to after the link
|
|
81
|
+
if (targetNode && targetNode.type === _constants.SDOC_LINK && anchor.path.length === 3) {
|
|
82
|
+
editor.selection = {
|
|
83
|
+
anchor: {
|
|
84
|
+
offset: anchor.offset,
|
|
85
|
+
path: [anchor.path[0], anchor.path[1] + 1]
|
|
86
|
+
},
|
|
87
|
+
focus: {
|
|
88
|
+
offset: focus.offset,
|
|
89
|
+
path: [focus.path[0], focus.path[1] + 1]
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
}
|
|
71
93
|
_slate.Transforms.insertNodes(editor, sdocFileNode);
|
|
72
94
|
} else {
|
|
73
95
|
const selectedText = _slate.Editor.string(editor, selection); // Selected text
|
|
@@ -157,6 +179,9 @@ const getBeforeText = editor => {
|
|
|
157
179
|
};
|
|
158
180
|
exports.getBeforeText = getBeforeText;
|
|
159
181
|
const isTriggeredByShortcut = editor => {
|
|
182
|
+
if ((0, _helpers.isSelectionInHeader)(editor)) {
|
|
183
|
+
return false;
|
|
184
|
+
}
|
|
160
185
|
const {
|
|
161
186
|
beforeText
|
|
162
187
|
} = getBeforeText(editor);
|
|
@@ -25,6 +25,10 @@ const SdocFileLink = _ref => {
|
|
|
25
25
|
children,
|
|
26
26
|
attributes
|
|
27
27
|
} = _ref;
|
|
28
|
+
const {
|
|
29
|
+
icon,
|
|
30
|
+
isDir
|
|
31
|
+
} = element;
|
|
28
32
|
const sdocFileRef = (0, _react.useRef)(null);
|
|
29
33
|
const scrollRef = (0, _useScrollContext.useScrollContext)();
|
|
30
34
|
const [isShowInsertHoverMenu, setIsShowInsertHoverMenu] = (0, _react.useState)(false);
|
|
@@ -134,9 +138,13 @@ const SdocFileLink = _ref => {
|
|
|
134
138
|
}, [_constants2.SDOC_LINK_TYPE.ICON_LINK, _constants2.SDOC_LINK_TYPE.CARD_LINK].includes(element.display_type) && /*#__PURE__*/_react.default.createElement("span", {
|
|
135
139
|
className: "sdoc-file-link-icon",
|
|
136
140
|
style: style
|
|
137
|
-
}, /*#__PURE__*/_react.default.createElement("i", {
|
|
141
|
+
}, element.type !== _elementType.WIKI_LINK && /*#__PURE__*/_react.default.createElement("i", {
|
|
138
142
|
className: "sdocfont sdoc-document"
|
|
139
|
-
})), /*#__PURE__*/_react.default.createElement("span", {
|
|
143
|
+
}), element.type === _elementType.WIKI_LINK && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, icon && /*#__PURE__*/_react.default.createElement("span", null, icon), !icon && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, isDir ? /*#__PURE__*/_react.default.createElement("span", {
|
|
144
|
+
className: "sf3-font sf3-font-files2"
|
|
145
|
+
}) : /*#__PURE__*/_react.default.createElement("span", {
|
|
146
|
+
className: "sf3-font sf3-font-file"
|
|
147
|
+
})))), /*#__PURE__*/_react.default.createElement("span", {
|
|
140
148
|
className: 'sdoc-file-text-link',
|
|
141
149
|
style: style
|
|
142
150
|
}, /*#__PURE__*/_react.default.createElement("a", {
|
|
@@ -4,13 +4,13 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
|
|
|
4
4
|
Object.defineProperty(exports, "__esModule", {
|
|
5
5
|
value: true
|
|
6
6
|
});
|
|
7
|
-
exports.insertWikiPageLink = exports.getWikiUrl = exports.
|
|
7
|
+
exports.insertWikiPageLink = exports.getWikiUrl = exports.generateWikiFileNode = void 0;
|
|
8
8
|
var _slate = require("@seafile/slate");
|
|
9
9
|
var _slugid = _interopRequireDefault(require("slugid"));
|
|
10
10
|
var _constants = require("../../constants");
|
|
11
11
|
var _helpers = require("../sdoc-link/helpers");
|
|
12
12
|
var _elementType = require("../../constants/element-type");
|
|
13
|
-
const insertWikiPageLink = (editor, text, wikiRepoId, pageId) => {
|
|
13
|
+
const insertWikiPageLink = (editor, text, wikiRepoId, pageId, icon, isDir) => {
|
|
14
14
|
if ((0, _helpers.isMenuDisabled)(editor)) return;
|
|
15
15
|
// Selection folded or not
|
|
16
16
|
const {
|
|
@@ -21,7 +21,7 @@ const insertWikiPageLink = (editor, text, wikiRepoId, pageId) => {
|
|
|
21
21
|
|
|
22
22
|
// Remove shortcut symbol,if trigger by shortcut
|
|
23
23
|
(0, _helpers.removeShortCutSymbol)(editor);
|
|
24
|
-
const wikiLinkNode =
|
|
24
|
+
const wikiLinkNode = generateWikiFileNode(wikiRepoId, pageId, text, icon, isDir);
|
|
25
25
|
if (isCollapsed) {
|
|
26
26
|
_slate.Transforms.insertNodes(editor, wikiLinkNode);
|
|
27
27
|
} else {
|
|
@@ -42,14 +42,18 @@ const insertWikiPageLink = (editor, text, wikiRepoId, pageId) => {
|
|
|
42
42
|
}
|
|
43
43
|
};
|
|
44
44
|
exports.insertWikiPageLink = insertWikiPageLink;
|
|
45
|
-
const
|
|
45
|
+
const generateWikiFileNode = function (wikiRepoId, pageId) {
|
|
46
46
|
let title = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '';
|
|
47
|
+
let icon = arguments.length > 3 ? arguments[3] : undefined;
|
|
48
|
+
let isDir = arguments.length > 4 ? arguments[4] : undefined;
|
|
47
49
|
const wikiPageLinkNode = {
|
|
48
50
|
id: _slugid.default.nice(),
|
|
49
51
|
type: _elementType.WIKI_LINK,
|
|
50
52
|
wiki_repo_id: wikiRepoId,
|
|
51
53
|
page_id: pageId,
|
|
52
54
|
title: title,
|
|
55
|
+
icon,
|
|
56
|
+
isDir,
|
|
53
57
|
display_type: _constants.INSERT_FILE_DISPLAY_TYPE[1],
|
|
54
58
|
children: [{
|
|
55
59
|
id: _slugid.default.nice(),
|
|
@@ -58,13 +62,11 @@ const generateSdocFileNode = function (wikiRepoId, pageId) {
|
|
|
58
62
|
};
|
|
59
63
|
return wikiPageLinkNode;
|
|
60
64
|
};
|
|
61
|
-
exports.
|
|
65
|
+
exports.generateWikiFileNode = generateWikiFileNode;
|
|
62
66
|
const getWikiUrl = (wikiRepoId, pageId) => {
|
|
63
67
|
const {
|
|
64
|
-
origin
|
|
65
|
-
pathname
|
|
68
|
+
origin
|
|
66
69
|
} = window.location;
|
|
67
|
-
|
|
68
|
-
return `${origin}${pathName}?page_id=${pageId}`;
|
|
70
|
+
return `${origin}/wikis/${wikiRepoId}/?page_id=${pageId}`;
|
|
69
71
|
};
|
|
70
72
|
exports.getWikiUrl = getWikiUrl;
|
package/dist/context.js
CHANGED
|
@@ -199,6 +199,10 @@ class Context {
|
|
|
199
199
|
const docUuid = this.getSetting('docUuid');
|
|
200
200
|
return this.api.getSdocFiles(docUuid, p, type);
|
|
201
201
|
}
|
|
202
|
+
getSearchFilesByFilename(query, page, per_page, search_type) {
|
|
203
|
+
const docUuid = this.getSetting('docUuid');
|
|
204
|
+
return this.api.searchFilesByFilename(docUuid, query, page, per_page, search_type);
|
|
205
|
+
}
|
|
202
206
|
getSdocLocalFileId(p) {
|
|
203
207
|
const docUuid = this.getSetting('docUuid');
|
|
204
208
|
return this.api.getSdocFileId(docUuid, p);
|