@seafile/sdoc-editor 0.1.81 → 0.1.83
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 +33 -7
- package/dist/basic-sdk/assets/css/sdoc-editor-plugins.css +2 -0
- package/dist/basic-sdk/comment/style.css +1 -0
- package/dist/basic-sdk/editor.js +42 -3
- package/dist/basic-sdk/extension/constants/index.js +2 -0
- package/dist/basic-sdk/extension/core/queries/index.js +15 -3
- package/dist/basic-sdk/extension/plugins/check-list/plugin.js +18 -8
- package/dist/basic-sdk/extension/plugins/header/menu/index.js +15 -3
- package/dist/basic-sdk/extension/plugins/header/menu/style.css +1 -1
- package/dist/basic-sdk/extension/plugins/header/plugin.js +20 -4
- package/dist/basic-sdk/extension/plugins/image/helpers.js +1 -3
- package/dist/basic-sdk/extension/plugins/image/menu/style.css +2 -2
- package/dist/basic-sdk/extension/plugins/image/plugin.js +21 -0
- package/dist/basic-sdk/extension/plugins/image/render-elem.js +1 -1
- package/dist/basic-sdk/extension/plugins/table/helpers.js +11 -0
- package/dist/basic-sdk/extension/plugins/table/render/table-header/rows-header/row-header.js +13 -0
- package/dist/basic-sdk/extension/plugins/text-align/menu/index.js +15 -3
- package/dist/basic-sdk/extension/plugins/text-align/menu/style.css +1 -1
- package/dist/basic-sdk/outline/index.js +75 -0
- package/dist/basic-sdk/outline/outline-item.js +52 -0
- package/dist/basic-sdk/outline/style.css +83 -0
- package/dist/basic-sdk/utils/event-handler.js +4 -0
- package/dist/basic-sdk/views/viewer.js +6 -4
- package/dist/components/code-block-hover-menu/index.css +1 -1
- package/dist/components/doc-info/index.js +3 -1
- package/dist/components/draft-dropdown/index.js +77 -0
- package/dist/components/draft-dropdown/style.css +43 -0
- package/dist/components/more-dropdown/index.js +10 -3
- package/dist/components/more-dropdown/style.css +1 -1
- package/dist/constants/index.js +1 -0
- package/dist/pages/simple-editor.js +2 -0
- package/package.json +1 -1
- package/public/locales/en/sdoc-editor.json +3 -1
- package/public/locales/zh-CN/sdoc-editor.json +3 -1
- package/dist/basic-sdk/assets/css/outline.css +0 -52
- package/dist/basic-sdk/outline.js +0 -125
|
@@ -17,23 +17,50 @@
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
.sdoc-editor-container .sdoc-editor-content {
|
|
20
|
-
|
|
20
|
+
width: 100%;
|
|
21
|
+
height: calc(100% - 44px);
|
|
21
22
|
display: flex;
|
|
22
23
|
background: #f5f5f5;
|
|
23
|
-
|
|
24
|
+
position: relative;
|
|
24
25
|
}
|
|
25
26
|
|
|
26
|
-
.sdoc-editor-container .sdoc-editor-
|
|
27
|
-
|
|
27
|
+
.sdoc-editor-container .sdoc-editor-content.readonly {
|
|
28
|
+
height: 100%;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.sdoc-editor-container .sdoc-absolute-wrapper {
|
|
32
|
+
position: absolute;
|
|
33
|
+
left: 0;
|
|
34
|
+
right: 0;
|
|
35
|
+
top: 0;
|
|
36
|
+
bottom: 0;
|
|
37
|
+
height: 100%;
|
|
38
|
+
width: 100%;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.sdoc-editor-container .sdoc-article-wrapper {
|
|
42
|
+
position: absolute;
|
|
43
|
+
left: 0;
|
|
44
|
+
right: 0;
|
|
45
|
+
top: 0;
|
|
46
|
+
bottom: 0;
|
|
47
|
+
z-index: 100;
|
|
28
48
|
overflow: auto;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.sdoc-editor-container .sdoc-article-container {
|
|
29
52
|
position: relative;
|
|
53
|
+
top: 0;
|
|
54
|
+
width: 794px;
|
|
55
|
+
margin: 0 auto;
|
|
56
|
+
padding-top: 20px;
|
|
57
|
+
padding-bottom: 20px;
|
|
30
58
|
}
|
|
31
59
|
|
|
32
60
|
.sdoc-editor-container .sdoc-editor-content .article {
|
|
33
61
|
width: 794px;
|
|
34
|
-
min-height:
|
|
62
|
+
min-height: 100%;
|
|
35
63
|
padding: 40px 60px;
|
|
36
|
-
margin: 20px 0;
|
|
37
64
|
background-color: #fff;
|
|
38
65
|
border: 1px solid #e5e6e8;
|
|
39
66
|
box-shadow: 0 0 15px rgba(0, 0, 0, 0.06);
|
|
@@ -43,7 +70,6 @@
|
|
|
43
70
|
caret-color: blue;
|
|
44
71
|
}
|
|
45
72
|
|
|
46
|
-
|
|
47
73
|
.sdoc-editor-container .seafile-block-container {
|
|
48
74
|
position: relative;
|
|
49
75
|
}
|
|
@@ -57,10 +57,12 @@
|
|
|
57
57
|
.sdoc-editor-container .article .image-size {
|
|
58
58
|
display: inline-block;
|
|
59
59
|
padding: 5px;
|
|
60
|
+
white-space: nowrap;
|
|
60
61
|
height: 22px;
|
|
61
62
|
position: absolute;
|
|
62
63
|
bottom: -25px;
|
|
63
64
|
left: 100%;
|
|
65
|
+
z-index: 1;
|
|
64
66
|
transform: translateX(5px);
|
|
65
67
|
border-radius: 3px;
|
|
66
68
|
line-height: 12px;
|
package/dist/basic-sdk/editor.js
CHANGED
|
@@ -194,18 +194,57 @@ var SDocEditor = function SDocEditor(_ref) {
|
|
|
194
194
|
eventProxy.onKeyDown(event);
|
|
195
195
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
196
196
|
}, []);
|
|
197
|
+
var _useState7 = useState({}),
|
|
198
|
+
_useState8 = _slicedToArray(_useState7, 2),
|
|
199
|
+
containerStyle = _useState8[0],
|
|
200
|
+
setContainerStyle = _useState8[1];
|
|
201
|
+
var handleWindowResize = useCallback(function () {
|
|
202
|
+
var rect = scrollRef.current.getBoundingClientRect();
|
|
203
|
+
var articleRect = articleRef.current.getBoundingClientRect();
|
|
204
|
+
if ((rect.width - articleRect.width) / 2 < 280) {
|
|
205
|
+
setContainerStyle({
|
|
206
|
+
marginLeft: '280px'
|
|
207
|
+
});
|
|
208
|
+
} else {
|
|
209
|
+
setContainerStyle({});
|
|
210
|
+
}
|
|
211
|
+
}, []);
|
|
212
|
+
useEffect(function () {
|
|
213
|
+
handleWindowResize();
|
|
214
|
+
window.addEventListener('resize', handleWindowResize);
|
|
215
|
+
return function () {
|
|
216
|
+
window.removeEventListener('resize', handleWindowResize);
|
|
217
|
+
};
|
|
218
|
+
}, [handleWindowResize]);
|
|
219
|
+
var _useState9 = useState(0),
|
|
220
|
+
_useState10 = _slicedToArray(_useState9, 2),
|
|
221
|
+
scrollLeft = _useState10[0],
|
|
222
|
+
setScrollLeft = _useState10[1];
|
|
223
|
+
var onWrapperScroll = useCallback(function (event) {
|
|
224
|
+
var scrollLeft = event.target.scrollLeft;
|
|
225
|
+
setScrollLeft(scrollLeft);
|
|
226
|
+
}, []);
|
|
197
227
|
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
|
|
198
228
|
className: "sdoc-editor-container"
|
|
199
229
|
}, /*#__PURE__*/React.createElement(Toolbar, {
|
|
200
230
|
editor: editor
|
|
201
231
|
}), /*#__PURE__*/React.createElement("div", {
|
|
202
232
|
className: "sdoc-editor-content"
|
|
233
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
234
|
+
className: "sdoc-absolute-wrapper"
|
|
203
235
|
}, /*#__PURE__*/React.createElement(SDocOutline, {
|
|
236
|
+
scrollLeft: scrollLeft,
|
|
204
237
|
doc: slateValue,
|
|
205
238
|
docUuid: config.docUuid
|
|
206
|
-
}), /*#__PURE__*/React.createElement("div", {
|
|
239
|
+
})), /*#__PURE__*/React.createElement("div", {
|
|
240
|
+
className: "sdoc-absolute-wrapper"
|
|
241
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
207
242
|
ref: scrollRef,
|
|
208
|
-
className: "sdoc-
|
|
243
|
+
className: "sdoc-article-wrapper",
|
|
244
|
+
onScroll: onWrapperScroll
|
|
245
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
246
|
+
className: "sdoc-article-container",
|
|
247
|
+
style: containerStyle
|
|
209
248
|
}, /*#__PURE__*/React.createElement(ScrollContext.Provider, {
|
|
210
249
|
value: {
|
|
211
250
|
scrollRef: scrollRef
|
|
@@ -225,7 +264,7 @@ var SDocEditor = function SDocEditor(_ref) {
|
|
|
225
264
|
onContextMenu: onContextMenu,
|
|
226
265
|
onMouseDown: onMouseDown,
|
|
227
266
|
decorate: decorate
|
|
228
|
-
})), /*#__PURE__*/React.createElement(CommentWrapper, null))))))), isShowContextMenu && /*#__PURE__*/React.createElement(ContextMenu, {
|
|
267
|
+
})), /*#__PURE__*/React.createElement(CommentWrapper, null))))))))), isShowContextMenu && /*#__PURE__*/React.createElement(ContextMenu, {
|
|
229
268
|
editor: editor,
|
|
230
269
|
contextMenuPosition: menuPosition
|
|
231
270
|
}));
|
|
@@ -120,4 +120,6 @@ export var ADDED_STYLE = {
|
|
|
120
120
|
computed_bg_color: '#e6ffed',
|
|
121
121
|
color: 'rgb(137, 181, 66)'
|
|
122
122
|
};
|
|
123
|
+
export var HEADER_TYPE_ARRAY = ['header1', 'header2', 'header3', 'header4', 'header5', 'header6'];
|
|
124
|
+
export var LIST_TYPE_ARRAY = ['unordered_list', 'ordered_list'];
|
|
123
125
|
export { BLOCKQUOTE, HEADER, HEADER1, HEADER2, HEADER3, HEADER4, HEADER5, HEADER6, PARAGRAPH, BOLD, ITALIC, UNDERLINE, STRIKETHROUGH, SUPERSCRIPT, SUBSCRIPT, ORDERED_LIST, UNORDERED_LIST, LIST_ITEM, LIST_LIC, CHECK_LIST, CHECK_LIST_ITEM, LINK, HTML, CODE_BLOCK, CODE_LINE, IMAGE, TABLE, TABLE_CELL, TABLE_ROW, FORMULA, COLUMN, TEXT_STYLE, TEXT_STYLE_MORE, BOLD_ITALIC, TEXT_ALIGN, ALIGN_LEFT, ALIGN_RIGHT, ALIGN_CENTER, ELEMENT_TYPE, KEYBOARD };
|
|
@@ -84,16 +84,28 @@ export var getSelectedNodeByType = function getSelectedNodeByType(editor, type)
|
|
|
84
84
|
nodeEntry = _Editor$nodes2[0];
|
|
85
85
|
return nodeEntry ? nodeEntry[0] : null;
|
|
86
86
|
};
|
|
87
|
-
export var
|
|
87
|
+
export var getSelectedNodeByTypes = function getSelectedNodeByTypes(editor, types) {
|
|
88
88
|
var match = function match(n) {
|
|
89
|
-
return getNodeType(n)
|
|
89
|
+
return types.includes(getNodeType(n));
|
|
90
90
|
};
|
|
91
91
|
var _Editor$nodes3 = Editor.nodes(editor, {
|
|
92
92
|
match: match,
|
|
93
|
-
universal:
|
|
93
|
+
universal: true
|
|
94
94
|
}),
|
|
95
95
|
_Editor$nodes4 = _slicedToArray(_Editor$nodes3, 1),
|
|
96
96
|
nodeEntry = _Editor$nodes4[0];
|
|
97
|
+
return nodeEntry ? nodeEntry[0] : null;
|
|
98
|
+
};
|
|
99
|
+
export var getSelectedNodeEntryByType = function getSelectedNodeEntryByType(editor, type) {
|
|
100
|
+
var match = function match(n) {
|
|
101
|
+
return getNodeType(n) === type;
|
|
102
|
+
};
|
|
103
|
+
var _Editor$nodes5 = Editor.nodes(editor, {
|
|
104
|
+
match: match,
|
|
105
|
+
universal: false
|
|
106
|
+
}),
|
|
107
|
+
_Editor$nodes6 = _slicedToArray(_Editor$nodes5, 1),
|
|
108
|
+
nodeEntry = _Editor$nodes6[0];
|
|
97
109
|
return nodeEntry ? nodeEntry : null;
|
|
98
110
|
};
|
|
99
111
|
export var getNodeEntries = function getNodeEntries(editor, options) {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Node, Range, Transforms } from '@seafile/slate';
|
|
2
2
|
import { CHECK_LIST_ITEM, PARAGRAPH } from '../../constants';
|
|
3
|
-
import { getSelectedNodeByType } from '../../core';
|
|
3
|
+
import { generateDefaultText, getSelectedNodeByType } from '../../core';
|
|
4
4
|
var withCheckList = function withCheckList(editor) {
|
|
5
5
|
var insertBreak = editor.insertBreak,
|
|
6
|
-
|
|
6
|
+
deleteBackward = editor.deleteBackward;
|
|
7
7
|
var newEditor = editor;
|
|
8
8
|
newEditor.insertBreak = function () {
|
|
9
9
|
var selection = newEditor.selection;
|
|
@@ -18,16 +18,25 @@ var withCheckList = function withCheckList(editor) {
|
|
|
18
18
|
}
|
|
19
19
|
if (Node.string(node).length === 0) {
|
|
20
20
|
Transforms.setNodes(editor, {
|
|
21
|
-
type: PARAGRAPH
|
|
21
|
+
type: PARAGRAPH,
|
|
22
|
+
children: [generateDefaultText()]
|
|
22
23
|
}, {
|
|
23
|
-
|
|
24
|
+
at: node[1]
|
|
25
|
+
});
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// If it is check-list-item, handle your own business logic
|
|
30
|
+
if (Node.string(node).length > 0) {
|
|
31
|
+
Transforms.splitNodes(editor, {
|
|
32
|
+
always: true
|
|
24
33
|
});
|
|
25
34
|
return;
|
|
26
35
|
}
|
|
27
36
|
insertBreak();
|
|
28
37
|
return;
|
|
29
38
|
};
|
|
30
|
-
newEditor.
|
|
39
|
+
newEditor.deleteBackward = function (unit) {
|
|
31
40
|
var selection = newEditor.selection;
|
|
32
41
|
if (selection && Range.isCollapsed(selection)) {
|
|
33
42
|
var selectedTodo = getSelectedNodeByType(editor, CHECK_LIST_ITEM);
|
|
@@ -35,15 +44,16 @@ var withCheckList = function withCheckList(editor) {
|
|
|
35
44
|
// If the current todo has no text, it will be converted to a paragraph
|
|
36
45
|
if (Node.string(selectedTodo).length === 0) {
|
|
37
46
|
Transforms.setNodes(editor, {
|
|
38
|
-
type: PARAGRAPH
|
|
47
|
+
type: PARAGRAPH,
|
|
48
|
+
children: [generateDefaultText()]
|
|
39
49
|
}, {
|
|
40
|
-
|
|
50
|
+
at: selectedTodo[1]
|
|
41
51
|
});
|
|
42
52
|
return;
|
|
43
53
|
}
|
|
44
54
|
}
|
|
45
55
|
}
|
|
46
|
-
|
|
56
|
+
deleteBackward(unit);
|
|
47
57
|
};
|
|
48
58
|
return newEditor;
|
|
49
59
|
};
|
|
@@ -16,12 +16,15 @@ var HeaderMenu = /*#__PURE__*/function (_React$Component) {
|
|
|
16
16
|
_classCallCheck(this, HeaderMenu);
|
|
17
17
|
_this = _super.call(this, props);
|
|
18
18
|
_this.registerEventHandler = function () {
|
|
19
|
-
document.addEventListener('click', _this.onHideHeaderMenu);
|
|
19
|
+
document.addEventListener('click', _this.onHideHeaderMenu, true);
|
|
20
20
|
};
|
|
21
21
|
_this.unregisterEventHandler = function () {
|
|
22
|
-
document.removeEventListener('click', _this.onHideHeaderMenu);
|
|
22
|
+
document.removeEventListener('click', _this.onHideHeaderMenu, true);
|
|
23
23
|
};
|
|
24
|
-
_this.onHideHeaderMenu = function () {
|
|
24
|
+
_this.onHideHeaderMenu = function (e) {
|
|
25
|
+
var menu = _this.menu;
|
|
26
|
+
var clickIsInMenu = menu && menu.contains(e.target) && menu !== e.target;
|
|
27
|
+
if (clickIsInMenu) return;
|
|
25
28
|
_this.setState({
|
|
26
29
|
isShowHeaderPopover: false
|
|
27
30
|
}, function () {
|
|
@@ -65,8 +68,16 @@ var HeaderMenu = /*#__PURE__*/function (_React$Component) {
|
|
|
65
68
|
|
|
66
69
|
// 执行命令
|
|
67
70
|
setHeaderType(editor, newType);
|
|
71
|
+
_this.setState({
|
|
72
|
+
isShowHeaderPopover: false
|
|
73
|
+
}, function () {
|
|
74
|
+
_this.unregisterEventHandler();
|
|
75
|
+
});
|
|
68
76
|
};
|
|
69
77
|
};
|
|
78
|
+
_this.setMenuRef = function (ref) {
|
|
79
|
+
_this.menu = ref;
|
|
80
|
+
};
|
|
70
81
|
_this.state = {
|
|
71
82
|
isShowHeaderPopover: false
|
|
72
83
|
};
|
|
@@ -92,6 +103,7 @@ var HeaderMenu = /*#__PURE__*/function (_React$Component) {
|
|
|
92
103
|
}, t(HEADER_TITLE_MAP[headerType])), !disabled && /*#__PURE__*/React.createElement("span", {
|
|
93
104
|
className: headerIconClass
|
|
94
105
|
})), isShowHeaderPopover && /*#__PURE__*/React.createElement("div", {
|
|
106
|
+
ref: this.setMenuRef,
|
|
95
107
|
className: "header-popover sdoc-dropdown-menu"
|
|
96
108
|
}, /*#__PURE__*/React.createElement("div", {
|
|
97
109
|
className: "sdoc-dropdown-menu-item",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
|
2
|
-
import { Editor, Element, Transforms } from '@seafile/slate';
|
|
3
|
-
import { PARAGRAPH } from '../../constants';
|
|
4
|
-
import { generateEmptyElement } from '../../core';
|
|
2
|
+
import { Editor, Element, Transforms, Node } from '@seafile/slate';
|
|
3
|
+
import { PARAGRAPH, HEADER_TYPE_ARRAY, LIST_TYPE_ARRAY } from '../../constants';
|
|
4
|
+
import { generateEmptyElement, getSelectedNodeByTypes } from '../../core';
|
|
5
5
|
var isSelectionAtLineEnd = function isSelectionAtLineEnd(editor, path) {
|
|
6
6
|
var selection = editor.selection;
|
|
7
7
|
if (!selection) return false;
|
|
@@ -9,7 +9,9 @@ var isSelectionAtLineEnd = function isSelectionAtLineEnd(editor, path) {
|
|
|
9
9
|
return isAtLineEnd;
|
|
10
10
|
};
|
|
11
11
|
var withHeader = function withHeader(editor) {
|
|
12
|
-
var insertBreak = editor.insertBreak
|
|
12
|
+
var insertBreak = editor.insertBreak,
|
|
13
|
+
insertFragment = editor.insertFragment,
|
|
14
|
+
insertText = editor.insertText;
|
|
13
15
|
var newEditor = editor;
|
|
14
16
|
|
|
15
17
|
// Rewrite insertBreak - insert paragraph when carriage return at the end of header
|
|
@@ -51,6 +53,20 @@ var withHeader = function withHeader(editor) {
|
|
|
51
53
|
insertBreak();
|
|
52
54
|
}
|
|
53
55
|
};
|
|
56
|
+
newEditor.insertFragment = function (data) {
|
|
57
|
+
var headerNode = getSelectedNodeByTypes(editor, HEADER_TYPE_ARRAY);
|
|
58
|
+
var headerText = Node.string(headerNode || {
|
|
59
|
+
children: []
|
|
60
|
+
});
|
|
61
|
+
var isSingleListItem = data.length === 1 && data[0].children.length === 1 && LIST_TYPE_ARRAY.includes(data[0].type);
|
|
62
|
+
// Insert a list item when the header is empty, insert only the text
|
|
63
|
+
if (headerNode && headerText.length === 0 && isSingleListItem) {
|
|
64
|
+
var text = Node.string(data[0]);
|
|
65
|
+
insertText(text);
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
return insertFragment(data);
|
|
69
|
+
};
|
|
54
70
|
return newEditor;
|
|
55
71
|
};
|
|
56
72
|
export default withHeader;
|
|
@@ -2,7 +2,7 @@ import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
|
2
2
|
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
|
3
3
|
import urlJoin from 'url-join';
|
|
4
4
|
import { Editor, Range, Transforms } from '@seafile/slate';
|
|
5
|
-
import { CODE_BLOCK, IMAGE
|
|
5
|
+
import { CODE_BLOCK, IMAGE } from '../../constants';
|
|
6
6
|
import { generateEmptyElement, getNodeType, isTextNode, getParentNode } from '../../core';
|
|
7
7
|
import context from '../../../../context';
|
|
8
8
|
export var isInsertImageMenuDisabled = function isInsertImageMenuDisabled(editor) {
|
|
@@ -17,8 +17,6 @@ export var isInsertImageMenuDisabled = function isInsertImageMenuDisabled(editor
|
|
|
17
17
|
type = getNodeType(parentNode);
|
|
18
18
|
}
|
|
19
19
|
if (type === CODE_BLOCK) return true;
|
|
20
|
-
if (type === ORDERED_LIST) return true;
|
|
21
|
-
if (type === UNORDERED_LIST) return true;
|
|
22
20
|
if (type.startsWith('header')) return true;
|
|
23
21
|
if (Editor.isVoid(editor, n)) return true;
|
|
24
22
|
return false;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Transforms, Path } from '@seafile/slate';
|
|
1
2
|
import context from '../../../../context';
|
|
2
3
|
import { insertImage } from './helpers';
|
|
3
4
|
var withImage = function withImage(editor) {
|
|
@@ -32,6 +33,26 @@ var withImage = function withImage(editor) {
|
|
|
32
33
|
}
|
|
33
34
|
insertData(data);
|
|
34
35
|
};
|
|
36
|
+
newEditor.imageOnKeyDown = function (e) {
|
|
37
|
+
if (e.keyCode === 13) {
|
|
38
|
+
var selection = newEditor.selection;
|
|
39
|
+
var focus = selection.focus;
|
|
40
|
+
var parentPath = Path.parent(focus.path);
|
|
41
|
+
var nextPath = Path.next(parentPath);
|
|
42
|
+
var nextSelection = {
|
|
43
|
+
anchor: {
|
|
44
|
+
offset: 0,
|
|
45
|
+
path: nextPath
|
|
46
|
+
},
|
|
47
|
+
focus: {
|
|
48
|
+
offset: 0,
|
|
49
|
+
path: nextPath
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
Transforms.setSelection(editor, nextSelection);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
};
|
|
35
56
|
return newEditor;
|
|
36
57
|
};
|
|
37
58
|
export default withImage;
|
|
@@ -464,4 +464,15 @@ export var getFirstTableCell = function getFirstTableCell(element) {
|
|
|
464
464
|
tableCellElement = tableCellElement.parentNode;
|
|
465
465
|
}
|
|
466
466
|
return tableCellElement;
|
|
467
|
+
};
|
|
468
|
+
export var rowElementHasImage = function rowElementHasImage(element) {
|
|
469
|
+
if (!element) return false;
|
|
470
|
+
if (!Array.isArray(element.children) || element.children.length === 0) return false;
|
|
471
|
+
return element.children.some(function (child) {
|
|
472
|
+
if (child.type === ELEMENT_TYPE.IMAGE) return true;
|
|
473
|
+
if (ObjectUtils.hasProperty(child, 'children')) {
|
|
474
|
+
return rowElementHasImage(child);
|
|
475
|
+
}
|
|
476
|
+
return false;
|
|
477
|
+
});
|
|
467
478
|
};
|
package/dist/basic-sdk/extension/plugins/table/render/table-header/rows-header/row-header.js
CHANGED
|
@@ -8,6 +8,7 @@ import { useResizeHandlersContext, useTableSelectedRangeContext } from '../../ho
|
|
|
8
8
|
import { useScrollContext } from '../../../../../../hooks/use-scroll-context';
|
|
9
9
|
import { ELEMENT_TYPE } from '../../../../../constants';
|
|
10
10
|
import { findPath, getSelectedNodeByType } from '../../../../../core';
|
|
11
|
+
import { rowElementHasImage } from '../../../helpers';
|
|
11
12
|
var RowHeader = function RowHeader(_ref) {
|
|
12
13
|
var _row$style;
|
|
13
14
|
var row = _ref.row,
|
|
@@ -30,6 +31,18 @@ var RowHeader = function RowHeader(_ref) {
|
|
|
30
31
|
var currentCellPath = currentCell ? findPath(editor, currentCell, [-1, -1]) : [-1, -1];
|
|
31
32
|
var pathLength = currentCellPath.length;
|
|
32
33
|
useEffect(function () {
|
|
34
|
+
if (rowElementHasImage(row)) {
|
|
35
|
+
var time = setTimeout(function () {
|
|
36
|
+
// There is a delay in image loading
|
|
37
|
+
var rowDom = ReactEditor.toDOMNode(editor, row);
|
|
38
|
+
if (!rowDom) return;
|
|
39
|
+
if (rowHeight === rowDom.clientHeight) return;
|
|
40
|
+
setRowHeight(rowDom.clientHeight);
|
|
41
|
+
}, 300);
|
|
42
|
+
return function () {
|
|
43
|
+
clearTimeout(time);
|
|
44
|
+
};
|
|
45
|
+
}
|
|
33
46
|
var rowDom = ReactEditor.toDOMNode(editor, row);
|
|
34
47
|
if (!rowDom) return;
|
|
35
48
|
if (rowHeight === rowDom.clientHeight) return;
|
|
@@ -16,12 +16,15 @@ var TextAlignMenu = /*#__PURE__*/function (_React$Component) {
|
|
|
16
16
|
_classCallCheck(this, TextAlignMenu);
|
|
17
17
|
_this = _super.call(this, props);
|
|
18
18
|
_this.registerEventHandler = function () {
|
|
19
|
-
document.addEventListener('click', _this.onHideTextAlignMenu);
|
|
19
|
+
document.addEventListener('click', _this.onHideTextAlignMenu, true);
|
|
20
20
|
};
|
|
21
21
|
_this.unregisterEventHandler = function () {
|
|
22
|
-
document.removeEventListener('click', _this.onHideTextAlignMenu);
|
|
22
|
+
document.removeEventListener('click', _this.onHideTextAlignMenu, true);
|
|
23
23
|
};
|
|
24
|
-
_this.onHideTextAlignMenu = function () {
|
|
24
|
+
_this.onHideTextAlignMenu = function (e) {
|
|
25
|
+
var menu = _this.menu;
|
|
26
|
+
var clickIsInMenu = menu && menu.contains(e.target) && menu !== e.target;
|
|
27
|
+
if (clickIsInMenu) return;
|
|
25
28
|
_this.setState({
|
|
26
29
|
isDropdownMenuOpen: false
|
|
27
30
|
}, function () {
|
|
@@ -60,6 +63,14 @@ var TextAlignMenu = /*#__PURE__*/function (_React$Component) {
|
|
|
60
63
|
_this.setType = function (type) {
|
|
61
64
|
var editor = _this.props.editor;
|
|
62
65
|
setAlignType(editor, type);
|
|
66
|
+
_this.setState({
|
|
67
|
+
isDropdownMenuOpen: false
|
|
68
|
+
}, function () {
|
|
69
|
+
_this.unregisterEventHandler();
|
|
70
|
+
});
|
|
71
|
+
};
|
|
72
|
+
_this.setMenuRef = function (ref) {
|
|
73
|
+
_this.menu = ref;
|
|
63
74
|
};
|
|
64
75
|
_this.state = {
|
|
65
76
|
isDropdownMenuOpen: false
|
|
@@ -89,6 +100,7 @@ var TextAlignMenu = /*#__PURE__*/function (_React$Component) {
|
|
|
89
100
|
}), !disabled && /*#__PURE__*/React.createElement("span", {
|
|
90
101
|
className: caretIconClass
|
|
91
102
|
})), isDropdownMenuOpen && /*#__PURE__*/React.createElement("div", {
|
|
103
|
+
ref: this.setMenuRef,
|
|
92
104
|
className: "align-popover sdoc-dropdown-menu"
|
|
93
105
|
}, MENUS_CONFIG_MAP[TEXT_ALIGN].map(function (item, index) {
|
|
94
106
|
return /*#__PURE__*/React.createElement("span", {
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
|
2
|
+
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
|
3
|
+
import { withTranslation } from 'react-i18next';
|
|
4
|
+
import { UncontrolledTooltip } from 'reactstrap';
|
|
5
|
+
import OutlineItem from './outline-item';
|
|
6
|
+
import './style.css';
|
|
7
|
+
var getOutlineSetting = function getOutlineSetting(docUuid) {
|
|
8
|
+
var currentValue = localStorage.getItem(docUuid);
|
|
9
|
+
var config = currentValue ? JSON.parse(currentValue) : {};
|
|
10
|
+
var _config$outlineOpen = config.outlineOpen,
|
|
11
|
+
outlineOpen = _config$outlineOpen === void 0 ? false : _config$outlineOpen;
|
|
12
|
+
return outlineOpen;
|
|
13
|
+
};
|
|
14
|
+
var setOutlineSetting = function setOutlineSetting(docUuid, isShown) {
|
|
15
|
+
var currentValue = localStorage.getItem(docUuid);
|
|
16
|
+
var config = currentValue ? JSON.parse(currentValue) : {};
|
|
17
|
+
config['outlineOpen'] = isShown;
|
|
18
|
+
localStorage.setItem(docUuid, JSON.stringify(config));
|
|
19
|
+
};
|
|
20
|
+
var SDocOutline = function SDocOutline(_ref) {
|
|
21
|
+
var scrollLeft = _ref.scrollLeft,
|
|
22
|
+
docUuid = _ref.docUuid,
|
|
23
|
+
doc = _ref.doc,
|
|
24
|
+
t = _ref.t;
|
|
25
|
+
var _useState = useState(false),
|
|
26
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
27
|
+
isShown = _useState2[0],
|
|
28
|
+
setIsShown = _useState2[1];
|
|
29
|
+
useEffect(function () {
|
|
30
|
+
var outlineOpen = getOutlineSetting(docUuid);
|
|
31
|
+
setIsShown(outlineOpen);
|
|
32
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
33
|
+
}, []);
|
|
34
|
+
var toggleShow = useCallback(function () {
|
|
35
|
+
setIsShown(!isShown);
|
|
36
|
+
setOutlineSetting(!isShown);
|
|
37
|
+
}, [isShown]);
|
|
38
|
+
var list = useMemo(function () {
|
|
39
|
+
return doc.filter(function (item) {
|
|
40
|
+
return ['header2', 'header3'].includes(item.type);
|
|
41
|
+
});
|
|
42
|
+
}, [doc]);
|
|
43
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
44
|
+
className: "sdoc-outline-wrapper",
|
|
45
|
+
style: {
|
|
46
|
+
left: -scrollLeft
|
|
47
|
+
}
|
|
48
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
49
|
+
className: "sdoc-outline"
|
|
50
|
+
}, isShown && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
|
|
51
|
+
className: "sdoc-outline-header"
|
|
52
|
+
}, /*#__PURE__*/React.createElement("h2", {
|
|
53
|
+
className: "sdoc-outline-header__title"
|
|
54
|
+
}, t('Outline')), /*#__PURE__*/React.createElement("span", {
|
|
55
|
+
className: "sdoc-outline-header__close sdocfont sdoc-cancel",
|
|
56
|
+
onClick: toggleShow
|
|
57
|
+
})), list.length === 0 && /*#__PURE__*/React.createElement("p", {
|
|
58
|
+
className: "mt-4 text-secondary"
|
|
59
|
+
}, t('Headings_you_add_to_the_document_will_appear_here')), list.length > 0 && /*#__PURE__*/React.createElement("ol", {
|
|
60
|
+
className: "sdoc-outline-list-container"
|
|
61
|
+
}, list.map(function (item, index) {
|
|
62
|
+
return /*#__PURE__*/React.createElement(OutlineItem, {
|
|
63
|
+
key: index,
|
|
64
|
+
item: item
|
|
65
|
+
});
|
|
66
|
+
})))), !isShown && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("span", {
|
|
67
|
+
id: "sdoc-outline-menu",
|
|
68
|
+
className: "sdoc-outline-menu sdocfont sdoc-table-of-content",
|
|
69
|
+
onClick: toggleShow
|
|
70
|
+
}), /*#__PURE__*/React.createElement(UncontrolledTooltip, {
|
|
71
|
+
placement: "right",
|
|
72
|
+
target: "sdoc-outline-menu"
|
|
73
|
+
}, t('Outline'))));
|
|
74
|
+
};
|
|
75
|
+
export default withTranslation('sdoc-editor')(SDocOutline);
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
|
|
2
|
+
import _createClass from "@babel/runtime/helpers/esm/createClass";
|
|
3
|
+
import _inherits from "@babel/runtime/helpers/esm/inherits";
|
|
4
|
+
import _createSuper from "@babel/runtime/helpers/esm/createSuper";
|
|
5
|
+
import React from 'react';
|
|
6
|
+
var OutlineItem = /*#__PURE__*/function (_React$PureComponent) {
|
|
7
|
+
_inherits(OutlineItem, _React$PureComponent);
|
|
8
|
+
var _super = _createSuper(OutlineItem);
|
|
9
|
+
function OutlineItem(props) {
|
|
10
|
+
var _this;
|
|
11
|
+
_classCallCheck(this, OutlineItem);
|
|
12
|
+
_this = _super.call(this, props);
|
|
13
|
+
_this.onItemClick = function () {
|
|
14
|
+
var item = _this.props.item;
|
|
15
|
+
var id = item.id;
|
|
16
|
+
document.getElementById(id).scrollIntoView();
|
|
17
|
+
};
|
|
18
|
+
_this.onMouseOver = function () {
|
|
19
|
+
_this.setState({
|
|
20
|
+
isHighlighted: true
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
_this.onMouseOut = function () {
|
|
24
|
+
_this.setState({
|
|
25
|
+
isHighlighted: false
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
_this.state = {
|
|
29
|
+
isHighlighted: false
|
|
30
|
+
};
|
|
31
|
+
return _this;
|
|
32
|
+
}
|
|
33
|
+
_createClass(OutlineItem, [{
|
|
34
|
+
key: "render",
|
|
35
|
+
value: function render() {
|
|
36
|
+
var isHighlighted = this.state.isHighlighted;
|
|
37
|
+
var item = this.props.item;
|
|
38
|
+
var type = item.type,
|
|
39
|
+
children = item.children;
|
|
40
|
+
return /*#__PURE__*/React.createElement("li", {
|
|
41
|
+
className: "sdoc-outline-item ".concat(type === 'header3' ? 'pl-5' : '', " ").concat(isHighlighted ? 'active' : ''),
|
|
42
|
+
onClick: this.onItemClick,
|
|
43
|
+
onMouseOver: this.onMouseOver,
|
|
44
|
+
onMouseOut: this.onMouseOut
|
|
45
|
+
}, children.map(function (child) {
|
|
46
|
+
return child.text;
|
|
47
|
+
}).join(''));
|
|
48
|
+
}
|
|
49
|
+
}]);
|
|
50
|
+
return OutlineItem;
|
|
51
|
+
}(React.PureComponent);
|
|
52
|
+
export default OutlineItem;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
.sdoc-outline-wrapper {
|
|
2
|
+
position: absolute;
|
|
3
|
+
top: 0;
|
|
4
|
+
bottom: 0;
|
|
5
|
+
display: flex;
|
|
6
|
+
margin: 20px 30px 20px 16px;
|
|
7
|
+
min-height: 0;
|
|
8
|
+
z-index: 101;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.sdoc-outline {
|
|
12
|
+
flex: 1;
|
|
13
|
+
width: 220px;
|
|
14
|
+
display: flex;
|
|
15
|
+
min-height: 0;
|
|
16
|
+
flex-direction: column;
|
|
17
|
+
font-size: 14px;
|
|
18
|
+
position: relative;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.sdoc-outline-header {
|
|
22
|
+
display: flex;
|
|
23
|
+
justify-content: space-between;
|
|
24
|
+
align-items: center;
|
|
25
|
+
padding: 0.25rem 0;
|
|
26
|
+
color: #999;
|
|
27
|
+
border-bottom: 1px solid #dbdbdb;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.sdoc-outline-header__title {
|
|
31
|
+
font-size: 14px;
|
|
32
|
+
line-height: 1.1;
|
|
33
|
+
margin: 0 !important;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.sdoc-outline-header__close {
|
|
37
|
+
cursor: pointer;
|
|
38
|
+
font-size: 14px;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.sdoc-outline-header__close:hover {
|
|
42
|
+
color: #555;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.sdoc-outline-list-container {
|
|
46
|
+
list-style: none;
|
|
47
|
+
padding: 0.5rem 0;
|
|
48
|
+
flex: 1;
|
|
49
|
+
display: flex;
|
|
50
|
+
flex-direction: column;
|
|
51
|
+
overflow: auto;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.sdoc-outline-item {
|
|
55
|
+
padding: 4px 0;
|
|
56
|
+
cursor: pointer;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.sdoc-outline-item.active {
|
|
60
|
+
color: #ff8000;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.sdoc-outline-menu {
|
|
64
|
+
line-height: 1;
|
|
65
|
+
font-size: 14px;
|
|
66
|
+
color: #888;
|
|
67
|
+
cursor: pointer;
|
|
68
|
+
width: 28px;
|
|
69
|
+
height: 28px;
|
|
70
|
+
background: #fff;
|
|
71
|
+
border-radius: 0 50% 50% 0;
|
|
72
|
+
box-shadow: 0 0 6px rgba(0,0,0, 0.12);
|
|
73
|
+
display: flex;
|
|
74
|
+
align-items: center;
|
|
75
|
+
justify-content: center;
|
|
76
|
+
position: absolute;
|
|
77
|
+
top: 20px;
|
|
78
|
+
left: -16px;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.sdoc-outline-menu:hover {
|
|
82
|
+
color: #333;
|
|
83
|
+
}
|
|
@@ -52,6 +52,10 @@ var EventProxy = /*#__PURE__*/_createClass(function EventProxy(_editor) {
|
|
|
52
52
|
if (node) {
|
|
53
53
|
_this.editor.tableOnKeyDown(event);
|
|
54
54
|
}
|
|
55
|
+
var imageNode = getSelectedNodeByType(editor, ELEMENT_TYPE.IMAGE);
|
|
56
|
+
if (imageNode) {
|
|
57
|
+
_this.editor.imageOnKeyDown(event);
|
|
58
|
+
}
|
|
55
59
|
};
|
|
56
60
|
this.onCopy = function (event) {
|
|
57
61
|
event.stopPropagation();
|
|
@@ -25,10 +25,12 @@ var SDocViewer = function SDocViewer(_ref) {
|
|
|
25
25
|
return /*#__PURE__*/React.createElement("div", {
|
|
26
26
|
className: "sdoc-editor-container"
|
|
27
27
|
}, /*#__PURE__*/React.createElement("div", {
|
|
28
|
-
className: "sdoc-editor-content"
|
|
28
|
+
className: "sdoc-editor-content readonly"
|
|
29
29
|
}, /*#__PURE__*/React.createElement("div", {
|
|
30
30
|
ref: scrollRef,
|
|
31
|
-
className: "sdoc-
|
|
31
|
+
className: "sdoc-article-wrapper"
|
|
32
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
33
|
+
className: "sdoc-article-container"
|
|
32
34
|
}, /*#__PURE__*/React.createElement(ScrollContext.Provider, {
|
|
33
35
|
value: {
|
|
34
36
|
scrollRef: scrollRef
|
|
@@ -37,7 +39,7 @@ var SDocViewer = function SDocViewer(_ref) {
|
|
|
37
39
|
editor: editor,
|
|
38
40
|
value: slateValue
|
|
39
41
|
}, /*#__PURE__*/React.createElement("div", {
|
|
40
|
-
className: "article
|
|
42
|
+
className: "article",
|
|
41
43
|
ref: articleRef
|
|
42
44
|
}, /*#__PURE__*/React.createElement(SetNodeToDecorations, null), /*#__PURE__*/React.createElement(Editable, {
|
|
43
45
|
readOnly: true,
|
|
@@ -50,6 +52,6 @@ var SDocViewer = function SDocViewer(_ref) {
|
|
|
50
52
|
},
|
|
51
53
|
onDOMBeforeInput: function onDOMBeforeInput(event) {},
|
|
52
54
|
decorate: decorate
|
|
53
|
-
})))))));
|
|
55
|
+
}))))))));
|
|
54
56
|
};
|
|
55
57
|
export default SDocViewer;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
.sdoc-code-block-hover-menu-container {
|
|
2
2
|
position: absolute;
|
|
3
3
|
height: 42px;
|
|
4
|
+
z-index: 101;
|
|
4
5
|
}
|
|
5
6
|
|
|
6
7
|
.sdoc-code-block-hover-menu-container .hover-menu-container {
|
|
@@ -14,7 +15,6 @@
|
|
|
14
15
|
border-radius: 3px;
|
|
15
16
|
box-shadow: 0 1px 0 rgba(0, 0, 0, 0.08);
|
|
16
17
|
border: 1px solid #e8e8e8;
|
|
17
|
-
z-index: 1000;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
.sdoc-code-block-hover-menu-container .hover-menu-container .active {
|
|
@@ -5,9 +5,11 @@ import context from '../../context';
|
|
|
5
5
|
import { EventBus } from '../../basic-sdk';
|
|
6
6
|
import { EXTERNAL_EVENT } from '../../constants';
|
|
7
7
|
import { DateUtils } from '../../utils';
|
|
8
|
+
import DraftDropdown from '../draft-dropdown';
|
|
8
9
|
var DocInfo = function DocInfo(_ref) {
|
|
9
10
|
var t = _ref.t,
|
|
10
11
|
isStarred = _ref.isStarred,
|
|
12
|
+
isDraft = _ref.isDraft,
|
|
11
13
|
isEditMode = _ref.isEditMode;
|
|
12
14
|
var onInternalLinkClick = useCallback(function () {
|
|
13
15
|
var eventBus = EventBus.getInstance();
|
|
@@ -22,7 +24,7 @@ var DocInfo = function DocInfo(_ref) {
|
|
|
22
24
|
var _context$getSettings = context.getSettings(),
|
|
23
25
|
isShowInternalLink = _context$getSettings.isShowInternalLink,
|
|
24
26
|
isStarIconShown = _context$getSettings.isStarIconShown;
|
|
25
|
-
var docInfo = /*#__PURE__*/React.createElement(React.Fragment, null, isStarIconShown && /*#__PURE__*/React.createElement("button", {
|
|
27
|
+
var docInfo = /*#__PURE__*/React.createElement(React.Fragment, null, isDraft && /*#__PURE__*/React.createElement(DraftDropdown, null), isStarIconShown && /*#__PURE__*/React.createElement("button", {
|
|
26
28
|
className: "doc-icon sdocfont ".concat(isStarred ? 'sdoc-starred' : 'sdoc-unstarred', " border-0 p-0 bg-transparent"),
|
|
27
29
|
title: isStarred ? t('Starred') : t('Unstarred'),
|
|
28
30
|
"aria-label": isStarred ? t('Unstar') : t('Star'),
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
|
|
2
|
+
import _createClass from "@babel/runtime/helpers/esm/createClass";
|
|
3
|
+
import _inherits from "@babel/runtime/helpers/esm/inherits";
|
|
4
|
+
import _createSuper from "@babel/runtime/helpers/esm/createSuper";
|
|
5
|
+
import React from 'react';
|
|
6
|
+
import { withTranslation } from 'react-i18next';
|
|
7
|
+
import { EventBus } from '../../basic-sdk';
|
|
8
|
+
import { EXTERNAL_EVENT } from '../../constants';
|
|
9
|
+
import './style.css';
|
|
10
|
+
var DraftDropdownMenu = /*#__PURE__*/function (_React$Component) {
|
|
11
|
+
_inherits(DraftDropdownMenu, _React$Component);
|
|
12
|
+
var _super = _createSuper(DraftDropdownMenu);
|
|
13
|
+
function DraftDropdownMenu(props) {
|
|
14
|
+
var _this;
|
|
15
|
+
_classCallCheck(this, DraftDropdownMenu);
|
|
16
|
+
_this = _super.call(this, props);
|
|
17
|
+
_this.registerEventHandler = function () {
|
|
18
|
+
document.addEventListener('click', _this.onHideDraftDropdownMenu);
|
|
19
|
+
};
|
|
20
|
+
_this.unregisterEventHandler = function () {
|
|
21
|
+
document.removeEventListener('click', _this.onHideDraftDropdownMenu);
|
|
22
|
+
};
|
|
23
|
+
_this.onHideDraftDropdownMenu = function () {
|
|
24
|
+
_this.setState({
|
|
25
|
+
isDropdownMenuOpen: false
|
|
26
|
+
}, function () {
|
|
27
|
+
_this.unregisterEventHandler();
|
|
28
|
+
});
|
|
29
|
+
};
|
|
30
|
+
_this.onToggleClick = function (event) {
|
|
31
|
+
event.stopPropagation();
|
|
32
|
+
event.nativeEvent.stopImmediatePropagation();
|
|
33
|
+
var isDropdownMenuOpen = !_this.state.isDropdownMenuOpen;
|
|
34
|
+
if (isDropdownMenuOpen) {
|
|
35
|
+
_this.setState({
|
|
36
|
+
isDropdownMenuOpen: isDropdownMenuOpen
|
|
37
|
+
}, function () {
|
|
38
|
+
_this.registerEventHandler();
|
|
39
|
+
});
|
|
40
|
+
} else {
|
|
41
|
+
_this.setState({
|
|
42
|
+
isDropdownMenuOpen: isDropdownMenuOpen
|
|
43
|
+
}, function () {
|
|
44
|
+
_this.unregisterEventHandler();
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
_this.unmark = function () {
|
|
49
|
+
var eventBus = EventBus.getInstance();
|
|
50
|
+
eventBus.dispatch(EXTERNAL_EVENT.UNMARK_AS_DRAFT);
|
|
51
|
+
};
|
|
52
|
+
_this.state = {
|
|
53
|
+
isDropdownMenuOpen: false
|
|
54
|
+
};
|
|
55
|
+
return _this;
|
|
56
|
+
}
|
|
57
|
+
_createClass(DraftDropdownMenu, [{
|
|
58
|
+
key: "render",
|
|
59
|
+
value: function render() {
|
|
60
|
+
var isDropdownMenuOpen = this.state.isDropdownMenuOpen;
|
|
61
|
+
var t = this.props.t;
|
|
62
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
63
|
+
className: "sdoc-draft-menu"
|
|
64
|
+
}, /*#__PURE__*/React.createElement("span", {
|
|
65
|
+
className: "draft-toggle sdoc-draft-identifier",
|
|
66
|
+
onClick: this.onToggleClick
|
|
67
|
+
}, t('Draft')), isDropdownMenuOpen && /*#__PURE__*/React.createElement("ul", {
|
|
68
|
+
className: "draft-popover list-unstyled m-0"
|
|
69
|
+
}, /*#__PURE__*/React.createElement("li", {
|
|
70
|
+
className: "draft-menu-item",
|
|
71
|
+
onClick: this.unmark
|
|
72
|
+
}, t('Unmark_as_draft'))));
|
|
73
|
+
}
|
|
74
|
+
}]);
|
|
75
|
+
return DraftDropdownMenu;
|
|
76
|
+
}(React.Component);
|
|
77
|
+
export default withTranslation('sdoc-editor')(DraftDropdownMenu);
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
.sdoc-draft-menu {
|
|
2
|
+
position: relative;
|
|
3
|
+
margin-left: 0.5rem;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.sdoc-draft-identifier {
|
|
7
|
+
display: inline-block;
|
|
8
|
+
font-size: 14px;
|
|
9
|
+
color: #888;
|
|
10
|
+
background: #eee;
|
|
11
|
+
padding: 0 8px;
|
|
12
|
+
height: 20px;
|
|
13
|
+
line-height: 20px;
|
|
14
|
+
border-radius: 10px;
|
|
15
|
+
cursor: pointer;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.sdoc-draft-identifier:hover {
|
|
19
|
+
background: #dbdbdb;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.sdoc-draft-menu .draft-popover {
|
|
23
|
+
position: absolute;
|
|
24
|
+
top: 25px;
|
|
25
|
+
left: 0;
|
|
26
|
+
width: 178px;
|
|
27
|
+
background-color: #fff;
|
|
28
|
+
border: 1px solid #e5e6e8;
|
|
29
|
+
border-radius: 2px;
|
|
30
|
+
padding: 8px 0;
|
|
31
|
+
box-shadow: 0 0 10px #e5e6e8;
|
|
32
|
+
z-index: 10;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.sdoc-draft-menu .draft-popover .draft-menu-item {
|
|
36
|
+
cursor: pointer;
|
|
37
|
+
width: 100%;
|
|
38
|
+
padding: 4px 12px;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.sdoc-draft-menu .draft-popover .draft-menu-item:hover {
|
|
42
|
+
background-color: rgb(245, 245, 245);
|
|
43
|
+
}
|
|
@@ -12,12 +12,15 @@ var MoreDropdownMenu = /*#__PURE__*/function (_React$Component) {
|
|
|
12
12
|
_classCallCheck(this, MoreDropdownMenu);
|
|
13
13
|
_this = _super.call(this, props);
|
|
14
14
|
_this.registerEventHandler = function () {
|
|
15
|
-
document.addEventListener('click', _this.onHideMoreDropdownMenu);
|
|
15
|
+
document.addEventListener('click', _this.onHideMoreDropdownMenu, true);
|
|
16
16
|
};
|
|
17
17
|
_this.unregisterEventHandler = function () {
|
|
18
|
-
document.removeEventListener('click', _this.onHideMoreDropdownMenu);
|
|
18
|
+
document.removeEventListener('click', _this.onHideMoreDropdownMenu, true);
|
|
19
19
|
};
|
|
20
|
-
_this.onHideMoreDropdownMenu = function () {
|
|
20
|
+
_this.onHideMoreDropdownMenu = function (e) {
|
|
21
|
+
var menu = _this.menu;
|
|
22
|
+
var clickIsInMenu = menu && menu.contains(e.target) && menu !== e.target;
|
|
23
|
+
if (clickIsInMenu) return;
|
|
21
24
|
_this.setState({
|
|
22
25
|
isDropdownMenuOpen: false
|
|
23
26
|
}, function () {
|
|
@@ -42,6 +45,9 @@ var MoreDropdownMenu = /*#__PURE__*/function (_React$Component) {
|
|
|
42
45
|
});
|
|
43
46
|
}
|
|
44
47
|
};
|
|
48
|
+
_this.setMenuRef = function (ref) {
|
|
49
|
+
_this.menu = ref;
|
|
50
|
+
};
|
|
45
51
|
_this.state = {
|
|
46
52
|
isDropdownMenuOpen: false
|
|
47
53
|
};
|
|
@@ -59,6 +65,7 @@ var MoreDropdownMenu = /*#__PURE__*/function (_React$Component) {
|
|
|
59
65
|
}, /*#__PURE__*/React.createElement("span", {
|
|
60
66
|
className: "sdocfont sdoc-more"
|
|
61
67
|
})), isDropdownMenuOpen && /*#__PURE__*/React.createElement("div", {
|
|
68
|
+
ref: this.setMenuRef,
|
|
62
69
|
className: "more-popover"
|
|
63
70
|
}, this.props.children));
|
|
64
71
|
}
|
package/dist/constants/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export var EXTERNAL_EVENT = {
|
|
2
2
|
INTERNAL_LINK_CLICK: 'internal_link_click',
|
|
3
3
|
TOGGLE_STAR: 'toggle_star',
|
|
4
|
+
UNMARK_AS_DRAFT: 'unmark_as_draft',
|
|
4
5
|
CANCEL_TABLE_SELECT_RANGE: 'cancel_table_select_range'
|
|
5
6
|
};
|
|
6
7
|
export var PAGE_EDIT_AREA_WIDTH = 672; // 672 = 794 - 2[borderLeft + borderRight] - 120[paddingLeft + paddingRight]
|
|
@@ -12,6 +12,7 @@ import DiffViewer from './diff-viewer';
|
|
|
12
12
|
import '../assets/css/simple-editor.css';
|
|
13
13
|
var SimpleEditor = function SimpleEditor(_ref) {
|
|
14
14
|
var isStarred = _ref.isStarred,
|
|
15
|
+
isDraft = _ref.isDraft,
|
|
15
16
|
t = _ref.t;
|
|
16
17
|
var _useState = useState(true),
|
|
17
18
|
_useState2 = _slicedToArray(_useState, 2),
|
|
@@ -123,6 +124,7 @@ var SimpleEditor = function SimpleEditor(_ref) {
|
|
|
123
124
|
}
|
|
124
125
|
return /*#__PURE__*/React.createElement(Layout, null, /*#__PURE__*/React.createElement(Header, null, /*#__PURE__*/React.createElement(DocInfo, {
|
|
125
126
|
isStarred: isStarred,
|
|
127
|
+
isDraft: isDraft,
|
|
126
128
|
isEditMode: !isShowChanges
|
|
127
129
|
}), /*#__PURE__*/React.createElement(DocOperations, {
|
|
128
130
|
isShowChanges: isShowChanges,
|
package/package.json
CHANGED
|
@@ -260,5 +260,7 @@
|
|
|
260
260
|
"Start_revise": "Start revise",
|
|
261
261
|
"Failed_to_execute_operation_on_server": "Failed to execute operation on server",
|
|
262
262
|
"Start_revise_tip": "Create a temporary document and modify on it, merge it back after reviewing changes",
|
|
263
|
-
"Load_doc_content_error": "Load doc content error"
|
|
263
|
+
"Load_doc_content_error": "Load doc content error",
|
|
264
|
+
"Draft": "Draft",
|
|
265
|
+
"Unmark_as_draft": "Unmark as draft"
|
|
264
266
|
}
|
|
@@ -260,5 +260,7 @@
|
|
|
260
260
|
"Start_revise": "开始修订",
|
|
261
261
|
"Failed_to_execute_operation_on_server": "无法在服务器上执行操作",
|
|
262
262
|
"Start_revise_tip": "创建一个临时文档并对其进行修订,检查更改后将其合并回来",
|
|
263
|
-
"Load_doc_content_error": "加载文档内容错误"
|
|
263
|
+
"Load_doc_content_error": "加载文档内容错误",
|
|
264
|
+
"Draft": "草稿",
|
|
265
|
+
"Unmark_as_draft": "取消草稿标记"
|
|
264
266
|
}
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
.display-outline-icon {
|
|
2
|
-
line-height: 1;
|
|
3
|
-
font-size: 14px;
|
|
4
|
-
color: #888;
|
|
5
|
-
cursor: pointer;
|
|
6
|
-
width: 28px;
|
|
7
|
-
height: 28px;
|
|
8
|
-
background: #fff;
|
|
9
|
-
border-radius: 0 50% 50% 0;
|
|
10
|
-
box-shadow: 0 0 6px rgba(0,0,0, 0.12);
|
|
11
|
-
display: flex;
|
|
12
|
-
align-items: center;
|
|
13
|
-
justify-content: center;
|
|
14
|
-
margin: 20px 230px 0 0;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
.display-outline-icon:hover {
|
|
18
|
-
color: #333;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
.sdoc-outline {
|
|
22
|
-
font-size: 14px;
|
|
23
|
-
width: 220px;
|
|
24
|
-
margin: 20px 30px 20px 16px;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
.sdoc-outline-header {
|
|
28
|
-
color: #999;
|
|
29
|
-
border-bottom: 1px solid #dbdbdb;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
.font-size-inherit {
|
|
33
|
-
font-size: inherit;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
.sdoc-outline-header .close-icon {
|
|
37
|
-
cursor: pointer;
|
|
38
|
-
font-size: 14px;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
.sdoc-outline-header .close-icon:hover {
|
|
42
|
-
color: #555;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
.outline-item {
|
|
46
|
-
padding: 4px 0;
|
|
47
|
-
cursor: pointer;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
.outline-item.active {
|
|
51
|
-
color: #ff8000;
|
|
52
|
-
}
|
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
|
|
2
|
-
import _createClass from "@babel/runtime/helpers/esm/createClass";
|
|
3
|
-
import _inherits from "@babel/runtime/helpers/esm/inherits";
|
|
4
|
-
import _createSuper from "@babel/runtime/helpers/esm/createSuper";
|
|
5
|
-
import React from 'react';
|
|
6
|
-
import { withTranslation } from 'react-i18next';
|
|
7
|
-
import { UncontrolledTooltip } from 'reactstrap';
|
|
8
|
-
import './assets/css/outline.css';
|
|
9
|
-
var SDocOutline = /*#__PURE__*/function (_React$PureComponent) {
|
|
10
|
-
_inherits(SDocOutline, _React$PureComponent);
|
|
11
|
-
var _super = _createSuper(SDocOutline);
|
|
12
|
-
function SDocOutline(props) {
|
|
13
|
-
var _this;
|
|
14
|
-
_classCallCheck(this, SDocOutline);
|
|
15
|
-
_this = _super.call(this, props);
|
|
16
|
-
_this.toggleShow = function () {
|
|
17
|
-
var docUuid = _this.props.docUuid;
|
|
18
|
-
_this.setState({
|
|
19
|
-
isShown: !_this.state.isShown
|
|
20
|
-
}, function () {
|
|
21
|
-
var currentValue = localStorage.getItem(docUuid);
|
|
22
|
-
var options = currentValue ? JSON.parse(currentValue) : {};
|
|
23
|
-
options['outlineOpen'] = _this.state.isShown;
|
|
24
|
-
localStorage.setItem(docUuid, JSON.stringify(options));
|
|
25
|
-
});
|
|
26
|
-
};
|
|
27
|
-
var _currentValue = localStorage.getItem(props.docUuid);
|
|
28
|
-
var _options = _currentValue ? JSON.parse(_currentValue) : {};
|
|
29
|
-
var _options$outlineOpen = _options.outlineOpen,
|
|
30
|
-
outlineOpen = _options$outlineOpen === void 0 ? false : _options$outlineOpen;
|
|
31
|
-
_this.state = {
|
|
32
|
-
isShown: outlineOpen
|
|
33
|
-
};
|
|
34
|
-
return _this;
|
|
35
|
-
}
|
|
36
|
-
_createClass(SDocOutline, [{
|
|
37
|
-
key: "render",
|
|
38
|
-
value: function render() {
|
|
39
|
-
var _this$props = this.props,
|
|
40
|
-
doc = _this$props.doc,
|
|
41
|
-
t = _this$props.t;
|
|
42
|
-
var isShown = this.state.isShown;
|
|
43
|
-
var list = doc.filter(function (item) {
|
|
44
|
-
return item.type == 'header2' || item.type == 'header3';
|
|
45
|
-
});
|
|
46
|
-
return isShown ? /*#__PURE__*/React.createElement("div", {
|
|
47
|
-
className: "sdoc-outline d-flex flex-column"
|
|
48
|
-
}, /*#__PURE__*/React.createElement("div", {
|
|
49
|
-
className: "sdoc-outline-header d-flex align-items-center justify-content-between py-1"
|
|
50
|
-
}, /*#__PURE__*/React.createElement("h2", {
|
|
51
|
-
className: "font-weight-normal m-0 font-size-inherit"
|
|
52
|
-
}, t('Outline')), /*#__PURE__*/React.createElement("span", {
|
|
53
|
-
onClick: this.toggleShow,
|
|
54
|
-
className: "close-icon sdocfont sdoc-cancel"
|
|
55
|
-
})), list.length ? /*#__PURE__*/React.createElement("ol", {
|
|
56
|
-
className: "list-unstyled py-2 flex-fill o-auto"
|
|
57
|
-
}, list.map(function (item, index) {
|
|
58
|
-
return /*#__PURE__*/React.createElement(OutlineItem, {
|
|
59
|
-
key: index,
|
|
60
|
-
item: item
|
|
61
|
-
});
|
|
62
|
-
})) : /*#__PURE__*/React.createElement("p", {
|
|
63
|
-
className: "mt-4 text-secondary"
|
|
64
|
-
}, t('Headings_you_add_to_the_document_will_appear_here'))) : /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("span", {
|
|
65
|
-
onClick: this.toggleShow,
|
|
66
|
-
id: "display-outline-icon",
|
|
67
|
-
className: "display-outline-icon sdocfont sdoc-table-of-content",
|
|
68
|
-
style: {
|
|
69
|
-
'marginRight': (window.innerWidth - 794) / 2 - 36
|
|
70
|
-
}
|
|
71
|
-
}), /*#__PURE__*/React.createElement(UncontrolledTooltip, {
|
|
72
|
-
placement: "right",
|
|
73
|
-
target: "display-outline-icon"
|
|
74
|
-
}, t('Outline')));
|
|
75
|
-
}
|
|
76
|
-
}]);
|
|
77
|
-
return SDocOutline;
|
|
78
|
-
}(React.PureComponent);
|
|
79
|
-
var OutlineItem = /*#__PURE__*/function (_React$PureComponent2) {
|
|
80
|
-
_inherits(OutlineItem, _React$PureComponent2);
|
|
81
|
-
var _super2 = _createSuper(OutlineItem);
|
|
82
|
-
function OutlineItem(props) {
|
|
83
|
-
var _this2;
|
|
84
|
-
_classCallCheck(this, OutlineItem);
|
|
85
|
-
_this2 = _super2.call(this, props);
|
|
86
|
-
_this2.onItemClick = function () {
|
|
87
|
-
var item = _this2.props.item;
|
|
88
|
-
var id = item.id;
|
|
89
|
-
document.getElementById(id).scrollIntoView();
|
|
90
|
-
};
|
|
91
|
-
_this2.onMouseOver = function () {
|
|
92
|
-
_this2.setState({
|
|
93
|
-
isHighlighted: true
|
|
94
|
-
});
|
|
95
|
-
};
|
|
96
|
-
_this2.onMouseOut = function () {
|
|
97
|
-
_this2.setState({
|
|
98
|
-
isHighlighted: false
|
|
99
|
-
});
|
|
100
|
-
};
|
|
101
|
-
_this2.state = {
|
|
102
|
-
isHighlighted: false
|
|
103
|
-
};
|
|
104
|
-
return _this2;
|
|
105
|
-
}
|
|
106
|
-
_createClass(OutlineItem, [{
|
|
107
|
-
key: "render",
|
|
108
|
-
value: function render() {
|
|
109
|
-
var isHighlighted = this.state.isHighlighted;
|
|
110
|
-
var item = this.props.item;
|
|
111
|
-
var type = item.type,
|
|
112
|
-
children = item.children;
|
|
113
|
-
return /*#__PURE__*/React.createElement("li", {
|
|
114
|
-
className: "outline-item ".concat(type == 'header3' ? 'pl-5' : '', " ").concat(isHighlighted ? 'active' : ''),
|
|
115
|
-
onClick: this.onItemClick,
|
|
116
|
-
onMouseOver: this.onMouseOver,
|
|
117
|
-
onMouseOut: this.onMouseOut
|
|
118
|
-
}, children.map(function (child) {
|
|
119
|
-
return child.text;
|
|
120
|
-
}).join(''));
|
|
121
|
-
}
|
|
122
|
-
}]);
|
|
123
|
-
return OutlineItem;
|
|
124
|
-
}(React.PureComponent);
|
|
125
|
-
export default withTranslation('sdoc-editor')(SDocOutline);
|