@seafile/sdoc-editor 0.4.12 → 0.4.14
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 +1 -1
- package/dist/basic-sdk/comment/components/global-comment/index.js +2 -2
- package/dist/basic-sdk/extension/constants/font.js +0 -1
- package/dist/basic-sdk/extension/plugins/blockquote/plugin.js +17 -6
- package/dist/basic-sdk/extension/plugins/blockquote/render-elem.js +1 -2
- package/dist/basic-sdk/extension/plugins/callout/plugin.js +21 -1
- package/dist/basic-sdk/extension/plugins/callout/render-elem/index.js +0 -3
- package/dist/basic-sdk/extension/plugins/check-list/render-elem.js +1 -2
- package/dist/basic-sdk/extension/plugins/code-block/helpers.js +0 -2
- package/dist/basic-sdk/extension/plugins/code-block/render-elem.js +1 -4
- package/dist/basic-sdk/extension/plugins/file-link/helpers.js +0 -1
- package/dist/basic-sdk/extension/plugins/header/render-elem.js +2 -6
- package/dist/basic-sdk/extension/plugins/html/helper.js +0 -1
- package/dist/basic-sdk/extension/plugins/image/hover-menu/index.js +4 -1
- package/dist/basic-sdk/extension/plugins/image/plugin.js +2 -1
- package/dist/basic-sdk/extension/plugins/link/helpers.js +0 -1
- package/dist/basic-sdk/extension/plugins/list/render-elem.js +2 -5
- package/dist/basic-sdk/extension/plugins/paragraph/render-elem.js +1 -4
- package/dist/basic-sdk/extension/plugins/sdoc-link/helpers.js +0 -1
- package/dist/basic-sdk/extension/plugins/search-replace/popover/index.js +1 -1
- package/dist/basic-sdk/extension/plugins/table/helpers.js +0 -1
- package/dist/basic-sdk/extension/plugins/table/plugin.js +33 -3
- package/dist/basic-sdk/extension/plugins/table/render/index.js +25 -28
- package/dist/basic-sdk/extension/plugins/table/render/table-root.js +0 -1
- package/dist/basic-sdk/extension/render/helper.js +1 -0
- package/dist/basic-sdk/extension/toolbar/side-toolbar/helpers.js +0 -1
- package/dist/basic-sdk/extension/toolbar/side-toolbar/transform-menus.js +10 -2
- package/dist/basic-sdk/utils/event-handler.js +1 -0
- package/package.json +1 -1
- package/public/locales/cs/sdoc-editor.json +1 -1
- package/public/locales/de/sdoc-editor.json +1 -1
- package/public/locales/en/sdoc-editor.json +1 -1
- package/public/locales/es/sdoc-editor.json +1 -1
- package/public/locales/fr/sdoc-editor.json +1 -1
- package/public/locales/it/sdoc-editor.json +1 -1
- package/public/locales/ru/sdoc-editor.json +1 -1
- package/public/locales/zh_CN/sdoc-editor.json +2 -2
|
@@ -78,6 +78,7 @@ const GlobalComment = _ref => {
|
|
|
78
78
|
setActiveComment(comment);
|
|
79
79
|
deleteUnseenNotifications && deleteUnseenNotifications(comment);
|
|
80
80
|
if (comment.detail.element_id === DOC_COMMENT_ELEMENT_ID) return;
|
|
81
|
+
if (!element) return;
|
|
81
82
|
const elementDom = ReactEditor.toDOMNode(editor, element, scrollRef);
|
|
82
83
|
scrollRef.current.scrollTop = elementDom.offsetTop - scrollRef.current.clientHeight / 3;
|
|
83
84
|
focusToCommentElement(editor, element);
|
|
@@ -150,8 +151,7 @@ const GlobalComment = _ref => {
|
|
|
150
151
|
className: "sdoc-comment-list-container"
|
|
151
152
|
}, Array.isArray(commentList) && commentList.map(comment => {
|
|
152
153
|
const elementId = comment.detail.element_id;
|
|
153
|
-
const element = getNodeById(editor.children, elementId);
|
|
154
|
-
if (!element && elementId !== DOC_COMMENT_ELEMENT_ID) return null;
|
|
154
|
+
const element = elementId !== DOC_COMMENT_ELEMENT_ID ? getNodeById(editor.children, elementId) : null;
|
|
155
155
|
const isActive = activeComment && activeComment.id === comment.id;
|
|
156
156
|
return /*#__PURE__*/React.createElement(CommentItemWrapper, {
|
|
157
157
|
key: comment.id,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Editor, Element, Transforms, Node, Path } from '@seafile/slate';
|
|
2
|
-
import { focusEditor, generateDefaultText, getSelectedNodeByType, isSelectionAtBlockStart } from '../../core';
|
|
2
|
+
import { focusEditor, generateDefaultText, generateEmptyElement, getSelectedNodeByType, getSelectedNodeEntryByType, isBlockAboveEmpty, isSelectionAtBlockStart } from '../../core';
|
|
3
3
|
import { BLOCKQUOTE, PARAGRAPH, CODE_BLOCK, TABLE } from '../../constants';
|
|
4
|
-
import {
|
|
4
|
+
import { getFormattedElements, getFormattedRestElements } from './helpers';
|
|
5
5
|
const withBlockquote = editor => {
|
|
6
6
|
const {
|
|
7
7
|
insertBreak,
|
|
@@ -54,23 +54,34 @@ const withBlockquote = editor => {
|
|
|
54
54
|
deleteBackward(unit);
|
|
55
55
|
return;
|
|
56
56
|
}
|
|
57
|
-
const
|
|
58
|
-
if (
|
|
57
|
+
const blockQuoteEntry = getSelectedNodeEntryByType(editor, BLOCKQUOTE);
|
|
58
|
+
if (blockQuoteEntry) {
|
|
59
59
|
const [currentLineEntry] = Editor.nodes(newEditor, {
|
|
60
60
|
match: n => Element.isElement(n) && n.type === PARAGRAPH,
|
|
61
61
|
mode: 'lowest'
|
|
62
62
|
});
|
|
63
63
|
if (!currentLineEntry) return deleteBackward(unit);
|
|
64
64
|
const currentLineIndex = currentLineEntry[1].slice(-1)[0];
|
|
65
|
-
|
|
66
|
-
|
|
65
|
+
// Transforms to paragraph when Select at the beginning of the first line
|
|
66
|
+
if (currentLineIndex === 0 && isBlockAboveEmpty(newEditor)) {
|
|
67
|
+
const emptyParagraph = generateEmptyElement(PARAGRAPH);
|
|
68
|
+
Transforms.removeNodes(editor, {
|
|
69
|
+
at: currentLineEntry[1]
|
|
70
|
+
});
|
|
71
|
+
Transforms.insertNodes(newEditor, emptyParagraph, {
|
|
72
|
+
at: blockQuoteEntry[1]
|
|
73
|
+
});
|
|
74
|
+
const previous = Path.previous(blockQuoteEntry[1]);
|
|
75
|
+
focusEditor(newEditor, Path.next(previous).concat(0));
|
|
67
76
|
return;
|
|
68
77
|
}
|
|
78
|
+
// Merge with previous line when Select at the beginning of the line
|
|
69
79
|
if (isSelectionAtBlockStart(editor)) {
|
|
70
80
|
const lineText = Node.string(currentLineEntry[0]);
|
|
71
81
|
const previousNodeEntry = Editor.previous(editor, {
|
|
72
82
|
at: currentLineEntry[1]
|
|
73
83
|
});
|
|
84
|
+
if (!previousNodeEntry) return;
|
|
74
85
|
const focusPoint = Editor.end(newEditor, previousNodeEntry[1]);
|
|
75
86
|
Transforms.insertText(newEditor, lineText, {
|
|
76
87
|
at: Editor.end(newEditor, previousNodeEntry[1])
|
|
@@ -9,8 +9,7 @@ const renderBlockquote = (props, editor) => {
|
|
|
9
9
|
textAlign: element.align
|
|
10
10
|
};
|
|
11
11
|
return /*#__PURE__*/React.createElement("blockquote", Object.assign({
|
|
12
|
-
"data-id": element.id
|
|
13
|
-
"data-root": "true"
|
|
12
|
+
"data-id": element.id
|
|
14
13
|
}, attributes, {
|
|
15
14
|
style: style
|
|
16
15
|
}), children);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import isHotkey from 'is-hotkey';
|
|
2
|
+
import { Editor, Transforms } from '@seafile/slate';
|
|
2
3
|
import { PARAGRAPH, INSERT_POSITION, CODE_BLOCK } from '../../constants';
|
|
3
4
|
import { isSelectionAtBlockStart } from '../../core';
|
|
4
5
|
import { getCalloutEntry, isCalloutContentEmpty, unwrapCallout } from './helper';
|
|
@@ -52,7 +53,9 @@ const withCallout = editor => {
|
|
|
52
53
|
return insertFragment(data);
|
|
53
54
|
};
|
|
54
55
|
newEditor.onHotKeyDown = event => {
|
|
55
|
-
|
|
56
|
+
const calloutEntry = getCalloutEntry(editor);
|
|
57
|
+
if (calloutEntry) {
|
|
58
|
+
const [, calloutPath] = calloutEntry;
|
|
56
59
|
// Close color picker
|
|
57
60
|
const eventBus = EventBus.getInstance();
|
|
58
61
|
eventBus.dispatch(INTERNAL_EVENT.CLOSE_CALLOUT_COLOR_PICKER);
|
|
@@ -60,9 +63,26 @@ const withCallout = editor => {
|
|
|
60
63
|
insertElement(newEditor, PARAGRAPH, INSERT_POSITION.AFTER);
|
|
61
64
|
return true;
|
|
62
65
|
}
|
|
66
|
+
if (isHotkey('mod+a', event)) {
|
|
67
|
+
event.preventDefault();
|
|
68
|
+
try {
|
|
69
|
+
const startPoint = Editor.start(newEditor, calloutPath);
|
|
70
|
+
const endPoint = Editor.end(newEditor, calloutPath);
|
|
71
|
+
const selectRange = Editor.range(newEditor, startPoint, endPoint);
|
|
72
|
+
Transforms.select(newEditor, selectRange);
|
|
73
|
+
return true;
|
|
74
|
+
} catch (error) {
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
63
78
|
}
|
|
64
79
|
return onHotKeyDown && onHotKeyDown(event);
|
|
65
80
|
};
|
|
81
|
+
newEditor.onCopy = event => {
|
|
82
|
+
if (getCalloutEntry(editor)) {
|
|
83
|
+
event.stopPropagation();
|
|
84
|
+
}
|
|
85
|
+
};
|
|
66
86
|
return newEditor;
|
|
67
87
|
};
|
|
68
88
|
export default withCallout;
|
|
@@ -51,7 +51,6 @@ const renderCallout = (_ref, editor) => {
|
|
|
51
51
|
top: menuTop,
|
|
52
52
|
left: left // left = code-block left distance
|
|
53
53
|
};
|
|
54
|
-
|
|
55
54
|
setPopoverPosition(newMenuPosition);
|
|
56
55
|
}
|
|
57
56
|
}, [isShowColorSelector, readOnly]);
|
|
@@ -82,7 +81,6 @@ const renderCallout = (_ref, editor) => {
|
|
|
82
81
|
top: menuTop,
|
|
83
82
|
left: left // left = callout left distance
|
|
84
83
|
};
|
|
85
|
-
|
|
86
84
|
setPopoverPosition(newMenuPosition);
|
|
87
85
|
setIsShowColorSelector(true);
|
|
88
86
|
}, [readOnly]);
|
|
@@ -100,7 +98,6 @@ const renderCallout = (_ref, editor) => {
|
|
|
100
98
|
}, [editor, element, isFocusOnCallout]);
|
|
101
99
|
return /*#__PURE__*/React.createElement("div", Object.assign({}, attributes, {
|
|
102
100
|
"data-id": element.id,
|
|
103
|
-
"data-root": "true",
|
|
104
101
|
className: "sdoc-callout-white-wrapper",
|
|
105
102
|
onMouseLeave: handleCloseColorSelector
|
|
106
103
|
}), /*#__PURE__*/React.createElement("div", {
|
|
@@ -33,8 +33,7 @@ class CheckListItem extends React.PureComponent {
|
|
|
33
33
|
textAlign: align
|
|
34
34
|
};
|
|
35
35
|
return /*#__PURE__*/React.createElement("div", Object.assign({
|
|
36
|
-
"data-id": id
|
|
37
|
-
"data-root": "true"
|
|
36
|
+
"data-id": id
|
|
38
37
|
}, attributes, {
|
|
39
38
|
className: "sdoc-checkbox-container ".concat(attributes.className),
|
|
40
39
|
style: style
|
|
@@ -23,7 +23,6 @@ export const isMenuDisabled = (editor, readonly) => {
|
|
|
23
23
|
if (isMatch) return false; // enable
|
|
24
24
|
return true; // disable
|
|
25
25
|
};
|
|
26
|
-
|
|
27
26
|
export const getSelectCodeElem = editor => {
|
|
28
27
|
const codeNode = getSelectedNodeByType(editor, CODE_BLOCK);
|
|
29
28
|
if (codeNode == null) return null;
|
|
@@ -63,7 +62,6 @@ export const changeToCodeBlock = function (editor) {
|
|
|
63
62
|
style: {
|
|
64
63
|
white_space: 'nowrap' // default nowrap
|
|
65
64
|
},
|
|
66
|
-
|
|
67
65
|
children: [{
|
|
68
66
|
id: slugid.nice(),
|
|
69
67
|
type: CODE_LINE,
|
|
@@ -81,7 +81,6 @@ const CodeBlock = _ref => {
|
|
|
81
81
|
top: menuTop,
|
|
82
82
|
left: left // left = code-block left distance
|
|
83
83
|
};
|
|
84
|
-
|
|
85
84
|
setMenuPosition(newMenuPosition);
|
|
86
85
|
}
|
|
87
86
|
setShowHoverMenu(true);
|
|
@@ -105,7 +104,6 @@ const CodeBlock = _ref => {
|
|
|
105
104
|
top: menuTop,
|
|
106
105
|
left: left // left = code-block left distance
|
|
107
106
|
};
|
|
108
|
-
|
|
109
107
|
setMenuPosition(newMenuPosition);
|
|
110
108
|
}
|
|
111
109
|
}, [readOnly, showHoverMenu]);
|
|
@@ -134,8 +132,7 @@ const CodeBlock = _ref => {
|
|
|
134
132
|
EventBus.getInstance().dispatch(INTERNAL_EVENT.UPDATE_SEARCH_REPLACE_HIGHLIGHT);
|
|
135
133
|
};
|
|
136
134
|
return /*#__PURE__*/React.createElement("div", Object.assign({
|
|
137
|
-
"data-id": element.id
|
|
138
|
-
"data-root": "true"
|
|
135
|
+
"data-id": element.id
|
|
139
136
|
}, attributes, {
|
|
140
137
|
className: "sdoc-code-block-container ".concat(attributes.className),
|
|
141
138
|
onClick: onFocusCodeBlock,
|
|
@@ -14,8 +14,7 @@ export const renderTitle = (props, editor) => {
|
|
|
14
14
|
textAlign: element.align
|
|
15
15
|
};
|
|
16
16
|
return /*#__PURE__*/React.createElement("div", Object.assign({
|
|
17
|
-
"data-id": element.id
|
|
18
|
-
"data-root": "true"
|
|
17
|
+
"data-id": element.id
|
|
19
18
|
}, attributes, {
|
|
20
19
|
className: "sdoc-header-title ".concat(attributes.className),
|
|
21
20
|
style: _objectSpread({}, style)
|
|
@@ -33,8 +32,7 @@ export const renderSubtitle = (props, editor) => {
|
|
|
33
32
|
textAlign: element.align
|
|
34
33
|
};
|
|
35
34
|
return /*#__PURE__*/React.createElement("div", Object.assign({
|
|
36
|
-
"data-id": element.id
|
|
37
|
-
"data-root": "true"
|
|
35
|
+
"data-id": element.id
|
|
38
36
|
}, attributes, {
|
|
39
37
|
className: "sdoc-header-subtitle ".concat(attributes.className),
|
|
40
38
|
style: _objectSpread({}, style)
|
|
@@ -65,8 +63,6 @@ export const renderHeader = (props, editor) => {
|
|
|
65
63
|
return /*#__PURE__*/React.createElement("div", Object.assign({
|
|
66
64
|
"data-id": element.id,
|
|
67
65
|
id: element.id // used for click left outline item, page scroll this element
|
|
68
|
-
,
|
|
69
|
-
"data-root": "true"
|
|
70
66
|
}, attributes, {
|
|
71
67
|
className: "sdoc-header-".concat(level, " ").concat(attributes.className),
|
|
72
68
|
style: _objectSpread({
|
|
@@ -89,7 +89,10 @@ const ImageHoverMenu = _ref => {
|
|
|
89
89
|
at: [p]
|
|
90
90
|
});
|
|
91
91
|
p = p + 1;
|
|
92
|
-
if (!afterLeaf.every(item =>
|
|
92
|
+
if (!afterLeaf.every(item => {
|
|
93
|
+
var _item$text;
|
|
94
|
+
return (item === null || item === void 0 ? void 0 : (_item$text = item.text) === null || _item$text === void 0 ? void 0 : _item$text.length) === 0;
|
|
95
|
+
})) {
|
|
93
96
|
afterNode = generateEmptyElement(PARAGRAPH);
|
|
94
97
|
afterNode.children = afterLeaf;
|
|
95
98
|
Transforms.insertNodes(editor, afterNode, {
|
|
@@ -115,7 +115,8 @@ const withImage = editor => {
|
|
|
115
115
|
distance: 2
|
|
116
116
|
});
|
|
117
117
|
const [node, path] = Editor.node(editor, [point.path[0], point.path[1]]);
|
|
118
|
-
|
|
118
|
+
const isPerviousNodeImage = node.type === IMAGE;
|
|
119
|
+
if (isPerviousNodeImage && Range.isCollapsed(selection) && isBlockAboveEmpty(editor) && !Path.isCommon(path, selection.anchor.path)) {
|
|
119
120
|
deleteBackward(unit);
|
|
120
121
|
focusEditor(newEditor, Editor.end(newEditor, focusPoint));
|
|
121
122
|
return;
|
|
@@ -10,7 +10,6 @@ const renderList = (props, editor) => {
|
|
|
10
10
|
const Tag = node.type === ORDERED_LIST ? 'ol' : 'ul';
|
|
11
11
|
return /*#__PURE__*/React.createElement(Tag, Object.assign({
|
|
12
12
|
"data-id": node.id,
|
|
13
|
-
"data-root": "true",
|
|
14
13
|
className: "list-container d-flex flex-column"
|
|
15
14
|
}, attributes), children);
|
|
16
15
|
};
|
|
@@ -36,8 +35,7 @@ const renderListItem = (props, editor) => {
|
|
|
36
35
|
}
|
|
37
36
|
const isBlod = element.children[0].children.every(item => item.bold === true);
|
|
38
37
|
return /*#__PURE__*/React.createElement("li", Object.assign({
|
|
39
|
-
"data-id": element.id
|
|
40
|
-
"data-root": "true"
|
|
38
|
+
"data-id": element.id
|
|
41
39
|
}, attributes, {
|
|
42
40
|
className: classnames(className, {
|
|
43
41
|
'sdoc-li-blod': isBlod
|
|
@@ -51,8 +49,7 @@ const renderListLic = (props, editor) => {
|
|
|
51
49
|
element
|
|
52
50
|
} = props;
|
|
53
51
|
return /*#__PURE__*/React.createElement("div", Object.assign({
|
|
54
|
-
"data-id": element.id
|
|
55
|
-
"data-root": "true"
|
|
52
|
+
"data-id": element.id
|
|
56
53
|
}, attributes), children);
|
|
57
54
|
};
|
|
58
55
|
export { renderList, renderListItem, renderListLic };
|
|
@@ -26,12 +26,9 @@ const Paragraph = _ref => {
|
|
|
26
26
|
textAlign: element.align,
|
|
27
27
|
paddingLeft: indent ? '28px' : ''
|
|
28
28
|
};
|
|
29
|
-
const newAttributes = _objectSpread(_objectSpread({}, attributes), typeof attributes.onMouseEnter === 'function' && {
|
|
30
|
-
'data-root': 'true'
|
|
31
|
-
});
|
|
32
29
|
return /*#__PURE__*/React.createElement("p", Object.assign({
|
|
33
30
|
"data-id": element.id
|
|
34
|
-
},
|
|
31
|
+
}, attributes, {
|
|
35
32
|
style: _objectSpread({
|
|
36
33
|
position: isShowPlaceHolder ? 'relative' : ''
|
|
37
34
|
}, style)
|
|
@@ -188,7 +188,7 @@ const SearchReplacePopover = _ref => {
|
|
|
188
188
|
disabled: !highlightInfos.length,
|
|
189
189
|
onClick: handleLast,
|
|
190
190
|
className: "btn btn-secondary"
|
|
191
|
-
}, t('
|
|
191
|
+
}, t('Prevs')), /*#__PURE__*/React.createElement("button", {
|
|
192
192
|
disabled: !highlightInfos.length,
|
|
193
193
|
onClick: handleNext,
|
|
194
194
|
className: "btn btn-secondary"
|
|
@@ -175,7 +175,6 @@ export const isAllInTable = editor => {
|
|
|
175
175
|
if (firstSelectedNode.type !== ELEMENT_TYPE.TABLE) return false;
|
|
176
176
|
return selectedNodes.slice(1).every(node => [ELEMENT_TYPE.TABLE_ROW, ELEMENT_TYPE.TABLE_CELL].includes(node.type)); // same table element
|
|
177
177
|
};
|
|
178
|
-
|
|
179
178
|
export const setCellStyle = (editor, style) => {
|
|
180
179
|
// Select single cell
|
|
181
180
|
if (ObjectUtils.isSameObject(editor.tableSelectedRange, EMPTY_SELECTED_RANGE)) {
|
|
@@ -88,17 +88,47 @@ const withTable = editor => {
|
|
|
88
88
|
if (selection) {
|
|
89
89
|
const before = Editor.before(newEditor, selection);
|
|
90
90
|
if (before) {
|
|
91
|
-
// If the current is not a table and the previous one is a table, no deletion will be performed. Otherwise, the last cell of the table will be deleted
|
|
92
|
-
// If deleting node is empty check-list, order-list, unordered-list, change to paragraph
|
|
93
91
|
const isTableOnBeforeLocation = isTableLocation(newEditor, before);
|
|
94
92
|
const isTableOnCurSelection = isTableLocation(newEditor, selection);
|
|
93
|
+
// If the current is not a table and the previous one is a table.
|
|
95
94
|
if (isTableOnBeforeLocation && !isTableOnCurSelection) {
|
|
96
|
-
const transformTypes = [CHECK_LIST_ITEM, ORDERED_LIST, UNORDERED_LIST];
|
|
97
95
|
const [currentNodeEntry] = Editor.nodes(editor, {
|
|
98
96
|
match: n => Element.isElement(n) && !Editor.parent(n, ReactEditor.findPath(editor, n))[1].length
|
|
99
97
|
});
|
|
100
98
|
if (!currentNodeEntry) return;
|
|
101
99
|
const [currentNode, currentPath] = Array.from(currentNodeEntry);
|
|
100
|
+
|
|
101
|
+
// If the current is paragraph.
|
|
102
|
+
if (currentNode.type === PARAGRAPH) {
|
|
103
|
+
const {
|
|
104
|
+
path
|
|
105
|
+
} = before;
|
|
106
|
+
Transforms.select(editor, {
|
|
107
|
+
anchor: {
|
|
108
|
+
offset: 0,
|
|
109
|
+
path: [path[0], 0, 0, 0]
|
|
110
|
+
},
|
|
111
|
+
focus: {
|
|
112
|
+
offset: 0,
|
|
113
|
+
path: [path[0], 0, 0, 0]
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
const beforeTable = Editor.node(editor, [path[0]]);
|
|
117
|
+
const beforeRow = Editor.node(editor, [path[0], path[1]]);
|
|
118
|
+
const tableSize = [beforeTable[0].children.length, beforeRow[0].children.length];
|
|
119
|
+
const allTableRange = {
|
|
120
|
+
minRowIndex: 0,
|
|
121
|
+
maxRowIndex: tableSize[0] - 1,
|
|
122
|
+
minColIndex: 0,
|
|
123
|
+
maxColIndex: tableSize[1] - 1
|
|
124
|
+
};
|
|
125
|
+
newEditor.tableSelectedRange = allTableRange;
|
|
126
|
+
eventBus.dispatch(INTERNAL_EVENT.SET_TABLE_SELECT_RANGE, beforeTable[0], allTableRange);
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// If deleting node is empty check-list, order-list, unordered-list, change to paragraph
|
|
131
|
+
const transformTypes = [CHECK_LIST_ITEM, ORDERED_LIST, UNORDERED_LIST];
|
|
102
132
|
if (transformTypes.includes(currentNode.type)) {
|
|
103
133
|
Transforms.delete(newEditor, {
|
|
104
134
|
at: currentPath
|
|
@@ -59,19 +59,33 @@ const Table = _ref => {
|
|
|
59
59
|
|
|
60
60
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
61
61
|
}, []);
|
|
62
|
+
const setSelectedRangeByClick = useCallback(range => {
|
|
63
|
+
setSelectedRange(range);
|
|
64
|
+
setTableSelectedRange(editor, range);
|
|
65
|
+
const {
|
|
66
|
+
maxRowIndex,
|
|
67
|
+
maxColIndex
|
|
68
|
+
} = range;
|
|
69
|
+
const selection = {
|
|
70
|
+
offset: 0,
|
|
71
|
+
path: [...path, maxRowIndex, maxColIndex, 0]
|
|
72
|
+
};
|
|
73
|
+
Transforms.setSelection(editor, {
|
|
74
|
+
anchor: selection,
|
|
75
|
+
focus: selection
|
|
76
|
+
});
|
|
77
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
78
|
+
}, [editor, path]);
|
|
62
79
|
useEffect(() => {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
|
|
80
|
+
const eventBus = EventBus.getInstance();
|
|
81
|
+
const cancelTableSelectRangeSubscribe = eventBus.subscribe(INTERNAL_EVENT.CANCEL_TABLE_SELECT_RANGE, clearRange);
|
|
82
|
+
const setTableSelectRangeSubscribe = eventBus.subscribe(INTERNAL_EVENT.SET_TABLE_SELECT_RANGE, setRange);
|
|
83
|
+
return () => {
|
|
84
|
+
cancelTableSelectRangeSubscribe();
|
|
85
|
+
setTableSelectRangeSubscribe();
|
|
86
|
+
};
|
|
73
87
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
74
|
-
}, [
|
|
88
|
+
}, []);
|
|
75
89
|
useEffect(() => {
|
|
76
90
|
setColumns(getTableColumns(editor, element));
|
|
77
91
|
if (isSettingSelectRange) {
|
|
@@ -150,23 +164,6 @@ const Table = _ref => {
|
|
|
150
164
|
|
|
151
165
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
152
166
|
}, []);
|
|
153
|
-
const setSelectedRangeByClick = useCallback(range => {
|
|
154
|
-
setSelectedRange(range);
|
|
155
|
-
setTableSelectedRange(editor, range);
|
|
156
|
-
const {
|
|
157
|
-
maxRowIndex,
|
|
158
|
-
maxColIndex
|
|
159
|
-
} = range;
|
|
160
|
-
const selection = {
|
|
161
|
-
offset: 0,
|
|
162
|
-
path: [...path, maxRowIndex, maxColIndex, 0]
|
|
163
|
-
};
|
|
164
|
-
Transforms.setSelection(editor, {
|
|
165
|
-
anchor: selection,
|
|
166
|
-
focus: selection
|
|
167
|
-
});
|
|
168
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
169
|
-
}, [editor, path]);
|
|
170
167
|
const tableContainerClassName = classnames('sdoc-table-container position-relative', attributes.className, className, {
|
|
171
168
|
'sdoc-table-selected': isSelected,
|
|
172
169
|
'sdoc-table-selected-range': !ObjectUtils.isSameObject(selectedRange, EMPTY_SELECTED_RANGE)
|
|
@@ -30,7 +30,6 @@ const TableRoot = _ref => {
|
|
|
30
30
|
className: classnames('sdoc-table-wrapper position-relative', attributes.className, {
|
|
31
31
|
'scroll': allWidth > editor.width
|
|
32
32
|
}),
|
|
33
|
-
"data-root": "true",
|
|
34
33
|
style: _objectSpread(_objectSpread({}, attributes.style), {}, {
|
|
35
34
|
maxWidth: editor.width ? editor.width : '100%'
|
|
36
35
|
})
|
|
@@ -18,4 +18,5 @@ const isNeedAddMouseEnterEvent = (editor, element) => {
|
|
|
18
18
|
export const setMouseEnter = (editor, element, attributes) => {
|
|
19
19
|
if (!isNeedAddMouseEnterEvent(editor, element)) return;
|
|
20
20
|
attributes['onMouseEnter'] = e => onMouseEnter(e, element);
|
|
21
|
+
attributes['data-root'] = 'true';
|
|
21
22
|
};
|
|
@@ -92,7 +92,6 @@ export const getDomTopHeight = (dom, slateNode) => {
|
|
|
92
92
|
if (ADD_POSITION_OFFSET_TYPE.includes(slateNode.type)) {
|
|
93
93
|
offsetY = lightHight / 2 + paddingTop - 12; // side toolbar icon is 12 px
|
|
94
94
|
}
|
|
95
|
-
|
|
96
95
|
const HEADER_HEIGHT = 56 + 44;
|
|
97
96
|
return rect.y - HEADER_HEIGHT + offsetY;
|
|
98
97
|
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import React, { useCallback } from 'react';
|
|
2
2
|
import { UncontrolledPopover } from 'reactstrap';
|
|
3
3
|
import { withTranslation } from 'react-i18next';
|
|
4
|
-
import { useSlateStatic } from '@seafile/slate-react';
|
|
4
|
+
import { ReactEditor, useSlateStatic } from '@seafile/slate-react';
|
|
5
5
|
import { onSetNodeType } from './helpers';
|
|
6
|
-
import { SIDE_TRANSFORM_MENUS_CONFIG, LIST_ITEM_SUPPORTED_TRANSFORMATION, LIST_ITEM_CORRELATION_TYPE } from '../../constants';
|
|
6
|
+
import { SIDE_TRANSFORM_MENUS_CONFIG, LIST_ITEM_SUPPORTED_TRANSFORMATION, LIST_ITEM_CORRELATION_TYPE, BLOCKQUOTE, CALL_OUT } from '../../constants';
|
|
7
7
|
import DropdownMenuItem from '../../commons/dropdown-menu-item';
|
|
8
8
|
const TransformMenus = _ref => {
|
|
9
9
|
let {
|
|
@@ -23,6 +23,14 @@ const TransformMenus = _ref => {
|
|
|
23
23
|
if (LIST_ITEM_CORRELATION_TYPE.includes(slateNode.type)) {
|
|
24
24
|
newSideMenusConfig = SIDE_TRANSFORM_MENUS_CONFIG.filter(item => LIST_ITEM_SUPPORTED_TRANSFORMATION.includes(item.type));
|
|
25
25
|
}
|
|
26
|
+
const path = ReactEditor.findPath(editor, slateNode);
|
|
27
|
+
if (path && path.length > 1) {
|
|
28
|
+
const nodeIndex = path[0];
|
|
29
|
+
const highestNode = editor.children[nodeIndex];
|
|
30
|
+
if (highestNode.type === BLOCKQUOTE) {
|
|
31
|
+
newSideMenusConfig = SIDE_TRANSFORM_MENUS_CONFIG.filter(item => item.type !== CALL_OUT);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
26
34
|
return newSideMenusConfig;
|
|
27
35
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
28
36
|
}, [slateNode]);
|
package/package.json
CHANGED
|
@@ -434,7 +434,7 @@
|
|
|
434
434
|
"Type_search_content": "Type search content",
|
|
435
435
|
"Replace_as": "Replace as",
|
|
436
436
|
"Type_replace_content": "Type replace content",
|
|
437
|
-
"
|
|
437
|
+
"Prevs": "Prevs",
|
|
438
438
|
"Next": "Další",
|
|
439
439
|
"Replace": "Nahradit",
|
|
440
440
|
"Replace_all": "Replace all",
|
|
@@ -434,7 +434,7 @@
|
|
|
434
434
|
"Type_search_content": "Type search content",
|
|
435
435
|
"Replace_as": "Replace as",
|
|
436
436
|
"Type_replace_content": "Type replace content",
|
|
437
|
-
"
|
|
437
|
+
"Prevs": "Prevs",
|
|
438
438
|
"Next": "Nächste Seite",
|
|
439
439
|
"Replace": "Ersetzen",
|
|
440
440
|
"Replace_all": "Replace all",
|
|
@@ -434,7 +434,7 @@
|
|
|
434
434
|
"Type_search_content": "Type search content",
|
|
435
435
|
"Replace_as": "Replace as",
|
|
436
436
|
"Type_replace_content": "Type replace content",
|
|
437
|
-
"
|
|
437
|
+
"Prevs": "Prevs",
|
|
438
438
|
"Next": "Next",
|
|
439
439
|
"Replace": "Replace",
|
|
440
440
|
"Replace_all": "Replace all",
|
|
@@ -434,7 +434,7 @@
|
|
|
434
434
|
"Type_search_content": "Type search content",
|
|
435
435
|
"Replace_as": "Replace as",
|
|
436
436
|
"Type_replace_content": "Type replace content",
|
|
437
|
-
"
|
|
437
|
+
"Prevs": "Prevs",
|
|
438
438
|
"Next": "Siguiente",
|
|
439
439
|
"Replace": "Reemplazar",
|
|
440
440
|
"Replace_all": "Replace all",
|
|
@@ -434,7 +434,7 @@
|
|
|
434
434
|
"Type_search_content": "Type search content",
|
|
435
435
|
"Replace_as": "Replace as",
|
|
436
436
|
"Type_replace_content": "Type replace content",
|
|
437
|
-
"
|
|
437
|
+
"Prevs": "Prevs",
|
|
438
438
|
"Next": "Suivant",
|
|
439
439
|
"Replace": "Remplacer",
|
|
440
440
|
"Replace_all": "Replace all",
|
|
@@ -434,7 +434,7 @@
|
|
|
434
434
|
"Type_search_content": "Type search content",
|
|
435
435
|
"Replace_as": "Replace as",
|
|
436
436
|
"Type_replace_content": "Type replace content",
|
|
437
|
-
"
|
|
437
|
+
"Prevs": "Prevs",
|
|
438
438
|
"Next": "Successivo",
|
|
439
439
|
"Replace": "Sostituire",
|
|
440
440
|
"Replace_all": "Replace all",
|
|
@@ -434,7 +434,7 @@
|
|
|
434
434
|
"Type_search_content": "Введите содержимое для поиска",
|
|
435
435
|
"Replace_as": "Заменить как",
|
|
436
436
|
"Type_replace_content": "Введите содержимое для замены",
|
|
437
|
-
"
|
|
437
|
+
"Prevs": "Prevs",
|
|
438
438
|
"Next": "Следующий",
|
|
439
439
|
"Replace": "Заменить",
|
|
440
440
|
"Replace_all": "Заменить все",
|
|
@@ -434,10 +434,10 @@
|
|
|
434
434
|
"Type_search_content": "输入查找内容",
|
|
435
435
|
"Replace_as": "替换为",
|
|
436
436
|
"Type_replace_content": "输入替换内容",
|
|
437
|
-
"
|
|
437
|
+
"Prevs": "上一个",
|
|
438
438
|
"Next": "下一页",
|
|
439
439
|
"Replace": "替换",
|
|
440
|
-
"Replace_all": "
|
|
440
|
+
"Replace_all": "替换全部",
|
|
441
441
|
"Are_you_sure_to_replace_all_number_xxx_in_this_document_with_yyy": "确定要将此文档内的 {{number}} 处 \"{{originalWord}} \" 替换为 \"{{replacedWord}} \" 吗?",
|
|
442
442
|
"Are_you_sure_to_clear_all_number_xxx_in_this_document": "确定将此文档内的 {{number}} 处 \"{{originalWord}}\" 全部清除吗?",
|
|
443
443
|
"Search_not_found": "未找到"
|