@seafile/sdoc-editor 1.0.27 → 1.0.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/basic-sdk/comment/components/global-comment/index.js +1 -1
- package/dist/basic-sdk/comment/utils/index.js +1 -1
- package/dist/basic-sdk/editor/comment-article.js +1 -1
- package/dist/basic-sdk/extension/constants/menus-config.js +3 -3
- package/dist/basic-sdk/extension/core/queries/index.js +7 -0
- package/dist/basic-sdk/extension/core/utils/index.js +4 -3
- package/dist/basic-sdk/extension/plugins/callout/helper.js +17 -0
- package/dist/basic-sdk/extension/plugins/callout/plugin.js +1 -2
- package/dist/basic-sdk/extension/plugins/callout/render-elem/index.js +7 -30
- package/dist/basic-sdk/extension/plugins/check-list/helpers.js +33 -4
- package/dist/basic-sdk/extension/plugins/code-block/hover-menu/index.js +1 -1
- package/dist/basic-sdk/extension/plugins/link/helpers.js +16 -0
- package/dist/basic-sdk/{assets/css/textlink-hovermenu.css → extension/plugins/link/hover/index.css} +1 -1
- package/dist/basic-sdk/extension/plugins/link/hover/index.js +1 -1
- package/dist/basic-sdk/extension/plugins/link/render-elem.js +39 -18
- package/dist/basic-sdk/extension/plugins/list/plugin/shortcut.js +1 -1
- package/dist/basic-sdk/extension/plugins/mention/render-elem/participant-popover.js +1 -1
- package/dist/basic-sdk/extension/plugins/table/menu/vertical-align-popover/style.css +0 -1
- package/dist/basic-sdk/extension/toolbar/side-toolbar/helpers.js +8 -1
- package/dist/basic-sdk/extension/toolbar/side-toolbar/transform-menus.js +7 -1
- package/package.json +1 -1
- package/public/locales/en/sdoc-editor.json +1 -1
- package/public/locales/ru/sdoc-editor.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
2
|
-
import React, { useCallback, useEffect,
|
|
2
|
+
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
|
3
3
|
import dayjs from 'dayjs';
|
|
4
4
|
import EventBus from '../../../utils/event-bus';
|
|
5
5
|
import useCommentList from '../../hooks/comment-hooks/use-comment-list';
|
|
@@ -31,7 +31,7 @@ export const searchCollaborators = (collaborators, searchValue) => {
|
|
|
31
31
|
};
|
|
32
32
|
|
|
33
33
|
// Mailto, file, tel, callto, sms, cid, xmpp, etc. are not support
|
|
34
|
-
const ALLOWED_URL_REG = /((http|https):\/\/[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|])/g;
|
|
34
|
+
// const ALLOWED_URL_REG = /((http|https):\/\/[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|])/g;
|
|
35
35
|
// export const textToHtml = (text) => {
|
|
36
36
|
// if (!text) return '';
|
|
37
37
|
// return text.replace(ALLOWED_URL_REG, '<a href="$1" target="_blank" class=' + COMMENT_URL_CLASSNAME + '>$1</a>');
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
2
2
|
import React, { useCallback, useMemo } from 'react';
|
|
3
3
|
import { Editable, ReactEditor, Slate } from '@seafile/slate-react';
|
|
4
|
-
import { Editor, Node
|
|
4
|
+
import { Editor, Node } from '@seafile/slate';
|
|
5
5
|
import isHotkey from 'is-hotkey';
|
|
6
6
|
import scrollIntoView from 'scroll-into-view-if-needed';
|
|
7
7
|
import { renderLeaf } from '../extension';
|
|
@@ -64,7 +64,7 @@ export const MENUS_CONFIG_MAP = {
|
|
|
64
64
|
[CHECK_LIST_ITEM]: {
|
|
65
65
|
id: CHECK_LIST_ITEM,
|
|
66
66
|
iconClass: 'sdocfont sdoc-check-square',
|
|
67
|
-
text: '
|
|
67
|
+
text: 'Check_list'
|
|
68
68
|
},
|
|
69
69
|
[CODE_BLOCK]: {
|
|
70
70
|
id: CODE_BLOCK,
|
|
@@ -255,7 +255,7 @@ export const SIDE_TRANSFORM_MENUS_CONFIG = [{
|
|
|
255
255
|
id: CHECK_LIST_ITEM,
|
|
256
256
|
iconClass: 'sdocfont sdoc-check-square',
|
|
257
257
|
type: CHECK_LIST_ITEM,
|
|
258
|
-
text: '
|
|
258
|
+
text: 'Check_list'
|
|
259
259
|
}, {
|
|
260
260
|
id: BLOCKQUOTE,
|
|
261
261
|
iconClass: 'sdocfont sdoc-quote1',
|
|
@@ -315,7 +315,7 @@ export const SIDE_INSERT_MENUS_CONFIG = {
|
|
|
315
315
|
id: '',
|
|
316
316
|
iconClass: 'sdocfont sdoc-check-square',
|
|
317
317
|
type: CHECK_LIST_ITEM,
|
|
318
|
-
text: '
|
|
318
|
+
text: 'Check_list'
|
|
319
319
|
},
|
|
320
320
|
[PARAGRAPH]: {
|
|
321
321
|
id: PARAGRAPH,
|
|
@@ -451,4 +451,11 @@ export const isCurrentLineEmpty = editor => {
|
|
|
451
451
|
};
|
|
452
452
|
export const isCurrentLineHasText = node => {
|
|
453
453
|
return Node.string(node).trim() !== '';
|
|
454
|
+
};
|
|
455
|
+
export const isMultiLevelList = listNode => {
|
|
456
|
+
const {
|
|
457
|
+
children
|
|
458
|
+
} = listNode || {};
|
|
459
|
+
let isMultiLevel = (children === null || children === void 0 ? void 0 : children.find(item => (item === null || item === void 0 ? void 0 : item.children.length) > 1)) ? true : false;
|
|
460
|
+
return isMultiLevel;
|
|
454
461
|
};
|
|
@@ -17,10 +17,10 @@ export const match = (node, path, predicate) => {
|
|
|
17
17
|
}
|
|
18
18
|
return predicate(node, path);
|
|
19
19
|
};
|
|
20
|
-
export const generateDefaultText =
|
|
20
|
+
export const generateDefaultText = text => {
|
|
21
21
|
return {
|
|
22
22
|
id: slugid.nice(),
|
|
23
|
-
text: ''
|
|
23
|
+
text: text || ''
|
|
24
24
|
};
|
|
25
25
|
};
|
|
26
26
|
export const generateDefaultParagraph = () => {
|
|
@@ -32,11 +32,12 @@ export const generateDefaultParagraph = () => {
|
|
|
32
32
|
};
|
|
33
33
|
export const generateEmptyElement = function (type) {
|
|
34
34
|
let props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
35
|
+
let text = arguments.length > 2 ? arguments[2] : undefined;
|
|
35
36
|
return _objectSpread(_objectSpread({
|
|
36
37
|
id: slugid.nice(),
|
|
37
38
|
type
|
|
38
39
|
}, props), {}, {
|
|
39
|
-
children: [generateDefaultText()]
|
|
40
|
+
children: [generateDefaultText(text)]
|
|
40
41
|
});
|
|
41
42
|
};
|
|
42
43
|
export function Placeholder(props) {
|
|
@@ -2,6 +2,7 @@ import { Editor, Node, Path, Transforms } from '@seafile/slate';
|
|
|
2
2
|
import { CALL_OUT, PARAGRAPH } from '../../constants/element-type';
|
|
3
3
|
import { focusEditor, generateEmptyElement, getSelectedElems, isRangeAcrossBlocks } from '../../core';
|
|
4
4
|
import { CALLOUT_ALLOWED_INSIDE_TYPES, CALLOUT_COLOR_MAP } from './constant';
|
|
5
|
+
import { DOCUMENT_PLUGIN_EDITOR } from '../../../constants';
|
|
5
6
|
export const isMenuActive = editor => {
|
|
6
7
|
const {
|
|
7
8
|
selection
|
|
@@ -124,4 +125,20 @@ export const insertElementAtNewLineInCallout = (editor, type, currentPath) => {
|
|
|
124
125
|
at: insertPath
|
|
125
126
|
});
|
|
126
127
|
Transforms.select(editor, insertPath);
|
|
128
|
+
};
|
|
129
|
+
export const getCalloutMenuPosition = (element, editor) => {
|
|
130
|
+
const {
|
|
131
|
+
top,
|
|
132
|
+
left
|
|
133
|
+
} = element.getBoundingClientRect();
|
|
134
|
+
const menuTop = top - 42; // top = top distance - menu height
|
|
135
|
+
const newMenuPosition = {
|
|
136
|
+
top: menuTop,
|
|
137
|
+
left: left // left = callout left distance
|
|
138
|
+
};
|
|
139
|
+
// 165 is distance with browser top
|
|
140
|
+
if (editor.editorType === DOCUMENT_PLUGIN_EDITOR && menuTop < 165) {
|
|
141
|
+
newMenuPosition['display'] = 'none';
|
|
142
|
+
}
|
|
143
|
+
return newMenuPosition;
|
|
127
144
|
};
|
|
@@ -7,6 +7,7 @@ import { CALLOUT_COLOR_MAP, CALLOUT_ICON_MAP } from '../constant';
|
|
|
7
7
|
import { INTERNAL_EVENT } from '../../../../constants';
|
|
8
8
|
import EventBus from '../../../../utils/event-bus';
|
|
9
9
|
import { useScrollContext } from '../../../../hooks/use-scroll-context';
|
|
10
|
+
import { getCalloutMenuPosition } from '../helper';
|
|
10
11
|
import CalloutHoverMenu from './callout-hover-menu';
|
|
11
12
|
import './index.css';
|
|
12
13
|
const renderCallout = (_ref, editor) => {
|
|
@@ -63,22 +64,10 @@ const renderCallout = (_ref, editor) => {
|
|
|
63
64
|
if (readOnly) return;
|
|
64
65
|
if (!isShowColorSelector) return;
|
|
65
66
|
if (e.currentTarget.scrollTop) {
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
left
|
|
69
|
-
} = calloutRef.current.getBoundingClientRect();
|
|
70
|
-
const menuTop = top - 36; // top = top distance - menu height
|
|
71
|
-
const newMenuPosition = {
|
|
72
|
-
top: menuTop,
|
|
73
|
-
left: left // left = code-block left distance
|
|
74
|
-
};
|
|
75
|
-
// 165 is distance with browser top
|
|
76
|
-
if (menuTop < 165) {
|
|
77
|
-
newMenuPosition['display'] = 'none';
|
|
78
|
-
}
|
|
79
|
-
setPopoverPosition(newMenuPosition);
|
|
67
|
+
const menuPosition = getCalloutMenuPosition(calloutRef.current, editor);
|
|
68
|
+
setPopoverPosition(menuPosition);
|
|
80
69
|
}
|
|
81
|
-
}, [isShowColorSelector, readOnly]);
|
|
70
|
+
}, [editor, isShowColorSelector, readOnly]);
|
|
82
71
|
useEffect(() => {
|
|
83
72
|
const eventBus = EventBus.getInstance();
|
|
84
73
|
const unsubscribe = eventBus.subscribe(INTERNAL_EVENT.CLOSE_CALLOUT_COLOR_PICKER, handleCloseColorSelector);
|
|
@@ -102,22 +91,10 @@ const renderCallout = (_ref, editor) => {
|
|
|
102
91
|
}, [isSelected]);
|
|
103
92
|
const handleDisplayColorSelector = useCallback(() => {
|
|
104
93
|
if (readOnly) return;
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
left
|
|
108
|
-
} = calloutRef.current.getBoundingClientRect();
|
|
109
|
-
const menuTop = top - 42; // top = top distance - menu height
|
|
110
|
-
const newMenuPosition = {
|
|
111
|
-
top: menuTop,
|
|
112
|
-
left: left // left = callout left distance
|
|
113
|
-
};
|
|
114
|
-
// 165 is distance with browser top
|
|
115
|
-
if (menuTop < 165) {
|
|
116
|
-
newMenuPosition['display'] = 'none';
|
|
117
|
-
}
|
|
118
|
-
setPopoverPosition(newMenuPosition);
|
|
94
|
+
const menuPosition = getCalloutMenuPosition(calloutRef.current, editor);
|
|
95
|
+
setPopoverPosition(menuPosition);
|
|
119
96
|
setIsShowColorSelector(true);
|
|
120
|
-
}, [readOnly]);
|
|
97
|
+
}, [editor, readOnly]);
|
|
121
98
|
const handleClick = useCallback(e => {
|
|
122
99
|
handleDisplayColorSelector();
|
|
123
100
|
}, [handleDisplayColorSelector]);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Transforms, Editor, Element } from '@seafile/slate';
|
|
2
|
-
import { CHECK_LIST_ITEM, PARAGRAPH, ELEMENT_TYPE, INSERT_POSITION } from '../../constants';
|
|
3
|
-
import { getSelectedNodeByType, generateEmptyElement } from '../../core';
|
|
1
|
+
import { Transforms, Editor, Element, Node } from '@seafile/slate';
|
|
2
|
+
import { CHECK_LIST_ITEM, PARAGRAPH, ELEMENT_TYPE, INSERT_POSITION, ORDERED_LIST, UNORDERED_LIST } from '../../constants';
|
|
3
|
+
import { getSelectedNodeByType, generateEmptyElement, isMultiLevelList } from '../../core';
|
|
4
4
|
export const isMenuDisabled = (editor, readonly) => {
|
|
5
5
|
if (readonly) return true;
|
|
6
6
|
if (editor.selection == null) return true;
|
|
@@ -19,7 +19,7 @@ export const isMenuDisabled = (editor, readonly) => {
|
|
|
19
19
|
} = element;
|
|
20
20
|
if (type === ELEMENT_TYPE.CODE_LINE) return true;
|
|
21
21
|
if (type === ELEMENT_TYPE.CODE_BLOCK) return true;
|
|
22
|
-
if (type
|
|
22
|
+
if ([ORDERED_LIST, UNORDERED_LIST].includes(type) && isMultiLevelList(element)) return true;
|
|
23
23
|
if (type === ELEMENT_TYPE.TABLE) return true;
|
|
24
24
|
if (type === ELEMENT_TYPE.TABLE_ROW) return true;
|
|
25
25
|
if (type === ELEMENT_TYPE.TABLE_CELL) return true;
|
|
@@ -33,6 +33,27 @@ export const getCheckListItemType = editor => {
|
|
|
33
33
|
if (!node) return PARAGRAPH;
|
|
34
34
|
return node.type;
|
|
35
35
|
};
|
|
36
|
+
export const convertToCheck = (editor, listNode, listPath) => {
|
|
37
|
+
const checkList = [];
|
|
38
|
+
const {
|
|
39
|
+
children
|
|
40
|
+
} = listNode || {};
|
|
41
|
+
children.forEach(item => {
|
|
42
|
+
const text = Node.string(item);
|
|
43
|
+
const checkNode = generateEmptyElement(CHECK_LIST_ITEM, {}, text);
|
|
44
|
+
checkList.push(checkNode);
|
|
45
|
+
});
|
|
46
|
+
Transforms.removeNodes(editor, {
|
|
47
|
+
at: [listPath[0]]
|
|
48
|
+
});
|
|
49
|
+
Transforms.insertNodes(editor, checkList, {
|
|
50
|
+
at: [listPath[0]]
|
|
51
|
+
});
|
|
52
|
+
Transforms.select(editor, {
|
|
53
|
+
path: [listPath[0], 0],
|
|
54
|
+
offset: 0
|
|
55
|
+
});
|
|
56
|
+
};
|
|
36
57
|
export const setCheckListItemType = (editor, newType, insertPosition) => {
|
|
37
58
|
if (insertPosition === INSERT_POSITION.AFTER) {
|
|
38
59
|
const p = generateEmptyElement(PARAGRAPH);
|
|
@@ -42,6 +63,14 @@ export const setCheckListItemType = (editor, newType, insertPosition) => {
|
|
|
42
63
|
});
|
|
43
64
|
Transforms.select(editor, [path[0] + 1]);
|
|
44
65
|
}
|
|
66
|
+
const path = Editor.path(editor, editor.selection);
|
|
67
|
+
if (path) {
|
|
68
|
+
const [targetNode, targetPath] = Editor.node(editor, [path[0]]);
|
|
69
|
+
if (targetNode && [ORDERED_LIST, UNORDERED_LIST].includes(targetNode === null || targetNode === void 0 ? void 0 : targetNode.type)) {
|
|
70
|
+
convertToCheck(editor, targetNode, targetPath);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
45
74
|
Transforms.setNodes(editor, {
|
|
46
75
|
type: newType
|
|
47
76
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useCallback, useEffect,
|
|
1
|
+
import React, { useCallback, useEffect, useState } from 'react';
|
|
2
2
|
import { Input } from 'reactstrap';
|
|
3
3
|
import { useTranslation, withTranslation } from 'react-i18next';
|
|
4
4
|
import Tooltip from '../../../../../components/tooltip';
|
|
@@ -183,4 +183,20 @@ export const isWeChat = () => {
|
|
|
183
183
|
let isWeChat = ua.match(/MicroMessenger/i) === 'micromessenger';
|
|
184
184
|
let isEnterpriseWeChat = ua.match(/MicroMessenger/i) === 'micromessenger' && ua.match(/wxwork/i) === 'wxwork';
|
|
185
185
|
return isEnterpriseWeChat || isWeChat;
|
|
186
|
+
};
|
|
187
|
+
export const getMenuPosition = element => {
|
|
188
|
+
if (!element) return {};
|
|
189
|
+
const {
|
|
190
|
+
top,
|
|
191
|
+
left,
|
|
192
|
+
width
|
|
193
|
+
} = element.getBoundingClientRect();
|
|
194
|
+
// top = top distance - menu height
|
|
195
|
+
const menuTop = top - 42;
|
|
196
|
+
// left = left distance - (menu width / 2) + (link with / 2)
|
|
197
|
+
const menuLeft = left - 140 / 2 + width / 2;
|
|
198
|
+
return {
|
|
199
|
+
top: menuTop,
|
|
200
|
+
left: menuLeft
|
|
201
|
+
};
|
|
186
202
|
};
|
|
@@ -3,7 +3,7 @@ import { createPortal } from 'react-dom';
|
|
|
3
3
|
import { useTranslation } from 'react-i18next';
|
|
4
4
|
import { useReadOnly } from '@seafile/slate-react';
|
|
5
5
|
import { isWeChat } from '../helpers';
|
|
6
|
-
import '
|
|
6
|
+
import './index.css';
|
|
7
7
|
const LinkHover = _ref => {
|
|
8
8
|
let {
|
|
9
9
|
editor,
|
|
@@ -1,20 +1,33 @@
|
|
|
1
1
|
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { Range } from '@seafile/slate';
|
|
4
|
-
import { unWrapLinkNode } from './helpers';
|
|
4
|
+
import { getMenuPosition, unWrapLinkNode } from './helpers';
|
|
5
5
|
import LinkHover from './hover';
|
|
6
6
|
import EventBus from '../../../utils/event-bus';
|
|
7
|
-
import { INTERNAL_EVENT } from '../../../constants';
|
|
7
|
+
import { DOCUMENT_PLUGIN_EDITOR, INTERNAL_EVENT } from '../../../constants';
|
|
8
8
|
import { ELEMENT_TYPE } from '../../constants';
|
|
9
9
|
import InlineBugFixer from '../../commons/Inline-bug-fix-wrapper';
|
|
10
|
-
|
|
10
|
+
import { ScrollContext } from '../../../hooks/use-scroll-context';
|
|
11
|
+
class Link extends React.Component {
|
|
11
12
|
constructor(props) {
|
|
12
13
|
super(props);
|
|
13
14
|
_defineProperty(this, "registerEventHandle", () => {
|
|
14
15
|
document.addEventListener('click', this.onHideLinkMenu);
|
|
16
|
+
const {
|
|
17
|
+
scrollRef
|
|
18
|
+
} = this.context;
|
|
19
|
+
if (scrollRef.current) {
|
|
20
|
+
scrollRef.current.addEventListener('scroll', this.onScroll);
|
|
21
|
+
}
|
|
15
22
|
});
|
|
16
23
|
_defineProperty(this, "unregisterEventHandle", () => {
|
|
17
24
|
document.removeEventListener('click', this.onHideLinkMenu);
|
|
25
|
+
const {
|
|
26
|
+
scrollRef
|
|
27
|
+
} = this.context;
|
|
28
|
+
if (scrollRef.current) {
|
|
29
|
+
scrollRef.current.addEventListener('scroll', this.onScroll);
|
|
30
|
+
}
|
|
18
31
|
});
|
|
19
32
|
_defineProperty(this, "onHideLinkMenu", () => {
|
|
20
33
|
this.setState({
|
|
@@ -23,22 +36,25 @@ class LinkHoverMenuComponent extends React.Component {
|
|
|
23
36
|
this.unregisterEventHandle();
|
|
24
37
|
});
|
|
25
38
|
});
|
|
26
|
-
_defineProperty(this, "
|
|
39
|
+
_defineProperty(this, "onScroll", e => {
|
|
40
|
+
this.setPosition(this.linkRef);
|
|
41
|
+
});
|
|
42
|
+
_defineProperty(this, "setPosition", element => {
|
|
27
43
|
const {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
// left = left distance - (menu width / 2) + (link with / 2)
|
|
35
|
-
const menuLeft = left - 140 / 2 + width / 2;
|
|
44
|
+
editor
|
|
45
|
+
} = this.props;
|
|
46
|
+
const menuPosition = getMenuPosition(element);
|
|
47
|
+
if (editor.editorType === DOCUMENT_PLUGIN_EDITOR && menuPosition.top < 165) {
|
|
48
|
+
menuPosition['display'] = 'none';
|
|
49
|
+
}
|
|
36
50
|
this.setState({
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
51
|
+
menuPosition
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
_defineProperty(this, "onLinkClick", e => {
|
|
55
|
+
this.setPosition(e.target);
|
|
56
|
+
this.setState({
|
|
57
|
+
isShowLinkMenu: true
|
|
42
58
|
});
|
|
43
59
|
setTimeout(() => {
|
|
44
60
|
this.registerEventHandle();
|
|
@@ -59,6 +75,9 @@ class LinkHoverMenuComponent extends React.Component {
|
|
|
59
75
|
element
|
|
60
76
|
});
|
|
61
77
|
});
|
|
78
|
+
_defineProperty(this, "setRef", ref => {
|
|
79
|
+
this.linkRef = ref;
|
|
80
|
+
});
|
|
62
81
|
this.state = {
|
|
63
82
|
isShowLinkMenu: false,
|
|
64
83
|
menuPosition: null
|
|
@@ -94,6 +113,7 @@ class LinkHoverMenuComponent extends React.Component {
|
|
|
94
113
|
}, attributes, {
|
|
95
114
|
onClick: this.onLinkClick
|
|
96
115
|
}), /*#__PURE__*/React.createElement("span", {
|
|
116
|
+
ref: this.setRef,
|
|
97
117
|
className: "virtual-link",
|
|
98
118
|
title: element.title
|
|
99
119
|
}, /*#__PURE__*/React.createElement(InlineBugFixer, null), children, /*#__PURE__*/React.createElement(InlineBugFixer, null))), isShowLinkMenu && (this.props.readonly || Range.isCollapsed(editor.selection)) && /*#__PURE__*/React.createElement(LinkHover, {
|
|
@@ -105,8 +125,9 @@ class LinkHoverMenuComponent extends React.Component {
|
|
|
105
125
|
}));
|
|
106
126
|
}
|
|
107
127
|
}
|
|
128
|
+
_defineProperty(Link, "contextType", ScrollContext);
|
|
108
129
|
const renderLink = (props, editor, readonly) => {
|
|
109
|
-
return /*#__PURE__*/React.createElement(
|
|
130
|
+
return /*#__PURE__*/React.createElement(Link, Object.assign({}, props, {
|
|
110
131
|
editor: editor,
|
|
111
132
|
readonly: readonly
|
|
112
133
|
}));
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Editor, Path, Range, Transforms } from '@seafile/slate';
|
|
2
|
-
import {
|
|
2
|
+
import { ORDERED_LIST, PARAGRAPH } from '../../../constants';
|
|
3
3
|
import { getBeforeText, setListType } from '../helpers';
|
|
4
4
|
import { focusEditor, getLastChild, getPreviousPath } from '../../../core';
|
|
5
5
|
import { generateEmptyListItem } from '../model';
|
|
@@ -136,7 +136,7 @@ const ParticipantPopover = _ref => {
|
|
|
136
136
|
setActiveCollaboratorIndex(nextActiveCollaboratorIndex);
|
|
137
137
|
}, [searchedCollaborators, activeCollaboratorIndex]);
|
|
138
138
|
const onSelectCollaborator = useCallback(collaborator => {
|
|
139
|
-
const [
|
|
139
|
+
const [, path] = getMentionTempIptEntry(editor);
|
|
140
140
|
insertMention(editor, collaborator);
|
|
141
141
|
addParticipants(collaborator.username);
|
|
142
142
|
Transforms.removeNodes(editor, {
|
|
@@ -3,12 +3,13 @@ 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
|
-
import { generateEmptyElement } from '../../core';
|
|
6
|
+
import { generateEmptyElement, findPath, isMultiLevelList } from '../../core';
|
|
7
7
|
import { generateEmptyList } from '../../plugins/list/model';
|
|
8
8
|
import { setClipboardCodeBlockData } from '../../plugins/code-block/helpers';
|
|
9
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, CALL_OUT } from '../../constants';
|
|
10
10
|
import { EMPTY_SELECTED_RANGE } from '../../plugins/table/constants';
|
|
11
11
|
import { unwrapCallout, wrapCallout } from '../../plugins/callout/helper';
|
|
12
|
+
import { convertToCheck } from '../../plugins/check-list/helpers';
|
|
12
13
|
import { getHeaderHeight } from '../../../utils/dom-utils';
|
|
13
14
|
export const onSetNodeType = (editor, element, type) => {
|
|
14
15
|
if (!type) return;
|
|
@@ -21,6 +22,12 @@ export const onSetNodeType = (editor, element, type) => {
|
|
|
21
22
|
return;
|
|
22
23
|
}
|
|
23
24
|
if (type === CHECK_LIST_ITEM) {
|
|
25
|
+
const path = findPath(editor, element);
|
|
26
|
+
const [targetNode, targetPath] = Editor.node(editor, [path[0]]) || [];
|
|
27
|
+
if (targetNode && [ORDERED_LIST, UNORDERED_LIST].includes(targetNode === null || targetNode === void 0 ? void 0 : targetNode.type) && !isMultiLevelList(targetNode)) {
|
|
28
|
+
convertToCheck(editor, targetNode, targetPath);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
24
31
|
const newType = element.type === CHECK_LIST_ITEM ? PARAGRAPH : CHECK_LIST_ITEM;
|
|
25
32
|
Transforms.setNodes(editor, {
|
|
26
33
|
type: newType
|
|
@@ -3,8 +3,9 @@ import { UncontrolledPopover } from 'reactstrap';
|
|
|
3
3
|
import { withTranslation } from 'react-i18next';
|
|
4
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, BLOCKQUOTE, CALL_OUT, HEADERS } from '../../constants';
|
|
6
|
+
import { SIDE_TRANSFORM_MENUS_CONFIG, LIST_ITEM_SUPPORTED_TRANSFORMATION, LIST_ITEM_CORRELATION_TYPE, BLOCKQUOTE, CALL_OUT, HEADERS, ORDERED_LIST, UNORDERED_LIST, CHECK_LIST_ITEM } from '../../constants';
|
|
7
7
|
import DropdownMenuItem from '../../commons/dropdown-menu-item';
|
|
8
|
+
import { isMultiLevelList } from '../../core';
|
|
8
9
|
const TransformMenus = _ref => {
|
|
9
10
|
let {
|
|
10
11
|
target,
|
|
@@ -37,6 +38,11 @@ const TransformMenus = _ref => {
|
|
|
37
38
|
if (HEADERS.includes(highestNode.type)) {
|
|
38
39
|
newSideMenusConfig = SIDE_TRANSFORM_MENUS_CONFIG.filter(item => item.type !== BLOCKQUOTE);
|
|
39
40
|
}
|
|
41
|
+
|
|
42
|
+
// Multi-level list items cannot be converted to checks
|
|
43
|
+
if ([ORDERED_LIST, UNORDERED_LIST].includes(highestNode.type) && isMultiLevelList(highestNode)) {
|
|
44
|
+
newSideMenusConfig = SIDE_TRANSFORM_MENUS_CONFIG.filter(item => item.type !== CHECK_LIST_ITEM);
|
|
45
|
+
}
|
|
40
46
|
}
|
|
41
47
|
return newSideMenusConfig;
|
|
42
48
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
package/package.json
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"Quote": "Quote",
|
|
17
17
|
"Ordered_list": "Ordered list",
|
|
18
18
|
"Unordered_list": "Unordered list",
|
|
19
|
-
"
|
|
19
|
+
"Check_list": "Check list",
|
|
20
20
|
"Insert_image": "Insert image",
|
|
21
21
|
"Insert_formula": "Insert formula",
|
|
22
22
|
"Formula": "Formula",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"Quote": "Цитата",
|
|
17
17
|
"Ordered_list": "Нумерованный список",
|
|
18
18
|
"Unordered_list": "Маркированный список",
|
|
19
|
-
"Check_list": "
|
|
19
|
+
"Check_list": "Контрольный список",
|
|
20
20
|
"Insert_image": "Вставить изображение",
|
|
21
21
|
"Insert_formula": "Вставить формулу",
|
|
22
22
|
"Formula": "Формула",
|