@seafile/sdoc-editor 0.3.5 → 0.3.6
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/assets/css/layout.css +12 -0
- package/dist/basic-sdk/constants/index.js +3 -0
- package/dist/basic-sdk/extension/constants/index.js +1 -0
- package/dist/basic-sdk/extension/plugins/blockquote/plugin.js +25 -1
- package/dist/basic-sdk/extension/plugins/code-block/render-elem.js +1 -1
- package/dist/basic-sdk/extension/plugins/list/render-elem.js +2 -1
- package/dist/basic-sdk/extension/render/custom-element.js +16 -30
- package/dist/basic-sdk/extension/toolbar/side-toolbar/event.js +25 -0
- package/dist/basic-sdk/extension/toolbar/side-toolbar/helpers.js +55 -1
- package/dist/basic-sdk/extension/toolbar/side-toolbar/index.js +156 -28
- package/package.json +1 -1
|
@@ -68,6 +68,18 @@
|
|
|
68
68
|
caret-color: blue;
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
+
.sdoc-editor-container .sdoc-editor-content .article .sdoc-drag-cover::before {
|
|
72
|
+
content: ' ';
|
|
73
|
+
width: 59px;
|
|
74
|
+
display: inline-block;
|
|
75
|
+
position: absolute;
|
|
76
|
+
left: -60px;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.sdoc-editor-container .sdoc-editor-content .article .sdoc-draging {
|
|
80
|
+
border-bottom: 2px solid rgba(35,131,226);
|
|
81
|
+
}
|
|
82
|
+
|
|
71
83
|
.sdoc-editor-container .seafile-block-container {
|
|
72
84
|
position: relative;
|
|
73
85
|
}
|
|
@@ -3,6 +3,9 @@ export var INTERNAL_EVENT = {
|
|
|
3
3
|
SET_TABLE_SELECT_RANGE: 'set_table_select_range',
|
|
4
4
|
HIDDEN_CODE_BLOCK_HOVER_MENU: 'hidden_code_block_hover_menu',
|
|
5
5
|
ON_MOUSE_ENTER_BLOCK: 'on_mouse_enter_block',
|
|
6
|
+
ON_DRAG_OVER_BLOCK: 'on_drag_over_block',
|
|
7
|
+
ON_DRAG_LEAVE_BLOCK: 'on_drag_leave_block',
|
|
8
|
+
ON_DRAG_DROP_BLOCK: 'on_drag_drop_block',
|
|
6
9
|
INSERT_ELEMENT: 'insert_element',
|
|
7
10
|
OUTLINE_STATE_CHANGED: 'outline_state_changed',
|
|
8
11
|
RELOAD_IMAGE: 'reload_image',
|
|
@@ -25,4 +25,5 @@ export var LIST_ITEM_CORRELATION_TYPE = [UNORDERED_LIST, ORDERED_LIST, LIST_ITEM
|
|
|
25
25
|
export var LIST_ITEM_SUPPORTED_TRANSFORMATION = [UNORDERED_LIST, ORDERED_LIST, 'left', 'center', 'right', BLOCKQUOTE];
|
|
26
26
|
export var ADD_POSITION_OFFSET_TYPE = [PARAGRAPH, SUBTITLE, HEADER1, HEADER2, HEADER3, HEADER4, HEADER5, HEADER6, CHECK_LIST_ITEM];
|
|
27
27
|
export var FILE_TYPE = (_FILE_TYPE = {}, _defineProperty(_FILE_TYPE, FILE_LINK, 'file'), _defineProperty(_FILE_TYPE, SDOC_LINK, 'sdoc'), _FILE_TYPE);
|
|
28
|
+
export var SUPPORTED_SIDE_OPERATION_TYPE = [PARAGRAPH, SUBTITLE, HEADER1, HEADER2, HEADER3, HEADER4, HEADER5, HEADER6, CHECK_LIST_ITEM, CODE_BLOCK, TABLE, BLOCKQUOTE];
|
|
28
29
|
export { ELEMENT_TYPE, BLOCKQUOTE, TITLE, SUBTITLE, HEADER, HEADER1, HEADER2, HEADER3, HEADER4, HEADER5, HEADER6, PARAGRAPH, ORDERED_LIST, UNORDERED_LIST, LIST_ITEM, CHECK_LIST_ITEM, CODE_BLOCK, CODE_LINE, TABLE, TABLE_CELL, TABLE_ROW, LINK, SDOC_LINK, FILE_LINK, IMAGE, TOP_LEVEL_TYPES, INLINE_LEVEL_TYPES };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
1
2
|
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
|
2
|
-
import { Editor, Element, Point, Transforms, Node } from '@seafile/slate';
|
|
3
|
+
import { Editor, Element, Point, Transforms, Node, Range } from '@seafile/slate';
|
|
3
4
|
import { ReactEditor } from '@seafile/slate-react';
|
|
4
5
|
import { generateEmptyElement, getSelectedNodeByType, isSelectionAtBlockStart } from '../../core';
|
|
5
6
|
import { BLOCKQUOTE, PARAGRAPH, CODE_BLOCK, TABLE } from '../../constants';
|
|
@@ -56,6 +57,29 @@ var withBlockquote = function withBlockquote(editor) {
|
|
|
56
57
|
setBlockQuoteType(editor, PARAGRAPH);
|
|
57
58
|
return;
|
|
58
59
|
}
|
|
60
|
+
if (unit === 'line' && Range.isCollapsed(selection)) {
|
|
61
|
+
var quoteString = Node.string(node);
|
|
62
|
+
for (var index = selection.anchor.offset; index > 1; index--) {
|
|
63
|
+
var char = quoteString.slice(index - 1, index);
|
|
64
|
+
if (char === '\n') {
|
|
65
|
+
var deleteRange = selection.anchor.offset === index ? _objectSpread(_objectSpread({}, selection), {}, {
|
|
66
|
+
anchor: _objectSpread(_objectSpread({}, selection.anchor), {}, {
|
|
67
|
+
offset: index - 1
|
|
68
|
+
})
|
|
69
|
+
}) // cursor at beginning of line, delete \n
|
|
70
|
+
: _objectSpread(_objectSpread({}, selection), {}, {
|
|
71
|
+
anchor: _objectSpread(_objectSpread({}, selection.anchor), {}, {
|
|
72
|
+
offset: index
|
|
73
|
+
})
|
|
74
|
+
}); // cursor at middle or end of line, save \n
|
|
75
|
+
Transforms.delete(editor, {
|
|
76
|
+
at: deleteRange
|
|
77
|
+
});
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
deleteBackward(unit);
|
|
82
|
+
}
|
|
59
83
|
}
|
|
60
84
|
deleteBackward(unit);
|
|
61
85
|
};
|
|
@@ -132,7 +132,7 @@ var CodeBlock = function CodeBlock(_ref) {
|
|
|
132
132
|
"data-id": element.id,
|
|
133
133
|
"data-root": "true"
|
|
134
134
|
}, attributes, {
|
|
135
|
-
className:
|
|
135
|
+
className: "sdoc-code-block-container ".concat(attributes.className),
|
|
136
136
|
onClick: onFocusCodeBlock,
|
|
137
137
|
onMouseLeave: onMouseLeave
|
|
138
138
|
}), /*#__PURE__*/React.createElement("pre", {
|
|
@@ -39,7 +39,8 @@ var renderListLic = function renderListLic(props, editor) {
|
|
|
39
39
|
children = props.children,
|
|
40
40
|
element = props.element;
|
|
41
41
|
return /*#__PURE__*/React.createElement("div", Object.assign({
|
|
42
|
-
"data-id": element.id
|
|
42
|
+
"data-id": element.id,
|
|
43
|
+
"data-root": "true"
|
|
43
44
|
}, attributes), children);
|
|
44
45
|
};
|
|
45
46
|
export { renderList, renderListItem, renderListLic };
|
|
@@ -1,33 +1,26 @@
|
|
|
1
1
|
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
2
2
|
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
|
3
|
-
import { useCallback } from 'react';
|
|
4
3
|
import { useSlateStatic } from '@seafile/slate-react';
|
|
5
|
-
import { BLOCKQUOTE, LINK, CHECK_LIST_ITEM, HEADER1, HEADER2, HEADER3, HEADER4, HEADER5, HEADER6, LIST_ITEM, ORDERED_LIST, PARAGRAPH, UNORDERED_LIST, CODE_BLOCK, CODE_LINE, IMAGE, ELEMENT_TYPE, SDOC_LINK, FILE_LINK, TITLE, SUBTITLE } from '../constants';
|
|
4
|
+
import { BLOCKQUOTE, LINK, CHECK_LIST_ITEM, HEADER1, HEADER2, HEADER3, HEADER4, HEADER5, HEADER6, LIST_ITEM, ORDERED_LIST, PARAGRAPH, UNORDERED_LIST, CODE_BLOCK, CODE_LINE, IMAGE, ELEMENT_TYPE, SDOC_LINK, FILE_LINK, TITLE, SUBTITLE, SUPPORTED_SIDE_OPERATION_TYPE } from '../constants';
|
|
6
5
|
import { BlockquotePlugin, LinkPlugin, CheckListPlugin, HeaderPlugin, ListPlugin, CodeBlockPlugin, ImagePlugin, TablePlugin, SdocLinkPlugin, ParagraphPlugin, FileLinkPlugin } from '../plugins';
|
|
7
|
-
import
|
|
8
|
-
import { INTERNAL_EVENT } from '../../constants';
|
|
6
|
+
import { onMouseEnter, onDragOver, onDragLeave, onDrop } from '../toolbar/side-toolbar/event';
|
|
9
7
|
import { getParentNode } from '../core';
|
|
10
8
|
var CustomRenderElement = function CustomRenderElement(props) {
|
|
11
9
|
var editor = useSlateStatic();
|
|
12
10
|
var element = props.element,
|
|
13
11
|
attributes = props.attributes;
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
12
|
+
if (SUPPORTED_SIDE_OPERATION_TYPE.includes(element.type)) {
|
|
13
|
+
attributes['onMouseEnter'] = onMouseEnter;
|
|
14
|
+
attributes['onDragOver'] = onDragOver;
|
|
15
|
+
attributes['onDragLeave'] = onDragLeave;
|
|
16
|
+
attributes['onDrop'] = onDrop;
|
|
17
|
+
attributes['className'] = 'sdoc-drag-cover';
|
|
18
|
+
}
|
|
19
19
|
switch (element.type) {
|
|
20
20
|
case PARAGRAPH:
|
|
21
21
|
{
|
|
22
|
-
var
|
|
23
|
-
|
|
24
|
-
var _ParagraphPlugin$rend = _slicedToArray(ParagraphPlugin.renderElements, 1),
|
|
25
|
-
_renderParagraph = _ParagraphPlugin$rend[0];
|
|
26
|
-
return _renderParagraph(props);
|
|
27
|
-
}
|
|
28
|
-
attributes['onMouseEnter'] = onMouseEnter;
|
|
29
|
-
var _ParagraphPlugin$rend2 = _slicedToArray(ParagraphPlugin.renderElements, 1),
|
|
30
|
-
renderParagraph = _ParagraphPlugin$rend2[0];
|
|
22
|
+
var _ParagraphPlugin$rend = _slicedToArray(ParagraphPlugin.renderElements, 1),
|
|
23
|
+
renderParagraph = _ParagraphPlugin$rend[0];
|
|
31
24
|
return renderParagraph(props);
|
|
32
25
|
}
|
|
33
26
|
case TITLE:
|
|
@@ -38,7 +31,6 @@ var CustomRenderElement = function CustomRenderElement(props) {
|
|
|
38
31
|
}
|
|
39
32
|
case SUBTITLE:
|
|
40
33
|
{
|
|
41
|
-
attributes['onMouseEnter'] = onMouseEnter;
|
|
42
34
|
var _HeaderPlugin$renderE2 = _slicedToArray(HeaderPlugin.renderElements, 2),
|
|
43
35
|
renderSubtitle = _HeaderPlugin$renderE2[1];
|
|
44
36
|
return renderSubtitle(props, editor);
|
|
@@ -50,7 +42,6 @@ var CustomRenderElement = function CustomRenderElement(props) {
|
|
|
50
42
|
case HEADER5:
|
|
51
43
|
case HEADER6:
|
|
52
44
|
{
|
|
53
|
-
attributes['onMouseEnter'] = onMouseEnter;
|
|
54
45
|
var _HeaderPlugin$renderE3 = _slicedToArray(HeaderPlugin.renderElements, 3),
|
|
55
46
|
renderHeader = _HeaderPlugin$renderE3[2];
|
|
56
47
|
return renderHeader(props, editor);
|
|
@@ -63,7 +54,6 @@ var CustomRenderElement = function CustomRenderElement(props) {
|
|
|
63
54
|
}
|
|
64
55
|
case BLOCKQUOTE:
|
|
65
56
|
{
|
|
66
|
-
attributes['onMouseEnter'] = onMouseEnter;
|
|
67
57
|
var _BlockquotePlugin$ren = _slicedToArray(BlockquotePlugin.renderElements, 1),
|
|
68
58
|
renderBlockquote = _BlockquotePlugin$ren[0];
|
|
69
59
|
return renderBlockquote(props, editor);
|
|
@@ -77,21 +67,18 @@ var CustomRenderElement = function CustomRenderElement(props) {
|
|
|
77
67
|
}
|
|
78
68
|
case LIST_ITEM:
|
|
79
69
|
{
|
|
80
|
-
attributes['onMouseEnter'] = onMouseEnter;
|
|
81
70
|
var _ListPlugin$renderEle2 = _slicedToArray(ListPlugin.renderElements, 2),
|
|
82
71
|
renderListItem = _ListPlugin$renderEle2[1];
|
|
83
72
|
return renderListItem(props, editor);
|
|
84
73
|
}
|
|
85
74
|
case CHECK_LIST_ITEM:
|
|
86
75
|
{
|
|
87
|
-
attributes['onMouseEnter'] = onMouseEnter;
|
|
88
76
|
var _CheckListPlugin$rend = _slicedToArray(CheckListPlugin.renderElements, 1),
|
|
89
77
|
renderCheckListItem = _CheckListPlugin$rend[0];
|
|
90
78
|
return renderCheckListItem(props, editor);
|
|
91
79
|
}
|
|
92
80
|
case CODE_BLOCK:
|
|
93
81
|
{
|
|
94
|
-
attributes['onMouseEnter'] = onMouseEnter;
|
|
95
82
|
var _CodeBlockPlugin$rend = _slicedToArray(CodeBlockPlugin.renderElements, 1),
|
|
96
83
|
renderCodeBlock = _CodeBlockPlugin$rend[0];
|
|
97
84
|
return renderCodeBlock(props, editor);
|
|
@@ -105,8 +92,8 @@ var CustomRenderElement = function CustomRenderElement(props) {
|
|
|
105
92
|
case IMAGE:
|
|
106
93
|
{
|
|
107
94
|
var _editor$element_comme;
|
|
108
|
-
var
|
|
109
|
-
var comments = ((_editor$element_comme = editor.element_comments_map) === null || _editor$element_comme === void 0 ? void 0 : _editor$element_comme[
|
|
95
|
+
var parentNode = getParentNode(editor.children, element.id);
|
|
96
|
+
var comments = ((_editor$element_comme = editor.element_comments_map) === null || _editor$element_comme === void 0 ? void 0 : _editor$element_comme[parentNode.id]) || [];
|
|
110
97
|
var unresolvedComments = comments && comments.filter(function (item) {
|
|
111
98
|
return !item.resolved;
|
|
112
99
|
});
|
|
@@ -122,7 +109,6 @@ var CustomRenderElement = function CustomRenderElement(props) {
|
|
|
122
109
|
}
|
|
123
110
|
case ELEMENT_TYPE.TABLE:
|
|
124
111
|
{
|
|
125
|
-
attributes['onMouseEnter'] = onMouseEnter;
|
|
126
112
|
var _TablePlugin$renderEl = _slicedToArray(TablePlugin.renderElements, 1),
|
|
127
113
|
renderTable = _TablePlugin$renderEl[0];
|
|
128
114
|
return renderTable(props, editor);
|
|
@@ -153,9 +139,9 @@ var CustomRenderElement = function CustomRenderElement(props) {
|
|
|
153
139
|
}
|
|
154
140
|
default:
|
|
155
141
|
{
|
|
156
|
-
var _ParagraphPlugin$
|
|
157
|
-
|
|
158
|
-
return
|
|
142
|
+
var _ParagraphPlugin$rend2 = _slicedToArray(ParagraphPlugin.renderElements, 1),
|
|
143
|
+
_renderParagraph = _ParagraphPlugin$rend2[0];
|
|
144
|
+
return _renderParagraph(props);
|
|
159
145
|
}
|
|
160
146
|
}
|
|
161
147
|
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import EventBus from '../../../utils/event-bus';
|
|
2
|
+
import { INTERNAL_EVENT } from '../../../constants';
|
|
3
|
+
export var onMouseEnter = function onMouseEnter(event) {
|
|
4
|
+
event.stopPropagation();
|
|
5
|
+
var eventBus = EventBus.getInstance();
|
|
6
|
+
eventBus.dispatch(INTERNAL_EVENT.ON_MOUSE_ENTER_BLOCK, event);
|
|
7
|
+
};
|
|
8
|
+
export var onDragOver = function onDragOver(event) {
|
|
9
|
+
event.stopPropagation();
|
|
10
|
+
event.preventDefault();
|
|
11
|
+
var eventBus = EventBus.getInstance();
|
|
12
|
+
eventBus.dispatch(INTERNAL_EVENT.ON_DRAG_OVER_BLOCK, event);
|
|
13
|
+
};
|
|
14
|
+
export var onDragLeave = function onDragLeave(event) {
|
|
15
|
+
event.stopPropagation();
|
|
16
|
+
event.preventDefault();
|
|
17
|
+
var eventBus = EventBus.getInstance();
|
|
18
|
+
eventBus.dispatch(INTERNAL_EVENT.ON_DRAG_LEAVE_BLOCK, event);
|
|
19
|
+
};
|
|
20
|
+
export var onDrop = function onDrop(event) {
|
|
21
|
+
event.stopPropagation();
|
|
22
|
+
event.preventDefault();
|
|
23
|
+
var eventBus = EventBus.getInstance();
|
|
24
|
+
eventBus.dispatch(INTERNAL_EVENT.ON_DRAG_DROP_BLOCK, event);
|
|
25
|
+
};
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { Transforms, Node, Editor, Element } from '@seafile/slate';
|
|
1
|
+
import { Transforms, Node, Editor, Element, Path } from '@seafile/slate';
|
|
2
2
|
import slugid from 'slugid';
|
|
3
3
|
import { ReactEditor } from '@seafile/slate-react';
|
|
4
4
|
import copy from 'copy-to-clipboard';
|
|
5
5
|
import { toggleList } from '../../plugins/list/transforms';
|
|
6
6
|
import { generateEmptyElement } from '../../core';
|
|
7
|
+
import { generateEmptyList } from '../../plugins/list/model';
|
|
7
8
|
import { setClipboardCodeBlockData } from '../../plugins/code-block/helpers';
|
|
8
9
|
import { ORDERED_LIST, UNORDERED_LIST, PARAGRAPH, CHECK_LIST_ITEM, IMAGE, TABLE, CODE_BLOCK, BLOCKQUOTE, LIST_ITEM_CORRELATION_TYPE, ADD_POSITION_OFFSET_TYPE, INSERT_POSITION, ELEMENT_TYPE } from '../../constants';
|
|
9
10
|
import { EMPTY_SELECTED_RANGE } from '../../plugins/table/constants';
|
|
@@ -116,4 +117,57 @@ export var insertElement = function insertElement(editor, type, insertPosition)
|
|
|
116
117
|
Transforms.setNodes(editor, {
|
|
117
118
|
type: type
|
|
118
119
|
});
|
|
120
|
+
};
|
|
121
|
+
export var getNodeEntry = function getNodeEntry(editor, el) {
|
|
122
|
+
var node = ReactEditor.toSlateNode(editor, el);
|
|
123
|
+
var path = ReactEditor.findPath(editor, node);
|
|
124
|
+
if (isList(editor, path)) {
|
|
125
|
+
path = path.slice(0, path.length - 1);
|
|
126
|
+
}
|
|
127
|
+
if (node && path) return [node, path];
|
|
128
|
+
return [];
|
|
129
|
+
};
|
|
130
|
+
export var isBlockquote = function isBlockquote(editor, path) {
|
|
131
|
+
var _nodeEntry$;
|
|
132
|
+
var nodeEntry = Editor.node(editor, path);
|
|
133
|
+
if (nodeEntry && ((_nodeEntry$ = nodeEntry[0]) === null || _nodeEntry$ === void 0 ? void 0 : _nodeEntry$.type) === BLOCKQUOTE) {
|
|
134
|
+
return true;
|
|
135
|
+
}
|
|
136
|
+
return false;
|
|
137
|
+
};
|
|
138
|
+
export var isList = function isList(editor, path) {
|
|
139
|
+
var _nodeEntry$2;
|
|
140
|
+
var nodeEntry = Editor.node(editor, [path[0]]);
|
|
141
|
+
if (nodeEntry && [ORDERED_LIST, UNORDERED_LIST].includes((_nodeEntry$2 = nodeEntry[0]) === null || _nodeEntry$2 === void 0 ? void 0 : _nodeEntry$2.type)) {
|
|
142
|
+
return true;
|
|
143
|
+
}
|
|
144
|
+
if (path.length > 1 && isBlockquote(editor, [path[0]])) {
|
|
145
|
+
var _nodeEntry$3;
|
|
146
|
+
var _nodeEntry = Editor.node(editor, [path[0], path[1]]);
|
|
147
|
+
if ([ORDERED_LIST, UNORDERED_LIST].includes((_nodeEntry$3 = _nodeEntry[0]) === null || _nodeEntry$3 === void 0 ? void 0 : _nodeEntry$3.type)) {
|
|
148
|
+
return true;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return false;
|
|
152
|
+
};
|
|
153
|
+
export var getListNode = function getListNode(editor, path) {
|
|
154
|
+
var listType = Editor.node(editor, [path[0]])[0].type;
|
|
155
|
+
if (listType === BLOCKQUOTE) {
|
|
156
|
+
listType = Editor.node(editor, [path[0], path[1]])[0].type;
|
|
157
|
+
}
|
|
158
|
+
var listItem = Editor.node(editor, path)[0];
|
|
159
|
+
var listNode = generateEmptyList(listType);
|
|
160
|
+
listNode.children[0] = listItem;
|
|
161
|
+
return listNode;
|
|
162
|
+
};
|
|
163
|
+
export var onWrapListItem = function onWrapListItem(editor, targetPath, sourcePath) {
|
|
164
|
+
var nextPath = Path.next(targetPath);
|
|
165
|
+
var listNode = getListNode(editor, sourcePath);
|
|
166
|
+
Transforms.insertNodes(editor, listNode, {
|
|
167
|
+
at: nextPath
|
|
168
|
+
});
|
|
169
|
+
Transforms.removeNodes(editor, {
|
|
170
|
+
at: sourcePath
|
|
171
|
+
});
|
|
172
|
+
return;
|
|
119
173
|
};
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
|
2
2
|
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
|
3
3
|
import classnames from 'classnames';
|
|
4
|
+
import { Editor, Path, Transforms } from '@seafile/slate';
|
|
4
5
|
import { ReactEditor, useSlateStatic } from '@seafile/slate-react';
|
|
6
|
+
import SideMenu from './side-menu';
|
|
5
7
|
import EventBus from '../../../utils/event-bus';
|
|
6
|
-
import { focusEditor } from '../../core';
|
|
7
8
|
import { useScrollContext } from '../../../hooks/use-scroll-context';
|
|
9
|
+
import { focusEditor } from '../../core';
|
|
10
|
+
import { getDomTopHeight, setSelection, isVoidNode, getNodeEntry, isBlockquote, isList, onWrapListItem } from './helpers';
|
|
8
11
|
import { INTERNAL_EVENT } from '../../../constants';
|
|
9
|
-
import {
|
|
10
|
-
import SideMenu from './side-menu';
|
|
12
|
+
import { CODE_BLOCK, TABLE, BLOCKQUOTE, CHECK_LIST_ITEM } from '../../constants';
|
|
11
13
|
import './index.css';
|
|
14
|
+
var sourceElement = null;
|
|
15
|
+
var targetElement = null;
|
|
12
16
|
var SideToolbar = function SideToolbar() {
|
|
13
17
|
var editor = useSlateStatic();
|
|
14
18
|
var scrollRef = useScrollContext();
|
|
@@ -23,26 +27,20 @@ var SideToolbar = function SideToolbar() {
|
|
|
23
27
|
setSidePosition = _useState4[1];
|
|
24
28
|
var _useState5 = useState(false),
|
|
25
29
|
_useState6 = _slicedToArray(_useState5, 2),
|
|
26
|
-
|
|
27
|
-
|
|
30
|
+
isNodeEmpty = _useState6[0],
|
|
31
|
+
setNodeEmpty = _useState6[1];
|
|
28
32
|
var _useState7 = useState(false),
|
|
29
33
|
_useState8 = _slicedToArray(_useState7, 2),
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
var _useState9 = useState(
|
|
34
|
+
isShowSideMenu = _useState8[0],
|
|
35
|
+
setShowSideMenu = _useState8[1];
|
|
36
|
+
var _useState9 = useState({}),
|
|
33
37
|
_useState10 = _slicedToArray(_useState9, 2),
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
var _useState11 = useState({}),
|
|
37
|
-
_useState12 = _slicedToArray(_useState11, 2),
|
|
38
|
-
menuPosition = _useState12[0],
|
|
39
|
-
setMenuPosition = _useState12[1];
|
|
38
|
+
menuPosition = _useState10[0],
|
|
39
|
+
setMenuPosition = _useState10[1];
|
|
40
40
|
var onReset = useCallback(function () {
|
|
41
41
|
setShowSideMenu(false);
|
|
42
42
|
setMenuPosition({});
|
|
43
43
|
setSlateNode(null);
|
|
44
|
-
setActive(false);
|
|
45
|
-
|
|
46
44
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
47
45
|
}, []);
|
|
48
46
|
useEffect(function () {
|
|
@@ -87,10 +85,6 @@ var SideToolbar = function SideToolbar() {
|
|
|
87
85
|
|
|
88
86
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
89
87
|
}, [editor, isShowSideMenu, scrollRef]);
|
|
90
|
-
var onActiveToggle = useCallback(function () {
|
|
91
|
-
if (isShowSideMenu) return;
|
|
92
|
-
setActive(!isActive);
|
|
93
|
-
}, [isActive, isShowSideMenu]);
|
|
94
88
|
var onShowSideMenuToggle = useCallback(function () {
|
|
95
89
|
setSelection(editor, slateNode);
|
|
96
90
|
var _menuRef$current$getB = menuRef.current.getBoundingClientRect(),
|
|
@@ -102,22 +96,156 @@ var SideToolbar = function SideToolbar() {
|
|
|
102
96
|
left: left
|
|
103
97
|
});
|
|
104
98
|
}, [editor, isShowSideMenu, slateNode]);
|
|
105
|
-
var
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
99
|
+
var dragStart = useCallback(function (event) {
|
|
100
|
+
sourceElement = ReactEditor.toDOMNode(editor, slateNode);
|
|
101
|
+
var path = ReactEditor.findPath(editor, slateNode);
|
|
102
|
+
|
|
103
|
+
// Dragging the first element within the blockquote drags the entire blockquote by default.
|
|
104
|
+
if (isBlockquote(editor, [path[0]]) && path.slice(1).every(function (p) {
|
|
105
|
+
return p === 0;
|
|
106
|
+
})) {
|
|
107
|
+
var nodeEntry = Editor.node(editor, [path[0]]);
|
|
108
|
+
sourceElement = ReactEditor.toDOMNode(editor, nodeEntry[0]);
|
|
109
|
+
}
|
|
110
|
+
event.dataTransfer.setDragImage(sourceElement, 0, 0);
|
|
111
|
+
}, [editor, slateNode]);
|
|
112
|
+
var dragOver = useCallback(function (event) {
|
|
113
|
+
var overElement = event.currentTarget;
|
|
114
|
+
if (!overElement.classList.contains('sdoc-draging')) {
|
|
115
|
+
overElement.classList.add('sdoc-draging');
|
|
116
|
+
}
|
|
117
|
+
}, []);
|
|
118
|
+
var dragLeave = useCallback(function (event) {
|
|
119
|
+
var leaveElement = event.currentTarget;
|
|
120
|
+
leaveElement.classList.remove('sdoc-draging');
|
|
121
|
+
}, []);
|
|
122
|
+
var drop = useCallback(function (event) {
|
|
123
|
+
targetElement = event.currentTarget;
|
|
124
|
+
targetElement.classList.remove('sdoc-draging');
|
|
125
|
+
var _getNodeEntry = getNodeEntry(editor, sourceElement),
|
|
126
|
+
_getNodeEntry2 = _slicedToArray(_getNodeEntry, 2),
|
|
127
|
+
sourceNode = _getNodeEntry2[0],
|
|
128
|
+
sourcePath = _getNodeEntry2[1];
|
|
129
|
+
var _getNodeEntry3 = getNodeEntry(editor, targetElement),
|
|
130
|
+
_getNodeEntry4 = _slicedToArray(_getNodeEntry3, 2),
|
|
131
|
+
targetPath = _getNodeEntry4[1];
|
|
132
|
+
|
|
133
|
+
// Dragging into a quoteBlock is not supported
|
|
134
|
+
if ([CODE_BLOCK, TABLE, BLOCKQUOTE].includes(sourceNode.type) && isBlockquote(editor, [targetPath[0]]) && targetPath.length > 1) {
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Dragging into a list is not supported
|
|
139
|
+
if ([CODE_BLOCK, TABLE, BLOCKQUOTE, CHECK_LIST_ITEM].includes(sourceNode.type) && isList(editor, targetPath)) {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Drag list
|
|
144
|
+
if (isList(editor, sourcePath)) {
|
|
145
|
+
// ordinary list items
|
|
146
|
+
if (!isBlockquote(editor, [sourcePath[0]])) {
|
|
147
|
+
// Drag ordinary list items to places other than list and quoteBlock
|
|
148
|
+
if (!isList(editor, targetPath) && !isBlockquote(editor, [targetPath[0]])) {
|
|
149
|
+
onWrapListItem(editor, targetPath, sourcePath);
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Drag ordinary list items into the quoteBlock
|
|
154
|
+
if (isBlockquote(editor, [targetPath[0]])) {
|
|
155
|
+
// Drag and drop ordinary list items onto the list within the quoteBlock
|
|
156
|
+
if (isList(editor, targetPath)) {
|
|
157
|
+
Transforms.moveNodes(editor, {
|
|
158
|
+
at: sourcePath,
|
|
159
|
+
to: Path.next(targetPath)
|
|
160
|
+
});
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
onWrapListItem(editor, targetPath, sourcePath);
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// quoteBlock list items
|
|
169
|
+
if (isBlockquote(editor, [sourcePath[0]])) {
|
|
170
|
+
// Drag quoteBlock list items to places other than list and quoteBlock
|
|
171
|
+
if (!isList(editor, targetPath) && !isBlockquote(editor, [targetPath[0]])) {
|
|
172
|
+
onWrapListItem(editor, targetPath, sourcePath);
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Drag quoteBlock list items into the quoteBlock
|
|
177
|
+
if (isBlockquote(editor, [targetPath[0]])) {
|
|
178
|
+
// Drag and drop ordinary list items onto the list within the quoteBlock
|
|
179
|
+
if (isList(editor, targetPath)) {
|
|
180
|
+
Transforms.moveNodes(editor, {
|
|
181
|
+
at: sourcePath,
|
|
182
|
+
to: Path.next(targetPath)
|
|
183
|
+
});
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
onWrapListItem(editor, targetPath, sourcePath);
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Drag backward
|
|
193
|
+
if (Path.isAfter(targetPath, sourcePath)) {
|
|
194
|
+
var toPath = targetPath.slice(0);
|
|
195
|
+
|
|
196
|
+
// Drag elements outside the quoteBlock into the quoteBlock
|
|
197
|
+
if (!isBlockquote(editor, [sourcePath[0]]) && isBlockquote(editor, [targetPath[0]]) && targetPath.length > 1) {
|
|
198
|
+
toPath = Path.next(targetPath);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Drag into list
|
|
202
|
+
if (isList(editor, targetPath)) {
|
|
203
|
+
toPath = Path.next(targetPath);
|
|
204
|
+
}
|
|
205
|
+
Transforms.moveNodes(editor, {
|
|
206
|
+
at: sourcePath,
|
|
207
|
+
to: toPath
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// Drag forward
|
|
212
|
+
if (Path.isBefore(targetPath, sourcePath)) {
|
|
213
|
+
var _toPath = Path.next(targetPath);
|
|
214
|
+
Transforms.moveNodes(editor, {
|
|
215
|
+
at: sourcePath,
|
|
216
|
+
to: _toPath
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// reset
|
|
221
|
+
sourceElement = null;
|
|
222
|
+
targetElement = null;
|
|
223
|
+
}, [editor]);
|
|
224
|
+
useEffect(function () {
|
|
225
|
+
var eventBus = EventBus.getInstance();
|
|
226
|
+
var unSubscribeDragOver = eventBus.subscribe(INTERNAL_EVENT.ON_DRAG_OVER_BLOCK, dragOver);
|
|
227
|
+
var unSubscribeDragLeave = eventBus.subscribe(INTERNAL_EVENT.ON_DRAG_LEAVE_BLOCK, dragLeave);
|
|
228
|
+
var unSubscribeDrop = eventBus.subscribe(INTERNAL_EVENT.ON_DRAG_DROP_BLOCK, drop);
|
|
229
|
+
return function () {
|
|
230
|
+
unSubscribeDragOver();
|
|
231
|
+
unSubscribeDragLeave();
|
|
232
|
+
unSubscribeDrop();
|
|
233
|
+
};
|
|
234
|
+
}, [dragLeave, dragOver, drop]);
|
|
110
235
|
return /*#__PURE__*/React.createElement("div", {
|
|
111
236
|
className: "sdoc-side-toolbar-container",
|
|
112
237
|
style: sidePosition
|
|
113
238
|
}, slateNode && /*#__PURE__*/React.createElement("div", {
|
|
114
239
|
ref: menuRef,
|
|
240
|
+
draggable: true,
|
|
241
|
+
onDragStart: dragStart,
|
|
115
242
|
className: "sdoc-side-op-icon",
|
|
116
|
-
onMouseEnter: onActiveToggle,
|
|
117
|
-
onMouseLeave: onActiveToggle,
|
|
118
243
|
onClick: onShowSideMenuToggle
|
|
119
244
|
}, /*#__PURE__*/React.createElement("span", {
|
|
120
|
-
className:
|
|
245
|
+
className: classnames('sdocfont', {
|
|
246
|
+
'sdoc-more-vertical': !isNodeEmpty,
|
|
247
|
+
'sdoc-append': isNodeEmpty
|
|
248
|
+
})
|
|
121
249
|
})), isShowSideMenu && /*#__PURE__*/React.createElement(SideMenu, {
|
|
122
250
|
slateNode: slateNode,
|
|
123
251
|
isNodeEmpty: isNodeEmpty,
|