@seafile/sdoc-editor 0.1.125 → 0.1.127
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/comment/comment/editor-comment.js +11 -2
- package/dist/basic-sdk/comment/comment/style.css +1 -0
- package/dist/basic-sdk/constants/index.js +2 -1
- package/dist/basic-sdk/editor.js +2 -1
- package/dist/basic-sdk/extension/constants/index.js +71 -0
- package/dist/basic-sdk/extension/index.js +2 -2
- package/dist/basic-sdk/extension/plugins/blockquote/render-elem.js +2 -1
- package/dist/basic-sdk/extension/plugins/check-list/index.js +2 -2
- package/dist/basic-sdk/extension/plugins/check-list/render-elem.js +7 -10
- package/dist/basic-sdk/extension/plugins/code-block/render-elem.js +8 -9
- package/dist/basic-sdk/extension/plugins/header/render-elem.js +2 -2
- package/dist/basic-sdk/extension/plugins/link/menu/add-link-dialog.js +7 -2
- package/dist/basic-sdk/extension/plugins/list/render-elem.js +3 -1
- package/dist/basic-sdk/extension/plugins/paragraph/render-elem.js +2 -1
- package/dist/basic-sdk/extension/plugins/sdoc-link/dialogs/select-sdoc-file-dialog/index.css +55 -0
- package/dist/basic-sdk/extension/plugins/sdoc-link/{menu/sdoc-link-file-dialog.js → dialogs/select-sdoc-file-dialog/index.js} +36 -29
- package/dist/basic-sdk/extension/plugins/sdoc-link/dialogs/select-sdoc-file-dialog/local-files/index.css +75 -0
- package/dist/basic-sdk/extension/plugins/sdoc-link/{menu/local-files.js → dialogs/select-sdoc-file-dialog/local-files/index.js} +42 -32
- package/dist/basic-sdk/extension/plugins/sdoc-link/{menu/sdoc-link-hover-menu.js → hover-menu/index.js} +1 -1
- package/dist/basic-sdk/extension/plugins/sdoc-link/menu/index.js +3 -3
- package/dist/basic-sdk/extension/plugins/sdoc-link/render-elem.js +2 -2
- package/dist/basic-sdk/extension/plugins/table/popover/table-size-popover/index.js +11 -4
- package/dist/basic-sdk/extension/plugins/table/render/table-root.js +1 -0
- package/dist/basic-sdk/extension/render/render-element.js +20 -7
- package/dist/basic-sdk/extension/toolbar/index.js +2 -1
- package/dist/basic-sdk/extension/toolbar/side-toolbar/helpers.js +121 -0
- package/dist/basic-sdk/extension/toolbar/side-toolbar/index.css +24 -0
- package/dist/basic-sdk/extension/toolbar/side-toolbar/index.js +123 -0
- package/dist/basic-sdk/extension/toolbar/side-toolbar/insert-below-menu.js +23 -0
- package/dist/basic-sdk/extension/toolbar/side-toolbar/insert-block-menu.js +95 -0
- package/dist/basic-sdk/extension/toolbar/side-toolbar/side-menu-item.js +35 -0
- package/dist/basic-sdk/extension/toolbar/side-toolbar/side-menu.css +64 -0
- package/dist/basic-sdk/extension/toolbar/side-toolbar/side-menu.js +76 -0
- package/dist/basic-sdk/extension/toolbar/side-toolbar/transform-menus.js +41 -0
- package/dist/basic-sdk/layout/article-container.js +3 -2
- package/dist/basic-sdk/outline/index.js +6 -6
- package/dist/basic-sdk/socket/socket-client.js +1 -1
- package/dist/basic-sdk/socket/socket-manager.js +0 -4
- package/package.json +1 -1
- package/public/locales/en/sdoc-editor.json +7 -1
- package/public/locales/zh-CN/sdoc-editor.json +8 -1
- package/dist/basic-sdk/extension/plugins/sdoc-link/menu/local-files.css +0 -98
- package/dist/basic-sdk/extension/plugins/sdoc-link/menu/sdoc-link-file-dialog.css +0 -35
- /package/dist/basic-sdk/extension/plugins/sdoc-link/{menu/sdoc-link-hover-menu.css → hover-menu/index.css} +0 -0
|
@@ -2,12 +2,13 @@ import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
|
|
|
2
2
|
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
|
3
3
|
import React, { useCallback, useState, useRef, useEffect } from 'react';
|
|
4
4
|
import { withTranslation } from 'react-i18next';
|
|
5
|
+
import classnames from 'classnames';
|
|
5
6
|
import slugid from 'slugid';
|
|
6
|
-
import context from '
|
|
7
|
-
import { getErrorMsg } from '
|
|
8
|
-
import toaster from '
|
|
9
|
-
import { getParentPathNameArr, getNewFileListData } from '
|
|
10
|
-
import './
|
|
7
|
+
import context from '../../../../../../../context';
|
|
8
|
+
import { getErrorMsg } from '../../../../../../../utils';
|
|
9
|
+
import toaster from '../../../../../../../components/toast';
|
|
10
|
+
import { getParentPathNameArr, getNewFileListData } from '../../../helpers';
|
|
11
|
+
import './index.css';
|
|
11
12
|
var LocalFiles = function LocalFiles(_ref) {
|
|
12
13
|
var onSelectedFile = _ref.onSelectedFile,
|
|
13
14
|
toggle = _ref.toggle,
|
|
@@ -72,6 +73,7 @@ var LocalFiles = function LocalFiles(_ref) {
|
|
|
72
73
|
getFileData(p, item.indexId, fileListData);
|
|
73
74
|
expandedFolder.add(item.indexId);
|
|
74
75
|
}
|
|
76
|
+
onSelectedFile(null);
|
|
75
77
|
setCurrentActiveItem(item);
|
|
76
78
|
setExpandedFolder(new Set(Array.from(expandedFolder)));
|
|
77
79
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
@@ -83,51 +85,59 @@ var LocalFiles = function LocalFiles(_ref) {
|
|
|
83
85
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
84
86
|
}, []);
|
|
85
87
|
var renderFileTree = useCallback(function (data) {
|
|
86
|
-
if (!Array.isArray(data))
|
|
87
|
-
return null;
|
|
88
|
-
}
|
|
88
|
+
if (!Array.isArray(data) || data.length === 0) return null;
|
|
89
89
|
return data.map(function (item) {
|
|
90
90
|
var _item$children, _item$children2;
|
|
91
|
+
if (!item) return null;
|
|
92
|
+
var type = item.type,
|
|
93
|
+
indexId = item.indexId,
|
|
94
|
+
name = item.name;
|
|
95
|
+
var selected = (currentActiveItem === null || currentActiveItem === void 0 ? void 0 : currentActiveItem.indexId) === indexId;
|
|
91
96
|
return /*#__PURE__*/React.createElement("div", {
|
|
92
|
-
key:
|
|
93
|
-
className: "sdoc-
|
|
94
|
-
},
|
|
97
|
+
key: indexId,
|
|
98
|
+
className: "sdoc-folder-container"
|
|
99
|
+
}, type === 'dir' && /*#__PURE__*/React.createElement("div", {
|
|
95
100
|
ref: folderRef,
|
|
96
|
-
className: "sdoc-
|
|
101
|
+
className: "sdoc-folder"
|
|
102
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
103
|
+
className: classnames('sdoc-folder-info sdoc-file-info', {
|
|
104
|
+
'active': selected,
|
|
105
|
+
'expanded': expandedFolder.has(indexId)
|
|
106
|
+
}),
|
|
97
107
|
onClick: function onClick(e) {
|
|
98
|
-
onToggle(e, item, fileListData);
|
|
108
|
+
return onToggle(e, item, fileListData);
|
|
99
109
|
}
|
|
100
110
|
}, /*#__PURE__*/React.createElement("div", {
|
|
101
|
-
className: "sdoc-
|
|
102
|
-
}, /*#__PURE__*/React.createElement("span", {
|
|
103
|
-
className: "".concat(expandedFolder.has(item.indexId) ? 'icon-drop-down-scale' : '')
|
|
111
|
+
className: "sdoc-file-icon-container"
|
|
104
112
|
}, /*#__PURE__*/React.createElement("i", {
|
|
105
|
-
className: "
|
|
106
|
-
})
|
|
107
|
-
className: "sdocfont sdoc-file"
|
|
113
|
+
className: "sdoc-file-icon sdoc-file-icon-toggle sdocfont sdoc-right-slide"
|
|
114
|
+
}), /*#__PURE__*/React.createElement("i", {
|
|
115
|
+
className: "sdoc-file-icon sdocfont sdoc-file sdoc-folder-icon"
|
|
108
116
|
})), /*#__PURE__*/React.createElement("span", {
|
|
109
|
-
className: "sdoc-folder-name"
|
|
110
|
-
},
|
|
111
|
-
className: "sdoc-
|
|
112
|
-
}, (
|
|
113
|
-
className: "sdoc-
|
|
114
|
-
}, t('Empty')), (
|
|
115
|
-
className:
|
|
117
|
+
className: "sdoc-folder-name sdoc-file-name"
|
|
118
|
+
}, name)), /*#__PURE__*/React.createElement("div", {
|
|
119
|
+
className: "sdoc-folder-children"
|
|
120
|
+
}, ((_item$children = item.children) === null || _item$children === void 0 ? void 0 : _item$children.length) === 0 && /*#__PURE__*/React.createElement("div", {
|
|
121
|
+
className: "sdoc-folder-children-empty"
|
|
122
|
+
}, "(".concat(t('Empty'), ")")), ((_item$children2 = item.children) === null || _item$children2 === void 0 ? void 0 : _item$children2.length) > 0 && renderFileTree(item.children))), type === 'file' && /*#__PURE__*/React.createElement("div", {
|
|
123
|
+
className: classnames('sdoc-file-info', {
|
|
124
|
+
'active': selected
|
|
125
|
+
}),
|
|
116
126
|
onClick: function onClick(e) {
|
|
117
127
|
onSelectFile(e, item);
|
|
118
128
|
}
|
|
119
|
-
}, /*#__PURE__*/React.createElement("
|
|
120
|
-
className: "sdoc-
|
|
129
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
130
|
+
className: "sdoc-file-icon-container"
|
|
121
131
|
}, /*#__PURE__*/React.createElement("i", {
|
|
122
|
-
className: "sdocfont sdoc-document"
|
|
132
|
+
className: "sdoc-file-icon sdocfont sdoc-document"
|
|
123
133
|
})), /*#__PURE__*/React.createElement("span", {
|
|
124
|
-
className: "sdoc-
|
|
125
|
-
},
|
|
134
|
+
className: "sdoc-file-name"
|
|
135
|
+
}, name)));
|
|
126
136
|
});
|
|
127
137
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
128
138
|
}, [fileListData, currentActiveItem, expandedFolder]);
|
|
129
139
|
return /*#__PURE__*/React.createElement("div", {
|
|
130
|
-
className: "sdoc-
|
|
140
|
+
className: "sdoc-files-tree"
|
|
131
141
|
}, renderFileTree(fileListData));
|
|
132
142
|
};
|
|
133
143
|
export default withTranslation('sdoc-editor')(LocalFiles);
|
|
@@ -6,7 +6,7 @@ import { withTranslation } from 'react-i18next';
|
|
|
6
6
|
import { ElementPopover } from '../../../commons';
|
|
7
7
|
import toaster from '../../../../../components/toast';
|
|
8
8
|
import { getUrl, onCopySdocLinkNode } from '../helpers';
|
|
9
|
-
import './
|
|
9
|
+
import './index.css';
|
|
10
10
|
var SdocLinkHoverMenu = function SdocLinkHoverMenu(_ref) {
|
|
11
11
|
var editor = _ref.editor,
|
|
12
12
|
menuPosition = _ref.menuPosition,
|
|
@@ -5,7 +5,7 @@ import { withTranslation } from 'react-i18next';
|
|
|
5
5
|
import { SDOC_LINK, MENUS_CONFIG_MAP } from '../../../constants';
|
|
6
6
|
import { MenuItem } from '../../../commons';
|
|
7
7
|
import { getType, isMenuDisabled } from '../helpers';
|
|
8
|
-
import
|
|
8
|
+
import SelectSdocFileDialog from '../dialogs/select-sdoc-file-dialog';
|
|
9
9
|
import './index.css';
|
|
10
10
|
var SdocLinkMenu = function SdocLinkMenu(_ref) {
|
|
11
11
|
var isRichEditor = _ref.isRichEditor,
|
|
@@ -77,9 +77,9 @@ var SdocLinkMenu = function SdocLinkMenu(_ref) {
|
|
|
77
77
|
onMouseDown: onInsertSdocFile
|
|
78
78
|
}, /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement("i", {
|
|
79
79
|
className: "sdocfont sdoc-document"
|
|
80
|
-
})), /*#__PURE__*/React.createElement("span", null, t('Sdoc_document')))), showInsertDialog && /*#__PURE__*/React.createElement(
|
|
80
|
+
})), /*#__PURE__*/React.createElement("span", null, t('Sdoc_document')))), showInsertDialog && /*#__PURE__*/React.createElement(SelectSdocFileDialog, {
|
|
81
81
|
editor: editor,
|
|
82
|
-
|
|
82
|
+
toggle: onDialogToggle
|
|
83
83
|
}));
|
|
84
84
|
};
|
|
85
85
|
export default withTranslation('sdoc-editor')(SdocLinkMenu);
|
|
@@ -3,7 +3,7 @@ import React, { useCallback, useEffect, useState, useRef } from 'react';
|
|
|
3
3
|
import { Range } from '@seafile/slate';
|
|
4
4
|
import { useScrollContext } from '../../../hooks/use-scroll-context';
|
|
5
5
|
import { unwrapLinkNode, getUrl } from './helpers';
|
|
6
|
-
import
|
|
6
|
+
import HoverMenu from './hover-menu';
|
|
7
7
|
import './render-elem.css';
|
|
8
8
|
var SdocFileLink = function SdocFileLink(_ref) {
|
|
9
9
|
var editor = _ref.editor,
|
|
@@ -104,7 +104,7 @@ var SdocFileLink = function SdocFileLink(_ref) {
|
|
|
104
104
|
e.preventDefault();
|
|
105
105
|
},
|
|
106
106
|
title: element.title
|
|
107
|
-
}, children))), isShowInsertHoverMenu && Range.isCollapsed(editor.selection) && /*#__PURE__*/React.createElement(
|
|
107
|
+
}, children))), isShowInsertHoverMenu && Range.isCollapsed(editor.selection) && /*#__PURE__*/React.createElement(HoverMenu, {
|
|
108
108
|
editor: editor,
|
|
109
109
|
menuPosition: menuPosition,
|
|
110
110
|
element: element,
|
|
@@ -106,15 +106,22 @@ var TableSizePopover = /*#__PURE__*/function (_Component) {
|
|
|
106
106
|
var _this$state2 = this.state,
|
|
107
107
|
selectedSize = _this$state2.selectedSize,
|
|
108
108
|
isShowCustomSizeDialog = _this$state2.isShowCustomSizeDialog;
|
|
109
|
-
var
|
|
109
|
+
var _this$props = this.props,
|
|
110
|
+
_this$props$trigger = _this$props.trigger,
|
|
111
|
+
trigger = _this$props$trigger === void 0 ? 'legacy' : _this$props$trigger,
|
|
112
|
+
_this$props$placement = _this$props.placement,
|
|
113
|
+
placement = _this$props$placement === void 0 ? 'bottom-start' : _this$props$placement,
|
|
114
|
+
popperClassName = _this$props.popperClassName,
|
|
115
|
+
t = _this$props.t;
|
|
110
116
|
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(UncontrolledPopover, {
|
|
111
117
|
target: this.props.target,
|
|
112
118
|
className: "sdoc-selected-table-size-popover",
|
|
113
|
-
trigger:
|
|
114
|
-
placement:
|
|
119
|
+
trigger: trigger,
|
|
120
|
+
placement: placement,
|
|
115
121
|
hideArrow: true,
|
|
116
122
|
fade: false,
|
|
117
|
-
ref: this.setRef
|
|
123
|
+
ref: this.setRef,
|
|
124
|
+
popperClassName: popperClassName
|
|
118
125
|
}, /*#__PURE__*/React.createElement("div", {
|
|
119
126
|
className: "sdoc-selected-table-size-container w-100 h-100 d-flex flex-column"
|
|
120
127
|
}, /*#__PURE__*/React.createElement("div", {
|
|
@@ -34,6 +34,7 @@ var TableRoot = function TableRoot(_ref) {
|
|
|
34
34
|
className: classnames('sdoc-table-wrapper position-relative', attributes.className, {
|
|
35
35
|
'scroll': allWidth > editor.width
|
|
36
36
|
}),
|
|
37
|
+
"data-root": "true",
|
|
37
38
|
style: _objectSpread(_objectSpread({}, attributes.style), {}, {
|
|
38
39
|
maxWidth: editor.width ? editor.width : '100%'
|
|
39
40
|
})
|
|
@@ -1,14 +1,23 @@
|
|
|
1
1
|
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
|
2
|
-
import React from 'react';
|
|
2
|
+
import React, { useCallback } from 'react';
|
|
3
3
|
import { useSlateStatic } from '@seafile/slate-react';
|
|
4
4
|
import { BLOCKQUOTE, LINK, CHECK_LIST_ITEM, HEADER1, HEADER2, HEADER3, HEADER4, HEADER5, HEADER6, LIST_ITEM, LIST_LIC, ORDERED_LIST, PARAGRAPH, UNORDERED_LIST, CODE_BLOCK, CODE_LINE, IMAGE, ELEMENT_TYPE, SDOC_LINK } from '../constants';
|
|
5
5
|
import { BlockquotePlugin, LinkPlugin, CheckListPlugin, HeaderPlugin, ListPlugin, CodeBlockPlugin, ImagePlugin, TablePlugin, SdocLinkPlugin, ParagraphPlugin } from '../plugins';
|
|
6
|
+
import EventBus from '../../utils/event-bus';
|
|
7
|
+
import { INTERNAL_EVENT } from '../../constants';
|
|
6
8
|
var CustomElement = function CustomElement(props) {
|
|
7
9
|
var editor = useSlateStatic();
|
|
8
|
-
var element = props.element
|
|
10
|
+
var element = props.element,
|
|
11
|
+
attributes = props.attributes;
|
|
12
|
+
var onMouseEnter = useCallback(function (event) {
|
|
13
|
+
event.stopPropagation();
|
|
14
|
+
var eventBus = EventBus.getInstance();
|
|
15
|
+
eventBus.dispatch(INTERNAL_EVENT.ON_MOUSE_ENTER_BLOCK, event);
|
|
16
|
+
}, []);
|
|
9
17
|
switch (element.type) {
|
|
10
18
|
case PARAGRAPH:
|
|
11
19
|
{
|
|
20
|
+
attributes['onMouseEnter'] = onMouseEnter;
|
|
12
21
|
var _ParagraphPlugin$rend = _slicedToArray(ParagraphPlugin.renderElements, 1),
|
|
13
22
|
renderParagraph = _ParagraphPlugin$rend[0];
|
|
14
23
|
return renderParagraph(props);
|
|
@@ -20,6 +29,7 @@ var CustomElement = function CustomElement(props) {
|
|
|
20
29
|
case HEADER5:
|
|
21
30
|
case HEADER6:
|
|
22
31
|
{
|
|
32
|
+
attributes['onMouseEnter'] = onMouseEnter;
|
|
23
33
|
var _HeaderPlugin$renderE = _slicedToArray(HeaderPlugin.renderElements, 1),
|
|
24
34
|
renderHeader = _HeaderPlugin$renderE[0];
|
|
25
35
|
return renderHeader(props, editor);
|
|
@@ -32,6 +42,7 @@ var CustomElement = function CustomElement(props) {
|
|
|
32
42
|
}
|
|
33
43
|
case BLOCKQUOTE:
|
|
34
44
|
{
|
|
45
|
+
attributes['onMouseEnter'] = onMouseEnter;
|
|
35
46
|
var _BlockquotePlugin$ren = _slicedToArray(BlockquotePlugin.renderElements, 1),
|
|
36
47
|
renderBlockquote = _BlockquotePlugin$ren[0];
|
|
37
48
|
return renderBlockquote(props, editor);
|
|
@@ -45,6 +56,7 @@ var CustomElement = function CustomElement(props) {
|
|
|
45
56
|
}
|
|
46
57
|
case LIST_ITEM:
|
|
47
58
|
{
|
|
59
|
+
attributes['onMouseEnter'] = onMouseEnter;
|
|
48
60
|
var _ListPlugin$renderEle2 = _slicedToArray(ListPlugin.renderElements, 2),
|
|
49
61
|
renderListItem = _ListPlugin$renderEle2[1];
|
|
50
62
|
return renderListItem(props, editor);
|
|
@@ -57,14 +69,14 @@ var CustomElement = function CustomElement(props) {
|
|
|
57
69
|
}
|
|
58
70
|
case CHECK_LIST_ITEM:
|
|
59
71
|
{
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
}));
|
|
72
|
+
attributes['onMouseEnter'] = onMouseEnter;
|
|
73
|
+
var _CheckListPlugin$rend = _slicedToArray(CheckListPlugin.renderElements, 1),
|
|
74
|
+
renderCheckListItem = _CheckListPlugin$rend[0];
|
|
75
|
+
return renderCheckListItem(props, editor);
|
|
65
76
|
}
|
|
66
77
|
case CODE_BLOCK:
|
|
67
78
|
{
|
|
79
|
+
attributes['onMouseEnter'] = onMouseEnter;
|
|
68
80
|
var _CodeBlockPlugin$rend = _slicedToArray(CodeBlockPlugin.renderElements, 1),
|
|
69
81
|
renderCodeBlock = _CodeBlockPlugin$rend[0];
|
|
70
82
|
return renderCodeBlock(props, editor);
|
|
@@ -83,6 +95,7 @@ var CustomElement = function CustomElement(props) {
|
|
|
83
95
|
}
|
|
84
96
|
case ELEMENT_TYPE.TABLE:
|
|
85
97
|
{
|
|
98
|
+
attributes['onMouseEnter'] = onMouseEnter;
|
|
86
99
|
var _TablePlugin$renderEl = _slicedToArray(TablePlugin.renderElements, 1),
|
|
87
100
|
renderTable = _TablePlugin$renderEl[0];
|
|
88
101
|
return renderTable(props, editor);
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { Transforms, Editor } from '@seafile/slate';
|
|
2
|
+
import { ReactEditor } from '@seafile/slate-react';
|
|
3
|
+
import copy from 'copy-to-clipboard';
|
|
4
|
+
import slugid from 'slugid';
|
|
5
|
+
import { toggleList } from '../../plugins/list/transforms';
|
|
6
|
+
import { generateImageNode } from '../../plugins/image/helpers';
|
|
7
|
+
import { generateEmptyTable } from '../../plugins/table/helpers';
|
|
8
|
+
import { genLinkNode } from '../../plugins/link/helpers';
|
|
9
|
+
import { generateEmptyElement } from '../../core';
|
|
10
|
+
import { ORDERED_LIST, UNORDERED_LIST, PARAGRAPH, CHECK_LIST_ITEM, CODE_BLOCK, CODE_LINE } from '../../constants';
|
|
11
|
+
export var onSetNodeType = function onSetNodeType(editor, element, type) {
|
|
12
|
+
if (!type) return;
|
|
13
|
+
if ([ORDERED_LIST, UNORDERED_LIST].includes(type)) {
|
|
14
|
+
toggleList(editor, type);
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
if (type === CHECK_LIST_ITEM) {
|
|
18
|
+
var newType = element.type === CHECK_LIST_ITEM ? PARAGRAPH : CHECK_LIST_ITEM;
|
|
19
|
+
Transforms.setNodes(editor, {
|
|
20
|
+
type: newType
|
|
21
|
+
});
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
if (['left', 'center', 'right'].includes(type)) {
|
|
25
|
+
Transforms.setNodes(editor, {
|
|
26
|
+
'align': type
|
|
27
|
+
});
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
Transforms.setNodes(editor, {
|
|
31
|
+
type: type
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
export var setSelection = function setSelection(editor, element) {
|
|
35
|
+
if (element) {
|
|
36
|
+
var path = ReactEditor.findPath(editor, element);
|
|
37
|
+
Transforms.select(editor, path);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
export var onCopyNode = function onCopyNode(editor) {
|
|
41
|
+
var newData = editor.setFragmentData(new DataTransfer());
|
|
42
|
+
copy('copy', {
|
|
43
|
+
onCopy: function onCopy(clipboardData) {
|
|
44
|
+
newData.types.forEach(function (type) {
|
|
45
|
+
var data = newData.getData(type);
|
|
46
|
+
clipboardData.setData(type, data);
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
};
|
|
51
|
+
export var onDeleteNode = function onDeleteNode(editor, element) {
|
|
52
|
+
var path = ReactEditor.findPath(editor, element);
|
|
53
|
+
Transforms.removeNodes(editor, {
|
|
54
|
+
at: path
|
|
55
|
+
});
|
|
56
|
+
};
|
|
57
|
+
export var insertBelowImage = function insertBelowImage(editor, src, selection) {
|
|
58
|
+
if (!src) return;
|
|
59
|
+
var p = generateEmptyElement(PARAGRAPH);
|
|
60
|
+
var imageNode = generateImageNode(src);
|
|
61
|
+
p.children[0] = imageNode;
|
|
62
|
+
var path = Editor.path(editor, selection);
|
|
63
|
+
Transforms.insertNodes(editor, p, {
|
|
64
|
+
at: [path[0] + 1]
|
|
65
|
+
});
|
|
66
|
+
};
|
|
67
|
+
export var insertBelowCodeBlock = function insertBelowCodeBlock(editor, language) {
|
|
68
|
+
var newCodeBlockNode = {
|
|
69
|
+
id: slugid.nice(),
|
|
70
|
+
type: CODE_BLOCK,
|
|
71
|
+
language: language,
|
|
72
|
+
style: {
|
|
73
|
+
white_space: 'nowrap' // default nowrap
|
|
74
|
+
},
|
|
75
|
+
|
|
76
|
+
children: [{
|
|
77
|
+
id: slugid.nice(),
|
|
78
|
+
type: CODE_LINE,
|
|
79
|
+
children: [{
|
|
80
|
+
text: '',
|
|
81
|
+
id: slugid.nice()
|
|
82
|
+
}]
|
|
83
|
+
}]
|
|
84
|
+
};
|
|
85
|
+
var path = Editor.path(editor, editor.selection);
|
|
86
|
+
Transforms.insertNodes(editor, newCodeBlockNode, {
|
|
87
|
+
mode: 'highest',
|
|
88
|
+
at: [path[0] + 1]
|
|
89
|
+
});
|
|
90
|
+
};
|
|
91
|
+
export var insertBelowTable = function insertBelowTable(editor, size, selection) {
|
|
92
|
+
if (!size) return;
|
|
93
|
+
var tableNode = generateEmptyTable(editor, size);
|
|
94
|
+
var path = Editor.path(editor, selection);
|
|
95
|
+
Transforms.insertNodes(editor, tableNode, {
|
|
96
|
+
at: [path[0] + 1]
|
|
97
|
+
});
|
|
98
|
+
};
|
|
99
|
+
export var insertBelowLink = function insertBelowLink(editor, title, url) {
|
|
100
|
+
if (!title || !url) return;
|
|
101
|
+
var p = generateEmptyElement(PARAGRAPH);
|
|
102
|
+
var linkNode = genLinkNode(url, title);
|
|
103
|
+
p.children[0] = {
|
|
104
|
+
id: slugid.nice(),
|
|
105
|
+
text: ' '
|
|
106
|
+
};
|
|
107
|
+
p.children[1] = linkNode;
|
|
108
|
+
p.children[2] = {
|
|
109
|
+
id: slugid.nice(),
|
|
110
|
+
text: ' '
|
|
111
|
+
};
|
|
112
|
+
var path = Editor.path(editor, editor.selection);
|
|
113
|
+
Transforms.insertNodes(editor, p, {
|
|
114
|
+
at: [path[0] + 1]
|
|
115
|
+
});
|
|
116
|
+
};
|
|
117
|
+
export var getDomTopHeight = function getDomTopHeight(dom) {
|
|
118
|
+
var HEADER_HEIGHT = 56 + 44;
|
|
119
|
+
var rect = dom.getBoundingClientRect();
|
|
120
|
+
return rect.y - HEADER_HEIGHT;
|
|
121
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
.sdoc-side-toolbar-container {
|
|
2
|
+
position: absolute;
|
|
3
|
+
left: 0px;
|
|
4
|
+
top: 0px;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.sdoc-side-toolbar-container .sdoc-side-op-icon {
|
|
8
|
+
border-radius: 3px;
|
|
9
|
+
padding: 0px 3px;
|
|
10
|
+
height: 24px;
|
|
11
|
+
color: #BDBDBD;
|
|
12
|
+
margin-right: 1px;
|
|
13
|
+
transform: rotate(180deg);
|
|
14
|
+
cursor: pointer;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.sdoc-side-toolbar-container .sdoc-side-op-icon :first-child {
|
|
18
|
+
font-size: 14px;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.sdoc-side-toolbar-container .side-op-icon-active {
|
|
22
|
+
background-color: #F2F2F2;
|
|
23
|
+
border-radius: 2px;
|
|
24
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
|
2
|
+
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
|
3
|
+
import classnames from 'classnames';
|
|
4
|
+
import { Node } from '@seafile/slate';
|
|
5
|
+
import { ReactEditor, useSlateStatic } from '@seafile/slate-react';
|
|
6
|
+
import EventBus from '../../../utils/event-bus';
|
|
7
|
+
import { useScrollContext } from '../../../hooks/use-scroll-context';
|
|
8
|
+
import { INTERNAL_EVENT } from '../../../constants';
|
|
9
|
+
import { getDomTopHeight, setSelection } from './helpers';
|
|
10
|
+
import SideMenu from './side-menu';
|
|
11
|
+
import './index.css';
|
|
12
|
+
var SideToolbar = function SideToolbar() {
|
|
13
|
+
var editor = useSlateStatic();
|
|
14
|
+
var scrollRef = useScrollContext();
|
|
15
|
+
var menuRef = useRef(null);
|
|
16
|
+
var _useState = useState(null),
|
|
17
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
18
|
+
slateNode = _useState2[0],
|
|
19
|
+
setSlateNode = _useState2[1];
|
|
20
|
+
var _useState3 = useState({}),
|
|
21
|
+
_useState4 = _slicedToArray(_useState3, 2),
|
|
22
|
+
sidePosition = _useState4[0],
|
|
23
|
+
setSidePosition = _useState4[1];
|
|
24
|
+
var _useState5 = useState(false),
|
|
25
|
+
_useState6 = _slicedToArray(_useState5, 2),
|
|
26
|
+
isActive = _useState6[0],
|
|
27
|
+
setActive = _useState6[1];
|
|
28
|
+
var _useState7 = useState(false),
|
|
29
|
+
_useState8 = _slicedToArray(_useState7, 2),
|
|
30
|
+
isNodeEmpty = _useState8[0],
|
|
31
|
+
setNodeEmpty = _useState8[1];
|
|
32
|
+
var _useState9 = useState(false),
|
|
33
|
+
_useState10 = _slicedToArray(_useState9, 2),
|
|
34
|
+
isShowSideMenu = _useState10[0],
|
|
35
|
+
setShowSideMenu = _useState10[1];
|
|
36
|
+
var _useState11 = useState({}),
|
|
37
|
+
_useState12 = _slicedToArray(_useState11, 2),
|
|
38
|
+
menuPosition = _useState12[0],
|
|
39
|
+
setMenuPosition = _useState12[1];
|
|
40
|
+
var onReset = useCallback(function () {
|
|
41
|
+
setShowSideMenu(false);
|
|
42
|
+
setMenuPosition({});
|
|
43
|
+
setSlateNode(null);
|
|
44
|
+
setActive(false);
|
|
45
|
+
}, []);
|
|
46
|
+
useEffect(function () {
|
|
47
|
+
var observerRefValue;
|
|
48
|
+
if (isShowSideMenu) {
|
|
49
|
+
scrollRef.current.addEventListener('scroll', onReset);
|
|
50
|
+
observerRefValue = scrollRef.current;
|
|
51
|
+
} else {
|
|
52
|
+
scrollRef.current.removeEventListener('scroll', onReset);
|
|
53
|
+
observerRefValue = null;
|
|
54
|
+
}
|
|
55
|
+
return function () {
|
|
56
|
+
if (observerRefValue) {
|
|
57
|
+
observerRefValue.removeEventListener('scroll', onReset);
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
61
|
+
}, [isShowSideMenu]);
|
|
62
|
+
useEffect(function () {
|
|
63
|
+
var handleMouseEnter = function handleMouseEnter(e) {
|
|
64
|
+
if (isShowSideMenu) return;
|
|
65
|
+
var dom = e.target;
|
|
66
|
+
while (((_dom = dom) === null || _dom === void 0 ? void 0 : (_dom$dataset = _dom.dataset) === null || _dom$dataset === void 0 ? void 0 : _dom$dataset.root) !== 'true') {
|
|
67
|
+
var _dom, _dom$dataset;
|
|
68
|
+
if (!dom.parentNode) return;
|
|
69
|
+
dom = dom.parentNode;
|
|
70
|
+
}
|
|
71
|
+
var top = getDomTopHeight(dom);
|
|
72
|
+
var node = ReactEditor.toSlateNode(editor, dom);
|
|
73
|
+
var isEmpty = Node.string(node) === '';
|
|
74
|
+
setSidePosition({
|
|
75
|
+
top: top + scrollRef.current.scrollTop,
|
|
76
|
+
left: 20
|
|
77
|
+
});
|
|
78
|
+
setSlateNode(node);
|
|
79
|
+
setNodeEmpty(isEmpty);
|
|
80
|
+
};
|
|
81
|
+
var eventBus = EventBus.getInstance();
|
|
82
|
+
var unSubscribeMouseEnter = eventBus.subscribe(INTERNAL_EVENT.ON_MOUSE_ENTER_BLOCK, handleMouseEnter);
|
|
83
|
+
return unSubscribeMouseEnter;
|
|
84
|
+
}, [editor, isShowSideMenu, scrollRef]);
|
|
85
|
+
var onActiveToggle = useCallback(function () {
|
|
86
|
+
if (isShowSideMenu) return;
|
|
87
|
+
setActive(!isActive);
|
|
88
|
+
}, [isActive, isShowSideMenu]);
|
|
89
|
+
var onShowSideMenuToggle = useCallback(function () {
|
|
90
|
+
setSelection(editor, slateNode);
|
|
91
|
+
var _menuRef$current$getB = menuRef.current.getBoundingClientRect(),
|
|
92
|
+
top = _menuRef$current$getB.top,
|
|
93
|
+
left = _menuRef$current$getB.left;
|
|
94
|
+
setShowSideMenu(!isShowSideMenu);
|
|
95
|
+
setMenuPosition({
|
|
96
|
+
top: top,
|
|
97
|
+
left: left
|
|
98
|
+
});
|
|
99
|
+
}, [editor, isShowSideMenu, slateNode]);
|
|
100
|
+
var iconClass = classnames('sdocfont', {
|
|
101
|
+
'sdoc-more-vertical': !isActive,
|
|
102
|
+
'sdoc-more-vertical-right': isActive && !isNodeEmpty,
|
|
103
|
+
'sdoc-append': isActive && isNodeEmpty
|
|
104
|
+
});
|
|
105
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
106
|
+
className: "sdoc-side-toolbar-container",
|
|
107
|
+
style: sidePosition
|
|
108
|
+
}, slateNode && /*#__PURE__*/React.createElement("div", {
|
|
109
|
+
ref: menuRef,
|
|
110
|
+
className: "sdoc-side-op-icon",
|
|
111
|
+
onMouseEnter: onActiveToggle,
|
|
112
|
+
onMouseLeave: onActiveToggle,
|
|
113
|
+
onClick: onShowSideMenuToggle
|
|
114
|
+
}, /*#__PURE__*/React.createElement("span", {
|
|
115
|
+
className: iconClass
|
|
116
|
+
})), isShowSideMenu && /*#__PURE__*/React.createElement(SideMenu, {
|
|
117
|
+
slateNode: slateNode,
|
|
118
|
+
isNodeEmpty: isNodeEmpty,
|
|
119
|
+
menuPosition: menuPosition,
|
|
120
|
+
onReset: onReset
|
|
121
|
+
}));
|
|
122
|
+
};
|
|
123
|
+
export default SideToolbar;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { UncontrolledPopover } from 'reactstrap';
|
|
3
|
+
import { insertBelowImage, insertBelowTable, insertBelowLink, insertBelowCodeBlock } from './helpers';
|
|
4
|
+
import InsertBlockMenu from './insert-block-menu';
|
|
5
|
+
var InsertBelowMenu = function InsertBelowMenu(_ref) {
|
|
6
|
+
var target = _ref.target;
|
|
7
|
+
return /*#__PURE__*/React.createElement(UncontrolledPopover, {
|
|
8
|
+
target: target,
|
|
9
|
+
className: "sdoc-side-menu-insert-below-popover",
|
|
10
|
+
trigger: "hover",
|
|
11
|
+
placement: "right-start",
|
|
12
|
+
hideArrow: true,
|
|
13
|
+
fade: false
|
|
14
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
15
|
+
className: "sdoc-side-inner-menu"
|
|
16
|
+
}, /*#__PURE__*/React.createElement(InsertBlockMenu, {
|
|
17
|
+
insertImage: insertBelowImage,
|
|
18
|
+
insertTable: insertBelowTable,
|
|
19
|
+
insertLink: insertBelowLink,
|
|
20
|
+
insertCodeBlock: insertBelowCodeBlock
|
|
21
|
+
})));
|
|
22
|
+
};
|
|
23
|
+
export default InsertBelowMenu;
|