@seafile/sdoc-editor 0.3.12 → 0.3.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/constants/index.js +2 -1
- package/dist/basic-sdk/extension/constants/element-type.js +1 -0
- package/dist/basic-sdk/extension/constants/index.js +21 -3
- package/dist/basic-sdk/extension/constants/menus-config.js +16 -1
- package/dist/basic-sdk/extension/core/utils/index.js +7 -4
- package/dist/basic-sdk/extension/plugins/blockquote/helpers.js +11 -3
- package/dist/basic-sdk/extension/plugins/blockquote/plugin.js +9 -0
- package/dist/basic-sdk/extension/plugins/callout/constant.js +47 -0
- package/dist/basic-sdk/extension/plugins/callout/helper.js +117 -0
- package/dist/basic-sdk/extension/plugins/callout/index.js +12 -0
- package/dist/basic-sdk/extension/plugins/callout/menu/index.css +16 -0
- package/dist/basic-sdk/extension/plugins/callout/menu/index.js +40 -0
- package/dist/basic-sdk/extension/plugins/callout/plugin.js +25 -19
- package/dist/basic-sdk/extension/plugins/callout/render-elem/color-selector.js +53 -0
- package/dist/basic-sdk/extension/plugins/callout/render-elem/index.css +67 -0
- package/dist/basic-sdk/extension/plugins/callout/render-elem/index.js +82 -0
- package/dist/basic-sdk/extension/plugins/code-block/helpers.js +2 -0
- package/dist/basic-sdk/extension/plugins/index.js +3 -2
- package/dist/basic-sdk/extension/plugins/paragraph/render-elem.js +5 -3
- package/dist/basic-sdk/extension/plugins/table/helpers.js +1 -0
- package/dist/basic-sdk/extension/plugins/table/popover/table-size-popover/index.css +2 -1
- package/dist/basic-sdk/extension/plugins/table/popover/table-size-popover/index.js +27 -9
- package/dist/basic-sdk/extension/plugins/table/popover/table-template/index.css +8 -4
- package/dist/basic-sdk/extension/render/custom-element.js +15 -4
- package/dist/basic-sdk/extension/render/helper.js +37 -0
- package/dist/basic-sdk/extension/toolbar/header-toolbar/index.js +4 -0
- package/dist/basic-sdk/extension/toolbar/side-toolbar/event.js +5 -1
- package/dist/basic-sdk/extension/toolbar/side-toolbar/helpers.js +13 -3
- package/dist/basic-sdk/extension/toolbar/side-toolbar/index.js +7 -1
- package/dist/basic-sdk/extension/toolbar/side-toolbar/insert-block-menu.js +13 -1
- package/package.json +1 -1
- package/public/locales/cs/sdoc-editor.json +4 -1
- package/public/locales/de/sdoc-editor.json +4 -1
- package/public/locales/en/sdoc-editor.json +4 -1
- package/public/locales/es/sdoc-editor.json +4 -1
- package/public/locales/fr/sdoc-editor.json +4 -1
- package/public/locales/it/sdoc-editor.json +4 -1
- package/public/locales/ru/sdoc-editor.json +5 -2
- package/public/locales/zh_CN/sdoc-editor.json +4 -1
- package/public/media/sdoc-editor-font/iconfont.svg +8 -0
- package/public/media/sdoc-editor-font.css +4 -1
|
@@ -12,7 +12,8 @@ export const INTERNAL_EVENT = {
|
|
|
12
12
|
ARTICLE_CLICK: 'hidden_comment',
|
|
13
13
|
UPDATE_TAG_VIEW: 'update_tag_view',
|
|
14
14
|
COMMENT_LIST_CLICK: 'comment_list_click',
|
|
15
|
-
UNSEEN_NOTIFICATIONS_COUNT: 'unseen_notifications_count'
|
|
15
|
+
UNSEEN_NOTIFICATIONS_COUNT: 'unseen_notifications_count',
|
|
16
|
+
DISPLAY_CALLOUT_COLOR_PICKER: 'display_callout_color_picker'
|
|
16
17
|
};
|
|
17
18
|
export const REVISION_DIFF_KEY = 'diff';
|
|
18
19
|
export const REVISION_DIFF_VALUE = '1';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// extension plugin
|
|
2
2
|
import * as ELEMENT_TYPE from './element-type';
|
|
3
|
-
import { BLOCKQUOTE, TITLE, SUBTITLE, HEADER, HEADER1, HEADER2, HEADER3, HEADER4, HEADER5, HEADER6, PARAGRAPH, ORDERED_LIST, UNORDERED_LIST, LIST_ITEM, CHECK_LIST_ITEM, CODE_BLOCK, CODE_LINE, TABLE, TABLE_CELL, TABLE_ROW, LINK, SDOC_LINK, FILE_LINK, IMAGE, TOP_LEVEL_TYPES, INLINE_LEVEL_TYPES } from './element-type';
|
|
3
|
+
import { BLOCKQUOTE, TITLE, SUBTITLE, HEADER, HEADER1, HEADER2, HEADER3, HEADER4, HEADER5, HEADER6, PARAGRAPH, ORDERED_LIST, UNORDERED_LIST, LIST_ITEM, CHECK_LIST_ITEM, CODE_BLOCK, CODE_LINE, TABLE, TABLE_CELL, TABLE_ROW, LINK, SDOC_LINK, FILE_LINK, IMAGE, TOP_LEVEL_TYPES, INLINE_LEVEL_TYPES, CALL_OUT } from './element-type';
|
|
4
4
|
export { DEFAULT_COLORS, STANDARD_COLORS, DEFAULT_RECENT_USED_LIST, DEFAULT_FONT_COLOR, RECENT_USED_HIGHLIGHT_COLORS_KEY, RECENT_USED_FONT_COLORS_KEY, RECENT_USED_TABLE_CELL_BACKGROUND_COLORS_KEY, DEFAULT_LAST_USED_FONT_COLOR, DEFAULT_LAST_USED_HIGHLIGHT_COLOR, DEFAULT_LAST_USED_TABLE_CELL_BACKGROUND_COLOR } from './color';
|
|
5
5
|
export { FONT_SIZE, DEFAULT_FONT, FONT, GOOGLE_FONT_CLASS, RECENT_USED_FONTS_KEY, SDOC_FONT_SIZE } from './font';
|
|
6
6
|
export { DIFF_TYPE, ADDED_STYLE, DELETED_STYLE } from './diff-view';
|
|
@@ -36,5 +36,23 @@ export const FILE_TYPE = {
|
|
|
36
36
|
[FILE_LINK]: 'file',
|
|
37
37
|
[SDOC_LINK]: 'sdoc'
|
|
38
38
|
};
|
|
39
|
-
export const SUPPORTED_SIDE_OPERATION_TYPE = [PARAGRAPH, SUBTITLE, HEADER1, HEADER2, HEADER3, HEADER4, HEADER5, HEADER6, CHECK_LIST_ITEM, CODE_BLOCK, TABLE, BLOCKQUOTE];
|
|
40
|
-
export
|
|
39
|
+
export const SUPPORTED_SIDE_OPERATION_TYPE = [PARAGRAPH, SUBTITLE, HEADER1, HEADER2, HEADER3, HEADER4, HEADER5, HEADER6, CHECK_LIST_ITEM, CODE_BLOCK, TABLE, BLOCKQUOTE, CALL_OUT];
|
|
40
|
+
export const MOUSE_ENTER_EVENT_DISABLED_MAP = {
|
|
41
|
+
[PARAGRAPH]: [CALL_OUT],
|
|
42
|
+
[TITLE]: [CALL_OUT],
|
|
43
|
+
[SUBTITLE]: [CALL_OUT],
|
|
44
|
+
[CHECK_LIST_ITEM]: [CALL_OUT],
|
|
45
|
+
[ORDERED_LIST]: [CALL_OUT],
|
|
46
|
+
[UNORDERED_LIST]: [CALL_OUT],
|
|
47
|
+
[UNORDERED_LIST]: [CALL_OUT],
|
|
48
|
+
[LIST_ITEM]: [CALL_OUT],
|
|
49
|
+
[BLOCKQUOTE]: [CALL_OUT],
|
|
50
|
+
[HEADER1]: [CALL_OUT],
|
|
51
|
+
[HEADER2]: [CALL_OUT],
|
|
52
|
+
[HEADER3]: [CALL_OUT],
|
|
53
|
+
[HEADER4]: [CALL_OUT],
|
|
54
|
+
[HEADER5]: [CALL_OUT],
|
|
55
|
+
[HEADER6]: [CALL_OUT],
|
|
56
|
+
[CALL_OUT]: [CALL_OUT]
|
|
57
|
+
};
|
|
58
|
+
export { ELEMENT_TYPE, BLOCKQUOTE, TITLE, SUBTITLE, HEADER, HEADER1, HEADER2, HEADER3, HEADER4, HEADER5, HEADER6, PARAGRAPH, ORDERED_LIST, UNORDERED_LIST, LIST_ITEM, CHECK_LIST_ITEM, CODE_BLOCK, CODE_LINE, TABLE, TABLE_CELL, TABLE_ROW, LINK, SDOC_LINK, FILE_LINK, IMAGE, TOP_LEVEL_TYPES, INLINE_LEVEL_TYPES, CALL_OUT };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { RECENT_USED_HIGHLIGHT_COLORS_KEY, DEFAULT_LAST_USED_HIGHLIGHT_COLOR, RECENT_USED_FONT_COLORS_KEY, DEFAULT_FONT_COLOR, DEFAULT_LAST_USED_FONT_COLOR } from './color';
|
|
2
|
-
import { BLOCKQUOTE, HEADER, HEADER1, HEADER2, HEADER3, HEADER4, HEADER5, HEADER6, ORDERED_LIST, UNORDERED_LIST, CHECK_LIST_ITEM, CODE_BLOCK, LINK, IMAGE, TABLE, SDOC_LINK, FILE_LINK, PARAGRAPH } from './element-type';
|
|
2
|
+
import { BLOCKQUOTE, HEADER, HEADER1, HEADER2, HEADER3, HEADER4, HEADER5, HEADER6, ORDERED_LIST, UNORDERED_LIST, CHECK_LIST_ITEM, CODE_BLOCK, LINK, IMAGE, TABLE, SDOC_LINK, FILE_LINK, PARAGRAPH, CALL_OUT } from './element-type';
|
|
3
3
|
export const UNDO = 'undo';
|
|
4
4
|
export const REDO = 'redo';
|
|
5
5
|
export const CLEAR_FORMAT = 'clear_format';
|
|
@@ -184,6 +184,11 @@ export const MENUS_CONFIG_MAP = {
|
|
|
184
184
|
id: "sdoc_".concat(FILE_LINK),
|
|
185
185
|
iconClass: 'sdocfont sdoc-link-file',
|
|
186
186
|
text: 'Link_file'
|
|
187
|
+
},
|
|
188
|
+
[CALL_OUT]: {
|
|
189
|
+
id: "sdoc_".concat(CALL_OUT),
|
|
190
|
+
iconClass: 'sdocfont sdoc-callout',
|
|
191
|
+
text: 'Callout'
|
|
187
192
|
}
|
|
188
193
|
};
|
|
189
194
|
|
|
@@ -243,6 +248,11 @@ export const SIDE_TRANSFORM_MENUS_CONFIG = [{
|
|
|
243
248
|
iconClass: 'sdocfont sdoc-quote1',
|
|
244
249
|
type: BLOCKQUOTE,
|
|
245
250
|
text: 'Quote'
|
|
251
|
+
}, {
|
|
252
|
+
id: CALL_OUT,
|
|
253
|
+
iconClass: 'sdocfont sdoc-callout',
|
|
254
|
+
type: CALL_OUT,
|
|
255
|
+
text: 'Callout'
|
|
246
256
|
}];
|
|
247
257
|
|
|
248
258
|
// Side insert menu config
|
|
@@ -271,6 +281,11 @@ export const SIDE_INSERT_MENUS_CONFIG = {
|
|
|
271
281
|
type: CODE_BLOCK,
|
|
272
282
|
text: 'Code_block'
|
|
273
283
|
},
|
|
284
|
+
[CALL_OUT]: {
|
|
285
|
+
id: '',
|
|
286
|
+
iconClass: 'sdocfont sdoc-callout',
|
|
287
|
+
text: 'Callout'
|
|
288
|
+
},
|
|
274
289
|
[ORDERED_LIST]: {
|
|
275
290
|
id: '',
|
|
276
291
|
iconClass: 'sdocfont sdoc-list-ol',
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
1
2
|
import React from 'react';
|
|
2
3
|
import slugid from 'slugid';
|
|
3
4
|
import { useTranslation } from 'react-i18next';
|
|
@@ -21,12 +22,14 @@ export const generateDefaultText = () => {
|
|
|
21
22
|
text: ''
|
|
22
23
|
};
|
|
23
24
|
};
|
|
24
|
-
export const generateEmptyElement = type
|
|
25
|
-
|
|
25
|
+
export const generateEmptyElement = function (type) {
|
|
26
|
+
let props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
27
|
+
return _objectSpread(_objectSpread({
|
|
26
28
|
id: slugid.nice(),
|
|
27
|
-
type
|
|
29
|
+
type
|
|
30
|
+
}, props), {}, {
|
|
28
31
|
children: [generateDefaultText()]
|
|
29
|
-
};
|
|
32
|
+
});
|
|
30
33
|
};
|
|
31
34
|
export function Placeholder(props) {
|
|
32
35
|
const {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
2
2
|
import { Editor, Transforms, Element } from '@seafile/slate';
|
|
3
3
|
import slugid from 'slugid';
|
|
4
|
-
import { BLOCKQUOTE, CHECK_LIST_ITEM, IMAGE, ORDERED_LIST, PARAGRAPH, UNORDERED_LIST, CODE_BLOCK, TABLE } from '../../constants';
|
|
4
|
+
import { BLOCKQUOTE, CHECK_LIST_ITEM, IMAGE, ORDERED_LIST, PARAGRAPH, UNORDERED_LIST, CODE_BLOCK, TABLE, CALL_OUT } from '../../constants';
|
|
5
5
|
import { focusEditor, getNodeType } from '../../core';
|
|
6
6
|
export const isMenuDisabled = (editor, readonly) => {
|
|
7
7
|
if (readonly) return true;
|
|
@@ -40,6 +40,8 @@ export const getBlockQuoteType = editor => {
|
|
|
40
40
|
const [n] = match;
|
|
41
41
|
return getNodeType(n);
|
|
42
42
|
};
|
|
43
|
+
|
|
44
|
+
// If cursor is in callout, insert block quote in callout, otherwise wrap block quote directly
|
|
43
45
|
export const setBlockQuoteType = (editor, active) => {
|
|
44
46
|
if (!active) {
|
|
45
47
|
const blockquoteNode = {
|
|
@@ -48,12 +50,18 @@ export const setBlockQuoteType = (editor, active) => {
|
|
|
48
50
|
};
|
|
49
51
|
Transforms.wrapNodes(editor, blockquoteNode, {
|
|
50
52
|
mode: 'highest',
|
|
51
|
-
match: n =>
|
|
53
|
+
match: n => {
|
|
54
|
+
if (n.type === CALL_OUT) return false;
|
|
55
|
+
return Element.isElement(n) && Editor.isBlock(editor, n);
|
|
56
|
+
}
|
|
52
57
|
});
|
|
53
58
|
} else {
|
|
54
59
|
Transforms.unwrapNodes(editor, {
|
|
55
60
|
mode: 'highest',
|
|
56
|
-
match: n =>
|
|
61
|
+
match: n => {
|
|
62
|
+
if (n.type === CALL_OUT) return false;
|
|
63
|
+
return Element.isElement(n) && Editor.isBlock(editor, n);
|
|
64
|
+
}
|
|
57
65
|
});
|
|
58
66
|
}
|
|
59
67
|
focusEditor(editor);
|
|
@@ -4,6 +4,7 @@ import { ReactEditor } from '@seafile/slate-react';
|
|
|
4
4
|
import { generateEmptyElement, getSelectedNodeByType, isSelectionAtBlockStart } from '../../core';
|
|
5
5
|
import { BLOCKQUOTE, PARAGRAPH, CODE_BLOCK, TABLE } from '../../constants';
|
|
6
6
|
import { setBlockQuoteType, getFormattedElements, getFormattedRestElements } from './helpers';
|
|
7
|
+
import { getCalloutEntry, insertElementAtNewLineInCallout } from '../callout/helper';
|
|
7
8
|
const withBlockquote = editor => {
|
|
8
9
|
const {
|
|
9
10
|
insertBreak,
|
|
@@ -30,6 +31,14 @@ const withBlockquote = editor => {
|
|
|
30
31
|
const str = Node.string(quoteElem);
|
|
31
32
|
// The last of the blockquote text is \n;
|
|
32
33
|
if (str && str.slice(-1) === '\n') {
|
|
34
|
+
const calloutEntry = getCalloutEntry(editor);
|
|
35
|
+
if (calloutEntry) {
|
|
36
|
+
// If the cursor is at the end of the callout, insert a paragraph inside the callout
|
|
37
|
+
// Remove the last \n
|
|
38
|
+
editor.deleteBackward('character');
|
|
39
|
+
insertElementAtNewLineInCallout(editor, PARAGRAPH, quotePath);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
33
42
|
// Step 1: Remove the last \n
|
|
34
43
|
editor.deleteBackward('character');
|
|
35
44
|
// Step 2: Insert a paragraph
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { BLOCKQUOTE, CALL_OUT, CHECK_LIST_ITEM, IMAGE, LINK, ORDERED_LIST, PARAGRAPH, SDOC_LINK, SUBTITLE, TITLE, UNORDERED_LIST } from '../../constants/element-type';
|
|
2
|
+
import { HEADERS, LIST_ITEM_CORRELATION_TYPE } from '../../constants';
|
|
3
|
+
|
|
4
|
+
// key as container fill color
|
|
5
|
+
export const CALLOUT_COLOR_MAP = {
|
|
6
|
+
'#f1f3f6': {
|
|
7
|
+
border_color: '#d9dbe0',
|
|
8
|
+
background_color: '#f1f3f6'
|
|
9
|
+
},
|
|
10
|
+
'#e1e9fe': {
|
|
11
|
+
border_color: '#cbdeff',
|
|
12
|
+
background_color: '#e1e9fe'
|
|
13
|
+
},
|
|
14
|
+
'#def0ff': {
|
|
15
|
+
border_color: '#c7ecff',
|
|
16
|
+
background_color: '#def0ff'
|
|
17
|
+
},
|
|
18
|
+
'#e7f9ee': {
|
|
19
|
+
border_color: '#a5dfbf',
|
|
20
|
+
background_color: '#e7f9ee'
|
|
21
|
+
},
|
|
22
|
+
'#eaf7d6': {
|
|
23
|
+
border_color: '#c3e788',
|
|
24
|
+
background_color: '#eaf7d6'
|
|
25
|
+
},
|
|
26
|
+
'#fef7e0': {
|
|
27
|
+
border_color: '#faecb3',
|
|
28
|
+
background_color: '#fef7e0'
|
|
29
|
+
},
|
|
30
|
+
'#fff1e8': {
|
|
31
|
+
border_color: '#ffe1cd',
|
|
32
|
+
background_color: '#fff1e8'
|
|
33
|
+
},
|
|
34
|
+
'#ffe6e3': {
|
|
35
|
+
border_color: '#ffc6c4',
|
|
36
|
+
background_color: '#ffe6e3'
|
|
37
|
+
},
|
|
38
|
+
'#ffe9f2': {
|
|
39
|
+
border_color: '#ffd0e6',
|
|
40
|
+
background_color: '#ffe9f2'
|
|
41
|
+
},
|
|
42
|
+
'#fde8ff': {
|
|
43
|
+
border_color: '#f0c1ff',
|
|
44
|
+
background_color: '#fde8ff'
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
export const CALLOUT_ALLOWED_INSIDE_TYPES = [CALL_OUT, ORDERED_LIST, UNORDERED_LIST, PARAGRAPH, TITLE, SUBTITLE, BLOCKQUOTE, ...HEADERS, ...LIST_ITEM_CORRELATION_TYPE, CHECK_LIST_ITEM, IMAGE, LINK, SDOC_LINK];
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { Editor, Node, Path, Transforms } from '@seafile/slate';
|
|
2
|
+
import { CALL_OUT } from '../../constants/element-type';
|
|
3
|
+
import { findPath, focusEditor, generateEmptyElement, getSelectedElems, isRangeAcrossBlocks } from '../../core';
|
|
4
|
+
import { CALLOUT_ALLOWED_INSIDE_TYPES, CALLOUT_COLOR_MAP } from './constant';
|
|
5
|
+
export const isMenuActive = editor => {
|
|
6
|
+
const {
|
|
7
|
+
selection
|
|
8
|
+
} = editor;
|
|
9
|
+
if (!selection) return false;
|
|
10
|
+
const isInsideCallout = !!getCalloutEntry(editor);
|
|
11
|
+
if (isInsideCallout) return true;
|
|
12
|
+
return false;
|
|
13
|
+
};
|
|
14
|
+
export const isMenuDisabled = (editor, readonly) => {
|
|
15
|
+
if (readonly) return true;
|
|
16
|
+
const {
|
|
17
|
+
selection
|
|
18
|
+
} = editor;
|
|
19
|
+
if (!selection) return true;
|
|
20
|
+
const selectedElements = getSelectedElems(editor);
|
|
21
|
+
const isRangeAcrossBlock = isRangeAcrossBlocks(editor);
|
|
22
|
+
// If selected multiple block element contains callout, disable callout menu
|
|
23
|
+
const isAllSelectedElementsInAllowTypes = selectedElements.length && selectedElements.every(element => {
|
|
24
|
+
if (element.type === CALL_OUT && isRangeAcrossBlock) return false;
|
|
25
|
+
return CALLOUT_ALLOWED_INSIDE_TYPES.includes(element.type);
|
|
26
|
+
});
|
|
27
|
+
if (isAllSelectedElementsInAllowTypes) return false;
|
|
28
|
+
return true;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* @param {keyof CALLOUT_COLOR_MAP} [background_color] fill color
|
|
33
|
+
*/
|
|
34
|
+
export const generateCallout = function () {
|
|
35
|
+
let background_color = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : Object.keys(CALLOUT_COLOR_MAP)[0];
|
|
36
|
+
const props = {
|
|
37
|
+
style: {
|
|
38
|
+
background_color
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
const callout = generateEmptyElement(CALL_OUT, props);
|
|
42
|
+
callout.children = [];
|
|
43
|
+
return callout;
|
|
44
|
+
};
|
|
45
|
+
export const wrapCallout = editor => {
|
|
46
|
+
const {
|
|
47
|
+
selection
|
|
48
|
+
} = editor;
|
|
49
|
+
if (!selection) return;
|
|
50
|
+
const callout = generateCallout();
|
|
51
|
+
Transforms.wrapNodes(editor, callout, {
|
|
52
|
+
mode: 'highest'
|
|
53
|
+
});
|
|
54
|
+
focusEditor(editor);
|
|
55
|
+
};
|
|
56
|
+
export const unwrapCallout = editor => {
|
|
57
|
+
const {
|
|
58
|
+
selection
|
|
59
|
+
} = editor;
|
|
60
|
+
if (!selection) return;
|
|
61
|
+
const aboveNodeEntry = Editor.above(editor, {
|
|
62
|
+
match: n => n.type === CALL_OUT
|
|
63
|
+
});
|
|
64
|
+
if (!aboveNodeEntry) return;
|
|
65
|
+
const [, calloutPath] = aboveNodeEntry;
|
|
66
|
+
Transforms.unwrapNodes(editor, {
|
|
67
|
+
at: calloutPath,
|
|
68
|
+
match: n => n.type === CALL_OUT
|
|
69
|
+
});
|
|
70
|
+
const point = Editor.point(editor, editor.selection);
|
|
71
|
+
focusEditor(editor, point);
|
|
72
|
+
};
|
|
73
|
+
export const changeFillBackgroundColor = (editor, background_color) => {
|
|
74
|
+
Transforms.setNodes(editor, {
|
|
75
|
+
style: {
|
|
76
|
+
background_color
|
|
77
|
+
}
|
|
78
|
+
}, {
|
|
79
|
+
match: n => n.type === CALL_OUT
|
|
80
|
+
});
|
|
81
|
+
Transforms.select(editor, Editor.start(editor, editor.selection));
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
// Check is cursor in callout
|
|
85
|
+
export const getCalloutEntry = function (editor) {
|
|
86
|
+
let at = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : editor.selection;
|
|
87
|
+
const aboveNodeEntry = Editor.above(editor, {
|
|
88
|
+
match: n => n.type === CALL_OUT,
|
|
89
|
+
mode: 'highest',
|
|
90
|
+
at
|
|
91
|
+
});
|
|
92
|
+
return aboveNodeEntry;
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
// Use in render-elem, to judge whether to display placeholder
|
|
96
|
+
export const isFocusOnElement = (editor, element) => {
|
|
97
|
+
var _editor$selection, _editor$selection$anc;
|
|
98
|
+
if (!editor.selection || !element) return false;
|
|
99
|
+
const elementPath = findPath(editor, element);
|
|
100
|
+
const isSelectOnElement = Path.isAncestor(elementPath, editor === null || editor === void 0 ? void 0 : (_editor$selection = editor.selection) === null || _editor$selection === void 0 ? void 0 : (_editor$selection$anc = _editor$selection.anchor) === null || _editor$selection$anc === void 0 ? void 0 : _editor$selection$anc.path);
|
|
101
|
+
return isSelectOnElement;
|
|
102
|
+
};
|
|
103
|
+
export const isCalloutContentEmpty = calloutEntry => {
|
|
104
|
+
const [calloutNode] = calloutEntry;
|
|
105
|
+
const contentString = Node.string(calloutNode);
|
|
106
|
+
return calloutNode.children.length === 1 && contentString.length === 0;
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
// Insert a new element at new line in callout after current path
|
|
110
|
+
export const insertElementAtNewLineInCallout = (editor, type, currentPath) => {
|
|
111
|
+
const element = generateEmptyElement(type);
|
|
112
|
+
const insertPath = Path.next(currentPath);
|
|
113
|
+
Transforms.insertNodes(editor, element, {
|
|
114
|
+
at: insertPath
|
|
115
|
+
});
|
|
116
|
+
Transforms.select(editor, insertPath);
|
|
117
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { CALL_OUT } from '../../constants';
|
|
2
|
+
import CalloutMenu from './menu';
|
|
3
|
+
import withCallout from './plugin';
|
|
4
|
+
import renderCallout from './render-elem';
|
|
5
|
+
const CalloutPlugin = {
|
|
6
|
+
type: CALL_OUT,
|
|
7
|
+
nodeType: 'element',
|
|
8
|
+
editorMenus: [CalloutMenu],
|
|
9
|
+
editorPlugin: withCallout,
|
|
10
|
+
renderElements: [renderCallout]
|
|
11
|
+
};
|
|
12
|
+
export default CalloutPlugin;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
.sdoc-callout-paste-unsupportable-type-alert {
|
|
2
|
+
display: none;
|
|
3
|
+
position: absolute;
|
|
4
|
+
top: 140px;
|
|
5
|
+
z-index: 1001;
|
|
6
|
+
left: 50%;
|
|
7
|
+
margin: auto;
|
|
8
|
+
transform: translateX(-50%);
|
|
9
|
+
transition: all 0.3s;
|
|
10
|
+
pointer-events: none;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.sdoc-callout-paste-unsupportable-type-alert.display {
|
|
14
|
+
display: block;
|
|
15
|
+
transition: all 0.3s;
|
|
16
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import React, { useCallback, useEffect } from 'react';
|
|
2
|
+
import { useTranslation } from 'react-i18next';
|
|
3
|
+
import { MenuItem } from '../../../commons';
|
|
4
|
+
import { MENUS_CONFIG_MAP } from '../../../constants';
|
|
5
|
+
import { CALL_OUT } from '../../../constants/element-type';
|
|
6
|
+
import { isMenuActive, isMenuDisabled, unwrapCallout, wrapCallout } from '../helper';
|
|
7
|
+
import { INTERNAL_EVENT } from '../../../../constants';
|
|
8
|
+
import toaster from '../../../../../components/toast';
|
|
9
|
+
import EventBus from '../../../../utils/event-bus';
|
|
10
|
+
const menuConfig = MENUS_CONFIG_MAP[CALL_OUT];
|
|
11
|
+
const CalloutMenu = _ref => {
|
|
12
|
+
let {
|
|
13
|
+
editor,
|
|
14
|
+
isRichEditor,
|
|
15
|
+
className,
|
|
16
|
+
readonly
|
|
17
|
+
} = _ref;
|
|
18
|
+
const {
|
|
19
|
+
t
|
|
20
|
+
} = useTranslation();
|
|
21
|
+
const handleDisplayAlert = useCallback(type => {
|
|
22
|
+
toaster.warning("".concat(t('The_current_location_does_not_support_pasting')).concat(t(type && type.at(0).toUpperCase() + type.slice(1))));
|
|
23
|
+
}, [t]);
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
const eventBus = EventBus.getInstance();
|
|
26
|
+
const unsubscribe = eventBus.subscribe(INTERNAL_EVENT.DISPLAY_CALLOUT_UNSUPPORT_ALERT, handleDisplayAlert);
|
|
27
|
+
return unsubscribe;
|
|
28
|
+
}, [handleDisplayAlert, t]);
|
|
29
|
+
const handleClick = useCallback(e => {
|
|
30
|
+
isMenuActive(editor) ? unwrapCallout(editor) : wrapCallout(editor);
|
|
31
|
+
}, [editor]);
|
|
32
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(MenuItem, Object.assign({
|
|
33
|
+
isRichEditor: isRichEditor,
|
|
34
|
+
className: className,
|
|
35
|
+
disabled: isMenuDisabled(editor, readonly),
|
|
36
|
+
isActive: isMenuActive(editor),
|
|
37
|
+
onMouseDown: handleClick
|
|
38
|
+
}, menuConfig)));
|
|
39
|
+
};
|
|
40
|
+
export default CalloutMenu;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import isHotkey from 'is-hotkey';
|
|
2
|
-
import { PARAGRAPH, INSERT_POSITION } from '../../constants';
|
|
2
|
+
import { PARAGRAPH, INSERT_POSITION, CODE_BLOCK } from '../../constants';
|
|
3
3
|
import { isSelectionAtBlockStart } from '../../core';
|
|
4
4
|
import { getCalloutEntry, isCalloutContentEmpty, unwrapCallout } from './helper';
|
|
5
5
|
import { insertElement } from '../../toolbar/side-toolbar/helpers';
|
|
@@ -15,23 +15,39 @@ const withCallout = editor => {
|
|
|
15
15
|
const {
|
|
16
16
|
insertFragment,
|
|
17
17
|
deleteBackward,
|
|
18
|
-
onHotKeyDown
|
|
18
|
+
onHotKeyDown,
|
|
19
|
+
insertData
|
|
19
20
|
} = editor;
|
|
20
21
|
const newEditor = editor;
|
|
21
22
|
newEditor.deleteBackward = unit => {
|
|
22
23
|
const calloutEntry = getCalloutEntry(editor);
|
|
23
24
|
if (calloutEntry) {
|
|
24
|
-
if (isSelectionAtBlockStart(editor) && isCalloutContentEmpty(
|
|
25
|
+
if (isSelectionAtBlockStart(editor) && isCalloutContentEmpty(calloutEntry)) {
|
|
26
|
+
unwrapCallout(editor);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
25
29
|
}
|
|
26
30
|
return deleteBackward(unit);
|
|
27
31
|
};
|
|
32
|
+
newEditor.insertData = data => {
|
|
33
|
+
if (getCalloutEntry(newEditor)) {
|
|
34
|
+
if (data.types.includes('text/code-block')) {
|
|
35
|
+
const eventBus = EventBus.getInstance();
|
|
36
|
+
eventBus.dispatch(INTERNAL_EVENT.DISPLAY_CALLOUT_UNSUPPORT_ALERT, CODE_BLOCK);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return insertData(data);
|
|
41
|
+
};
|
|
28
42
|
newEditor.insertFragment = data => {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
43
|
+
if (getCalloutEntry(editor)) {
|
|
44
|
+
var _data$find;
|
|
45
|
+
const eventBus = EventBus.getInstance();
|
|
46
|
+
const unsupportType = (_data$find = data.find(node => !CALLOUT_ALLOWED_INSIDE_TYPES.includes(node.type))) === null || _data$find === void 0 ? void 0 : _data$find.type;
|
|
47
|
+
if (unsupportType) {
|
|
48
|
+
eventBus.dispatch(INTERNAL_EVENT.DISPLAY_CALLOUT_UNSUPPORT_ALERT, unsupportType);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
35
51
|
}
|
|
36
52
|
return insertFragment(data);
|
|
37
53
|
};
|
|
@@ -40,16 +56,6 @@ const withCallout = editor => {
|
|
|
40
56
|
insertElement(newEditor, PARAGRAPH, INSERT_POSITION.AFTER);
|
|
41
57
|
return true;
|
|
42
58
|
}
|
|
43
|
-
if (isHotkey('enter', event)) {
|
|
44
|
-
const calloutEntry = getCalloutEntry(editor);
|
|
45
|
-
if (calloutEntry) {
|
|
46
|
-
if (isCalloutContentEmpty(editor, calloutEntry)) {
|
|
47
|
-
unwrapCallout(editor);
|
|
48
|
-
event.preventDefault();
|
|
49
|
-
return true;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
59
|
return onHotKeyDown && onHotKeyDown(event);
|
|
54
60
|
};
|
|
55
61
|
return newEditor;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import React, { forwardRef, useCallback, useImperativeHandle, useRef } from 'react';
|
|
2
|
+
import { Transforms } from '@seafile/slate';
|
|
3
|
+
import { CALLOUT_COLOR_MAP } from '../constant';
|
|
4
|
+
import { findPath } from '../../../core';
|
|
5
|
+
import { changeFillBackgroundColor } from '../helper';
|
|
6
|
+
import './index.css';
|
|
7
|
+
const ColorSelector = (_ref, ref) => {
|
|
8
|
+
let {
|
|
9
|
+
editor,
|
|
10
|
+
element
|
|
11
|
+
} = _ref;
|
|
12
|
+
const selectorRef = useRef(null);
|
|
13
|
+
const handleClickColor = useCallback((editor, element, background_color) => {
|
|
14
|
+
const currentPath = findPath(editor, element);
|
|
15
|
+
Transforms.select(editor, currentPath);
|
|
16
|
+
changeFillBackgroundColor(editor, background_color);
|
|
17
|
+
}, []);
|
|
18
|
+
useImperativeHandle(ref, () => ({
|
|
19
|
+
colorSelectorContainer: selectorRef.current
|
|
20
|
+
}));
|
|
21
|
+
const isShowCheckedIcon = useCallback((element, currentBackgroundColor) => {
|
|
22
|
+
const {
|
|
23
|
+
background_color
|
|
24
|
+
} = element.style;
|
|
25
|
+
return background_color && background_color === currentBackgroundColor;
|
|
26
|
+
}, []);
|
|
27
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
28
|
+
ref: selectorRef,
|
|
29
|
+
className: "sdoc-selector-gap-filler",
|
|
30
|
+
contentEditable: false
|
|
31
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
32
|
+
className: "sdoc-callout-color-selector-container"
|
|
33
|
+
}, /*#__PURE__*/React.createElement("ul", {
|
|
34
|
+
className: "sdoc-color-selector-list"
|
|
35
|
+
}, Object.values(CALLOUT_COLOR_MAP).map((_ref2, index) => {
|
|
36
|
+
let {
|
|
37
|
+
border_color,
|
|
38
|
+
background_color
|
|
39
|
+
} = _ref2;
|
|
40
|
+
return /*#__PURE__*/React.createElement("li", {
|
|
41
|
+
key: "sdoc-callout-color-selector-".concat(index),
|
|
42
|
+
className: "sdoc-callout-color-item",
|
|
43
|
+
onClick: () => handleClickColor(editor, element, Object.keys(CALLOUT_COLOR_MAP)[index]),
|
|
44
|
+
style: {
|
|
45
|
+
borderColor: border_color,
|
|
46
|
+
backgroundColor: background_color
|
|
47
|
+
}
|
|
48
|
+
}, isShowCheckedIcon(element, background_color) && /*#__PURE__*/React.createElement("i", {
|
|
49
|
+
className: "sdoc-callout-color-checked-icon sdocfont sdoc-check-mark"
|
|
50
|
+
}));
|
|
51
|
+
}))));
|
|
52
|
+
};
|
|
53
|
+
export default forwardRef(ColorSelector);
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
.sdoc-callout-white-wrapper {
|
|
2
|
+
padding: 5px 0;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
.sdoc-callout-container {
|
|
6
|
+
position: relative;
|
|
7
|
+
padding: 10px;
|
|
8
|
+
border-width: 1px;
|
|
9
|
+
border-style: solid;
|
|
10
|
+
border-radius: 5px;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.sdoc-callout-container .sdoc-callout-placeholder {
|
|
14
|
+
position: absolute;
|
|
15
|
+
top: 15px;
|
|
16
|
+
left: 10px;
|
|
17
|
+
color: #b8b6b6;
|
|
18
|
+
pointer-events: none;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.sdoc-selector-gap-filler {
|
|
22
|
+
position: absolute;
|
|
23
|
+
left: 0;
|
|
24
|
+
top: -40px;
|
|
25
|
+
width: 300px;
|
|
26
|
+
height: 100%;
|
|
27
|
+
z-index: 100;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.sdoc-selector-gap-filler .sdoc-callout-color-selector-container {
|
|
31
|
+
position: absolute;
|
|
32
|
+
padding: 10px;
|
|
33
|
+
top: -5px;
|
|
34
|
+
left: 5px;
|
|
35
|
+
background-color: #fff;
|
|
36
|
+
border: 1px solid #eee;
|
|
37
|
+
border-radius: 3px;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.sdoc-callout-color-selector-container .sdoc-color-selector-list {
|
|
41
|
+
display: flex;
|
|
42
|
+
margin: 0;
|
|
43
|
+
padding: 0;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.sdoc-callout-color-selector-container .sdoc-color-selector-list .sdoc-callout-color-item {
|
|
47
|
+
position: relative;
|
|
48
|
+
margin-right: 10px;
|
|
49
|
+
width: 16px;
|
|
50
|
+
height: 16px;
|
|
51
|
+
list-style: none;
|
|
52
|
+
border-width: 1px;
|
|
53
|
+
border-style: solid;
|
|
54
|
+
border-radius: 3px;
|
|
55
|
+
cursor: pointer;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.sdoc-callout-color-selector-container .sdoc-color-selector-list .sdoc-callout-color-item:last-child {
|
|
59
|
+
margin-right: 0px;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.sdoc-callout-color-selector-container .sdoc-color-selector-list .sdoc-callout-color-item .sdoc-callout-color-checked-icon {
|
|
63
|
+
position: absolute;
|
|
64
|
+
top: -2px;
|
|
65
|
+
font-size: 12px;
|
|
66
|
+
left: 1px;
|
|
67
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/* eslint-disable react-hooks/rules-of-hooks */
|
|
2
|
+
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
|
3
|
+
import { useTranslation } from 'react-i18next';
|
|
4
|
+
import ColorSelector from './color-selector';
|
|
5
|
+
import { CALLOUT_COLOR_MAP } from '../constant';
|
|
6
|
+
import { isFocusOnElement } from '../helper';
|
|
7
|
+
import { Editor } from '@seafile/slate';
|
|
8
|
+
import { findPath } from '../../../core';
|
|
9
|
+
import { INTERNAL_EVENT } from '../../../../constants';
|
|
10
|
+
import EventBus from '../../../../utils/event-bus';
|
|
11
|
+
import './index.css';
|
|
12
|
+
const renderCallout = (_ref, editor) => {
|
|
13
|
+
let {
|
|
14
|
+
attributes,
|
|
15
|
+
children,
|
|
16
|
+
element
|
|
17
|
+
} = _ref;
|
|
18
|
+
const [isShowColorSelector, setIsShowColorSelector] = useState(false);
|
|
19
|
+
const [isSelecting, setIsSelecting] = useState(false);
|
|
20
|
+
const calloutRef = useRef(null);
|
|
21
|
+
const colorSelectorRef = useRef({
|
|
22
|
+
colorSelectorContainer: null
|
|
23
|
+
});
|
|
24
|
+
const {
|
|
25
|
+
t
|
|
26
|
+
} = useTranslation();
|
|
27
|
+
const {
|
|
28
|
+
background_color
|
|
29
|
+
} = element.style;
|
|
30
|
+
const isFocusOnCallout = isFocusOnElement(editor, element);
|
|
31
|
+
const handleMouseEnter = useCallback(id => {
|
|
32
|
+
const isMoveInCurrentCallout = id === element.id;
|
|
33
|
+
isMoveInCurrentCallout && !isSelecting && setIsShowColorSelector(true);
|
|
34
|
+
}, [element.id, isSelecting]);
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
const eventBus = EventBus.getInstance();
|
|
37
|
+
const unsubscribe = eventBus.subscribe(INTERNAL_EVENT.DISPLAY_CALLOUT_COLOR_PICKER, handleMouseEnter);
|
|
38
|
+
return unsubscribe;
|
|
39
|
+
}, [handleMouseEnter]);
|
|
40
|
+
const handleMouseLeave = useCallback(e => {
|
|
41
|
+
setIsShowColorSelector(false);
|
|
42
|
+
setIsSelecting(false);
|
|
43
|
+
}, []);
|
|
44
|
+
const handleClick = useCallback(e => {
|
|
45
|
+
var _colorSelectorRef$cur, _colorSelectorRef$cur2;
|
|
46
|
+
setIsSelecting(true);
|
|
47
|
+
const isClickInColorSelector = (_colorSelectorRef$cur = colorSelectorRef.current) === null || _colorSelectorRef$cur === void 0 ? void 0 : (_colorSelectorRef$cur2 = _colorSelectorRef$cur.colorSelectorContainer) === null || _colorSelectorRef$cur2 === void 0 ? void 0 : _colorSelectorRef$cur2.contains(e.target);
|
|
48
|
+
!isClickInColorSelector && setIsShowColorSelector(false);
|
|
49
|
+
}, []);
|
|
50
|
+
const isShowPlaceholder = useCallback(() => {
|
|
51
|
+
if (isFocusOnCallout) return false;
|
|
52
|
+
// If element contains more than one element or element is not paragraph, show placeholder
|
|
53
|
+
const isContainUnitElement = element.children.length !== 1 || element.children.some(childElement => childElement.type !== 'paragraph');
|
|
54
|
+
if (isContainUnitElement) return false;
|
|
55
|
+
const elementPath = findPath(editor, element);
|
|
56
|
+
const elementContent = Editor.string(editor, elementPath);
|
|
57
|
+
return !elementContent.length;
|
|
58
|
+
}, [editor, element, isFocusOnCallout]);
|
|
59
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
60
|
+
className: "sdoc-callout-white-wrapper"
|
|
61
|
+
}, /*#__PURE__*/React.createElement("div", Object.assign({
|
|
62
|
+
"data-id": element.id,
|
|
63
|
+
"data-root": "true",
|
|
64
|
+
onMouseLeave: handleMouseLeave,
|
|
65
|
+
onClick: handleClick,
|
|
66
|
+
ref: calloutRef,
|
|
67
|
+
style: {
|
|
68
|
+
backgroundColor: background_color ? CALLOUT_COLOR_MAP[background_color].background_color : 'transparent',
|
|
69
|
+
borderColor: isFocusOnCallout ? CALLOUT_COLOR_MAP[background_color].border_color : 'transparent'
|
|
70
|
+
}
|
|
71
|
+
}, attributes, {
|
|
72
|
+
className: "".concat(attributes.className, " sdoc-callout-container")
|
|
73
|
+
}), children, isShowPlaceholder() && /*#__PURE__*/React.createElement("div", {
|
|
74
|
+
contentEditable: false,
|
|
75
|
+
className: "sdoc-callout-placeholder"
|
|
76
|
+
}, t('Please_enter...')), isShowColorSelector && /*#__PURE__*/React.createElement(ColorSelector, {
|
|
77
|
+
ref: colorSelectorRef,
|
|
78
|
+
editor: editor,
|
|
79
|
+
element: element
|
|
80
|
+
})));
|
|
81
|
+
};
|
|
82
|
+
export default renderCallout;
|
|
@@ -4,12 +4,14 @@ import slugid from 'slugid';
|
|
|
4
4
|
import { CODE_BLOCK, CODE_LINE, INSERT_POSITION, PARAGRAPH } from '../../constants';
|
|
5
5
|
import { getNodeType, getSelectedNodeByType, getSelectedElems } from '../../core';
|
|
6
6
|
import { genCodeLangs } from './prismjs';
|
|
7
|
+
import { getCalloutEntry } from '../callout/helper';
|
|
7
8
|
export const isMenuDisabled = (editor, readonly) => {
|
|
8
9
|
if (readonly) return true;
|
|
9
10
|
const {
|
|
10
11
|
selection
|
|
11
12
|
} = editor;
|
|
12
13
|
if (selection == null) return true;
|
|
14
|
+
if (getCalloutEntry(editor)) return true;
|
|
13
15
|
const selectedElems = getSelectedElems(editor);
|
|
14
16
|
const hasVoid = selectedElems.some(elem => editor.isVoid(elem));
|
|
15
17
|
if (hasVoid) return true;
|
|
@@ -14,6 +14,7 @@ import FontPlugin from './font';
|
|
|
14
14
|
import SdocLinkPlugin from './sdoc-link';
|
|
15
15
|
import FileLinkPlugin from './file-link';
|
|
16
16
|
import ParagraphPlugin from './paragraph';
|
|
17
|
-
|
|
17
|
+
import CalloutPlugin from './callout';
|
|
18
|
+
const Plugins = [MarkDownPlugin, HtmlPlugin, HeaderPlugin, LinkPlugin, BlockquotePlugin, ListPlugin, CheckListPlugin, CodeBlockPlugin, ImagePlugin, TablePlugin, TextPlugin, TextAlignPlugin, FontPlugin, SdocLinkPlugin, FileLinkPlugin, CalloutPlugin];
|
|
18
19
|
export default Plugins;
|
|
19
|
-
export { MarkDownPlugin, HeaderPlugin, LinkPlugin, BlockquotePlugin, ListPlugin, CheckListPlugin, CodeBlockPlugin, ImagePlugin, TablePlugin, TextPlugin, HtmlPlugin, TextAlignPlugin, FontPlugin, SdocLinkPlugin, ParagraphPlugin, FileLinkPlugin };
|
|
20
|
+
export { MarkDownPlugin, HeaderPlugin, LinkPlugin, BlockquotePlugin, ListPlugin, CheckListPlugin, CodeBlockPlugin, ImagePlugin, TablePlugin, TextPlugin, HtmlPlugin, TextAlignPlugin, FontPlugin, SdocLinkPlugin, ParagraphPlugin, FileLinkPlugin, CalloutPlugin };
|
|
@@ -22,10 +22,12 @@ const Paragraph = _ref => {
|
|
|
22
22
|
const style = {
|
|
23
23
|
textAlign: element.align
|
|
24
24
|
};
|
|
25
|
+
const newAttributes = _objectSpread(_objectSpread({}, attributes), typeof attributes.onMouseEnter === 'function' && {
|
|
26
|
+
'data-root': 'true'
|
|
27
|
+
});
|
|
25
28
|
return /*#__PURE__*/React.createElement("p", Object.assign({
|
|
26
|
-
"data-id": element.id
|
|
27
|
-
|
|
28
|
-
}, attributes, {
|
|
29
|
+
"data-id": element.id
|
|
30
|
+
}, newAttributes, {
|
|
29
31
|
style: _objectSpread({
|
|
30
32
|
position: isShowPlaceHolder ? 'relative' : ''
|
|
31
33
|
}, style)
|
|
@@ -32,6 +32,7 @@ export const isTableMenuDisabled = (editor, readonly) => {
|
|
|
32
32
|
if (type === ELEMENT_TYPE.TABLE) return true;
|
|
33
33
|
if (type === ELEMENT_TYPE.TABLE_CELL) return true;
|
|
34
34
|
if (type === ELEMENT_TYPE.TABLE_ROW) return true;
|
|
35
|
+
if (type === ELEMENT_TYPE.CALL_OUT) return true;
|
|
35
36
|
if (Editor.isVoid(editor, n)) return true;
|
|
36
37
|
return false;
|
|
37
38
|
},
|
|
@@ -15,12 +15,12 @@ const TableSizePopover = _ref => {
|
|
|
15
15
|
} = _ref;
|
|
16
16
|
const minSize = [5, 10];
|
|
17
17
|
const maxSize = [10, 10];
|
|
18
|
-
const {
|
|
19
|
-
t
|
|
20
|
-
} = useTranslation();
|
|
21
18
|
const [displaySize, setDisplaySize] = useState([5, 10]);
|
|
22
19
|
const [selectedSize, setSelectedSize] = useState([1, 1]);
|
|
23
20
|
const ref = useRef(null);
|
|
21
|
+
const {
|
|
22
|
+
t
|
|
23
|
+
} = useTranslation();
|
|
24
24
|
const onMouseEnter = useCallback(function (event) {
|
|
25
25
|
let cellPosition = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [1, 1];
|
|
26
26
|
let newDisplaySize = displaySize.slice(0);
|
|
@@ -83,12 +83,11 @@ const TableSizePopover = _ref => {
|
|
|
83
83
|
className: "sdoc-selected-table-size-container w-100 h-100 d-flex flex-column"
|
|
84
84
|
}, /*#__PURE__*/React.createElement("div", {
|
|
85
85
|
className: "sdoc-selected-table-tools-container"
|
|
86
|
-
}, /*#__PURE__*/React.createElement(
|
|
86
|
+
}, /*#__PURE__*/React.createElement(MenuItem, {
|
|
87
87
|
id: "sdoc-table-template-review-btn",
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
}))), /*#__PURE__*/React.createElement("div", {
|
|
88
|
+
text: "Table_template",
|
|
89
|
+
iconClassname: "sdocfont sdoc-right-slide sdoc-dropdown-item-right-icon"
|
|
90
|
+
})), /*#__PURE__*/React.createElement("div", {
|
|
92
91
|
className: "sdoc-table-size-select"
|
|
93
92
|
}, renderTableSize()), /*#__PURE__*/React.createElement("div", {
|
|
94
93
|
className: "sdoc-selected-table-size-tip w-100 "
|
|
@@ -97,4 +96,23 @@ const TableSizePopover = _ref => {
|
|
|
97
96
|
targetId: "sdoc-table-template-review-btn"
|
|
98
97
|
})));
|
|
99
98
|
};
|
|
100
|
-
export default TableSizePopover;
|
|
99
|
+
export default TableSizePopover;
|
|
100
|
+
const MenuItem = _ref2 => {
|
|
101
|
+
let {
|
|
102
|
+
id,
|
|
103
|
+
className,
|
|
104
|
+
text,
|
|
105
|
+
iconClassname
|
|
106
|
+
} = _ref2;
|
|
107
|
+
const {
|
|
108
|
+
t
|
|
109
|
+
} = useTranslation();
|
|
110
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
111
|
+
id: id,
|
|
112
|
+
className: classnames('sdoc-selected-table-size-custom', {
|
|
113
|
+
className
|
|
114
|
+
})
|
|
115
|
+
}, /*#__PURE__*/React.createElement("span", null, t(text)), /*#__PURE__*/React.createElement("i", {
|
|
116
|
+
className: iconClassname
|
|
117
|
+
}));
|
|
118
|
+
};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
.sdoc-table-template-inner-popover {
|
|
2
2
|
display: flex;
|
|
3
3
|
flex-wrap: wrap;
|
|
4
|
-
padding:
|
|
5
|
-
width:
|
|
4
|
+
padding: 10px;
|
|
5
|
+
width: 310px;
|
|
6
6
|
height: 100%;
|
|
7
7
|
background-color: #fff;
|
|
8
8
|
}
|
|
@@ -14,9 +14,13 @@
|
|
|
14
14
|
cursor: pointer;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
+
.sdoc-table-template-view-table:hover {
|
|
18
|
+
box-shadow: 0 0 3px 2px #e2e3e6;
|
|
19
|
+
}
|
|
20
|
+
|
|
17
21
|
.sdoc-table-template-view-table .sdoc-table-template-row .sdoc-table-template-cell {
|
|
18
|
-
width:
|
|
19
|
-
height:
|
|
22
|
+
width: 28px;
|
|
23
|
+
height: 15px;
|
|
20
24
|
border-left: 1px solid #e2e3e6;
|
|
21
25
|
border-right: 1px solid #e2e3e6;
|
|
22
26
|
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
2
2
|
import { useSlateStatic } from '@seafile/slate-react';
|
|
3
|
-
import { BLOCKQUOTE, LINK, CHECK_LIST_ITEM, HEADER1, HEADER2, HEADER3, HEADER4, HEADER5, HEADER6, LIST_ITEM, ORDERED_LIST, PARAGRAPH, UNORDERED_LIST, CODE_BLOCK, CODE_LINE, IMAGE, ELEMENT_TYPE, SDOC_LINK, FILE_LINK, TITLE, SUBTITLE, SUPPORTED_SIDE_OPERATION_TYPE } from '../constants';
|
|
4
|
-
import { BlockquotePlugin, LinkPlugin, CheckListPlugin, HeaderPlugin, ListPlugin, CodeBlockPlugin, ImagePlugin, TablePlugin, SdocLinkPlugin, ParagraphPlugin, FileLinkPlugin } from '../plugins';
|
|
5
|
-
import {
|
|
3
|
+
import { BLOCKQUOTE, LINK, CHECK_LIST_ITEM, HEADER1, HEADER2, HEADER3, HEADER4, HEADER5, HEADER6, LIST_ITEM, ORDERED_LIST, PARAGRAPH, UNORDERED_LIST, CODE_BLOCK, CODE_LINE, IMAGE, ELEMENT_TYPE, SDOC_LINK, FILE_LINK, TITLE, SUBTITLE, CALL_OUT, SUPPORTED_SIDE_OPERATION_TYPE } from '../constants';
|
|
4
|
+
import { BlockquotePlugin, LinkPlugin, CheckListPlugin, HeaderPlugin, ListPlugin, CodeBlockPlugin, ImagePlugin, TablePlugin, SdocLinkPlugin, ParagraphPlugin, FileLinkPlugin, CalloutPlugin } from '../plugins';
|
|
5
|
+
import { onDragOver, onDragLeave, onDrop } from '../toolbar/side-toolbar/event';
|
|
6
6
|
import { getParentNode } from '../core';
|
|
7
|
+
import { setMouseEnter } from './helper';
|
|
7
8
|
const CustomRenderElement = props => {
|
|
8
9
|
const editor = useSlateStatic();
|
|
9
10
|
const {
|
|
@@ -11,7 +12,7 @@ const CustomRenderElement = props => {
|
|
|
11
12
|
attributes
|
|
12
13
|
} = props;
|
|
13
14
|
if (SUPPORTED_SIDE_OPERATION_TYPE.includes(element.type)) {
|
|
14
|
-
|
|
15
|
+
setMouseEnter(editor, element, attributes);
|
|
15
16
|
attributes['onDragOver'] = onDragOver;
|
|
16
17
|
attributes['onDragLeave'] = onDragLeave;
|
|
17
18
|
attributes['onDrop'] = onDrop;
|
|
@@ -20,6 +21,11 @@ const CustomRenderElement = props => {
|
|
|
20
21
|
switch (element.type) {
|
|
21
22
|
case PARAGRAPH:
|
|
22
23
|
{
|
|
24
|
+
const parentNode = getParentNode(editor.children, element.id);
|
|
25
|
+
if (parentNode && parentNode.type === LIST_ITEM) {
|
|
26
|
+
const [renderParagraph] = ParagraphPlugin.renderElements;
|
|
27
|
+
return renderParagraph(props);
|
|
28
|
+
}
|
|
23
29
|
const [renderParagraph] = ParagraphPlugin.renderElements;
|
|
24
30
|
return renderParagraph(props);
|
|
25
31
|
}
|
|
@@ -119,6 +125,11 @@ const CustomRenderElement = props => {
|
|
|
119
125
|
const [renderFileLink] = FileLinkPlugin.renderElements;
|
|
120
126
|
return renderFileLink(props, editor);
|
|
121
127
|
}
|
|
128
|
+
case CALL_OUT:
|
|
129
|
+
{
|
|
130
|
+
const [renderCallout] = CalloutPlugin.renderElements;
|
|
131
|
+
return renderCallout(props, editor);
|
|
132
|
+
}
|
|
122
133
|
default:
|
|
123
134
|
{
|
|
124
135
|
const [renderParagraph] = ParagraphPlugin.renderElements;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Editor } from '@seafile/slate';
|
|
2
|
+
import { findPath } from '../core';
|
|
3
|
+
import { CALL_OUT, MOUSE_ENTER_EVENT_DISABLED_MAP } from '../constants';
|
|
4
|
+
import { INTERNAL_EVENT } from '../../constants';
|
|
5
|
+
import EventBus from '../../utils/event-bus';
|
|
6
|
+
import { onMouseEnter } from '../toolbar/side-toolbar/event';
|
|
7
|
+
const isNeedAddMouseEnterEvent = (editor, element) => {
|
|
8
|
+
const elementPath = findPath(editor, element);
|
|
9
|
+
// If the element is the root element, return true
|
|
10
|
+
if (elementPath.length <= 1) return true;
|
|
11
|
+
// If the element type is not in filter list, return true
|
|
12
|
+
if (!Reflect.ownKeys(MOUSE_ENTER_EVENT_DISABLED_MAP).includes(element.type)) return true;
|
|
13
|
+
const disableEventEntry = Editor.above(editor, {
|
|
14
|
+
match: n => MOUSE_ENTER_EVENT_DISABLED_MAP[element.type].includes(n.type),
|
|
15
|
+
mode: 'highest',
|
|
16
|
+
at: elementPath
|
|
17
|
+
});
|
|
18
|
+
return !disableEventEntry;
|
|
19
|
+
};
|
|
20
|
+
export const setMouseEnter = (editor, element, attributes) => {
|
|
21
|
+
if (!isNeedAddMouseEnterEvent(editor, element)) return;
|
|
22
|
+
attributes['onMouseEnter'] = e => onMouseEnter(e, element);
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
// Element extra event
|
|
26
|
+
export const handleElementMouseEnterEvent = element => {
|
|
27
|
+
const {
|
|
28
|
+
id,
|
|
29
|
+
type
|
|
30
|
+
} = element;
|
|
31
|
+
const eventBus = EventBus.getInstance();
|
|
32
|
+
const elementEventMap = {
|
|
33
|
+
[CALL_OUT]: eventBus.dispatch(INTERNAL_EVENT.DISPLAY_CALLOUT_COLOR_PICKER, id)
|
|
34
|
+
};
|
|
35
|
+
const event = elementEventMap[type];
|
|
36
|
+
event && event();
|
|
37
|
+
};
|
|
@@ -13,6 +13,7 @@ import HistoryMenu from './redo-undo';
|
|
|
13
13
|
import Font from '../../plugins/font/menu';
|
|
14
14
|
import InsertToolbar from './insert-toolbar';
|
|
15
15
|
import ActiveTableMenu from '../../plugins/table/menu/active-table-menu';
|
|
16
|
+
import CalloutMenu from '../../plugins/callout/menu';
|
|
16
17
|
const HeaderToolbar = _ref => {
|
|
17
18
|
let {
|
|
18
19
|
editor,
|
|
@@ -56,6 +57,9 @@ const HeaderToolbar = _ref => {
|
|
|
56
57
|
}), /*#__PURE__*/React.createElement(TextAlignMenu, {
|
|
57
58
|
editor: editor,
|
|
58
59
|
readonly: readonly
|
|
60
|
+
}), /*#__PURE__*/React.createElement(CalloutMenu, {
|
|
61
|
+
editor: editor,
|
|
62
|
+
readonly: readonly
|
|
59
63
|
})), /*#__PURE__*/React.createElement(ActiveTableMenu, {
|
|
60
64
|
editor: editor,
|
|
61
65
|
readonly: readonly
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import EventBus from '../../../utils/event-bus';
|
|
2
2
|
import { INTERNAL_EVENT } from '../../../constants';
|
|
3
|
-
|
|
3
|
+
import { CALL_OUT } from '../../constants';
|
|
4
|
+
import { handleElementMouseEnterEvent } from '../../render/helper';
|
|
5
|
+
export const onMouseEnter = (event, element) => {
|
|
4
6
|
event.stopPropagation();
|
|
5
7
|
const eventBus = EventBus.getInstance();
|
|
6
8
|
eventBus.dispatch(INTERNAL_EVENT.ON_MOUSE_ENTER_BLOCK, event);
|
|
9
|
+
element.type === CALL_OUT && eventBus.dispatch(INTERNAL_EVENT.DISPLAY_CALLOUT_COLOR_PICKER);
|
|
10
|
+
handleElementMouseEnterEvent(element);
|
|
7
11
|
};
|
|
8
12
|
export const onDragOver = event => {
|
|
9
13
|
event.stopPropagation();
|
|
@@ -6,10 +6,15 @@ import { toggleList } from '../../plugins/list/transforms';
|
|
|
6
6
|
import { generateEmptyElement } from '../../core';
|
|
7
7
|
import { generateEmptyList } from '../../plugins/list/model';
|
|
8
8
|
import { setClipboardCodeBlockData } from '../../plugins/code-block/helpers';
|
|
9
|
-
import { ORDERED_LIST, UNORDERED_LIST, PARAGRAPH, CHECK_LIST_ITEM, IMAGE, TABLE, CODE_BLOCK, BLOCKQUOTE, LIST_ITEM_CORRELATION_TYPE, ADD_POSITION_OFFSET_TYPE, INSERT_POSITION, ELEMENT_TYPE } from '../../constants';
|
|
9
|
+
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
|
+
import { unwrapCallout, wrapCallout } from '../../plugins/callout/helper';
|
|
11
12
|
export const onSetNodeType = (editor, element, type) => {
|
|
12
13
|
if (!type) return;
|
|
14
|
+
if (type === CALL_OUT) {
|
|
15
|
+
wrapCallout(editor);
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
13
18
|
if ([ORDERED_LIST, UNORDERED_LIST].includes(type)) {
|
|
14
19
|
toggleList(editor, type);
|
|
15
20
|
return;
|
|
@@ -70,6 +75,10 @@ export const onCopyNode = (editor, element) => {
|
|
|
70
75
|
}
|
|
71
76
|
};
|
|
72
77
|
export const onDeleteNode = (editor, element) => {
|
|
78
|
+
if (element.type === CALL_OUT) {
|
|
79
|
+
unwrapCallout(editor);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
73
82
|
const path = ReactEditor.findPath(editor, element);
|
|
74
83
|
Transforms.removeNodes(editor, {
|
|
75
84
|
at: path
|
|
@@ -92,10 +101,11 @@ export const isVoidNode = node => {
|
|
|
92
101
|
const hasImage = node.children.find(n => n.type === IMAGE);
|
|
93
102
|
const isTable = node.type === TABLE;
|
|
94
103
|
const isCodeBlock = node.type === CODE_BLOCK;
|
|
95
|
-
|
|
104
|
+
const isCallout = node.type === CALL_OUT;
|
|
105
|
+
return Node.string(node) === '' && !hasImage && !isTable && !isCodeBlock && !isCallout;
|
|
96
106
|
};
|
|
97
107
|
export const isNotSupportTransform = node => {
|
|
98
|
-
if (node.type && [CODE_BLOCK, TABLE].includes(node.type)) {
|
|
108
|
+
if (node.type && [CODE_BLOCK, TABLE, CALL_OUT].includes(node.type)) {
|
|
99
109
|
return true;
|
|
100
110
|
}
|
|
101
111
|
return false;
|
|
@@ -8,7 +8,8 @@ import { useScrollContext } from '../../../hooks/use-scroll-context';
|
|
|
8
8
|
import { focusEditor } from '../../core';
|
|
9
9
|
import { getDomTopHeight, setSelection, isVoidNode, getNodeEntry, isBlockquote, isList, onWrapListItem } from './helpers';
|
|
10
10
|
import { INTERNAL_EVENT } from '../../../constants';
|
|
11
|
-
import { CODE_BLOCK, TABLE, BLOCKQUOTE, CHECK_LIST_ITEM } from '../../constants';
|
|
11
|
+
import { CODE_BLOCK, TABLE, BLOCKQUOTE, CHECK_LIST_ITEM, CALL_OUT } from '../../constants';
|
|
12
|
+
import { getCalloutEntry } from '../../plugins/callout/helper';
|
|
12
13
|
import './index.css';
|
|
13
14
|
let sourceElement = null;
|
|
14
15
|
let targetElement = null;
|
|
@@ -118,6 +119,11 @@ const SideToolbar = () => {
|
|
|
118
119
|
return;
|
|
119
120
|
}
|
|
120
121
|
|
|
122
|
+
// Drag into callout is not supported
|
|
123
|
+
if ([CALL_OUT, CODE_BLOCK, TABLE].includes(sourceNode.type) && getCalloutEntry(editor, targetPath)) {
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
|
|
121
127
|
// Drag list
|
|
122
128
|
if (isList(editor, sourcePath)) {
|
|
123
129
|
// ordinary list items
|
|
@@ -8,10 +8,11 @@ import TableSizePopover from '../../plugins/table/popover/table-size-popover';
|
|
|
8
8
|
import { changeToCodeBlock } from '../../plugins/code-block/helpers';
|
|
9
9
|
import { toggleList } from '../../plugins/list/transforms';
|
|
10
10
|
import { setCheckListItemType } from '../../plugins/check-list/helpers';
|
|
11
|
-
import { ELEMENT_TYPE, INSERT_POSITION, LOCAL_IMAGE, SIDE_INSERT_MENUS_CONFIG } from '../../constants';
|
|
11
|
+
import { ELEMENT_TYPE, INSERT_POSITION, LOCAL_IMAGE, PARAGRAPH, SIDE_INSERT_MENUS_CONFIG } from '../../constants';
|
|
12
12
|
import EventBus from '../../../utils/event-bus';
|
|
13
13
|
import { INTERNAL_EVENT } from '../../../constants';
|
|
14
14
|
import DropdownMenuItem from '../../commons/dropdown-menu-item';
|
|
15
|
+
import { wrapCallout } from '../../plugins/callout/helper';
|
|
15
16
|
const InsertBlockMenu = _ref => {
|
|
16
17
|
let {
|
|
17
18
|
insertPosition,
|
|
@@ -65,6 +66,14 @@ const InsertBlockMenu = _ref => {
|
|
|
65
66
|
insertElement(editor, type, insertPosition);
|
|
66
67
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
67
68
|
}, [editor, insertPosition, slateNode]);
|
|
69
|
+
const onInsertCallout = useCallback(type => {
|
|
70
|
+
if (insertPosition === INSERT_POSITION.CURRENT) {
|
|
71
|
+
wrapCallout(editor);
|
|
72
|
+
} else if (insertPosition === INSERT_POSITION.AFTER) {
|
|
73
|
+
insertElement(editor, type, insertPosition);
|
|
74
|
+
wrapCallout(editor);
|
|
75
|
+
}
|
|
76
|
+
}, [editor, insertPosition]);
|
|
68
77
|
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(DropdownMenuItem, {
|
|
69
78
|
menuConfig: _objectSpread({}, SIDE_INSERT_MENUS_CONFIG[ELEMENT_TYPE.IMAGE]),
|
|
70
79
|
onClick: onInsertImageToggle
|
|
@@ -86,6 +95,9 @@ const InsertBlockMenu = _ref => {
|
|
|
86
95
|
}), /*#__PURE__*/React.createElement(DropdownMenuItem, {
|
|
87
96
|
menuConfig: _objectSpread({}, SIDE_INSERT_MENUS_CONFIG[ELEMENT_TYPE.CODE_BLOCK]),
|
|
88
97
|
onClick: onInsertCodeBlock
|
|
98
|
+
}), /*#__PURE__*/React.createElement(DropdownMenuItem, {
|
|
99
|
+
menuConfig: _objectSpread({}, SIDE_INSERT_MENUS_CONFIG[ELEMENT_TYPE.CALL_OUT]),
|
|
100
|
+
onClick: () => onInsertCallout(PARAGRAPH)
|
|
89
101
|
}), /*#__PURE__*/React.createElement(DropdownMenuItem, {
|
|
90
102
|
menuConfig: _objectSpread({}, SIDE_INSERT_MENUS_CONFIG[ELEMENT_TYPE.UNORDERED_LIST]),
|
|
91
103
|
onClick: () => {
|
package/package.json
CHANGED
|
@@ -414,5 +414,8 @@
|
|
|
414
414
|
"New": "Nový",
|
|
415
415
|
"Table_template": "Table template",
|
|
416
416
|
"Jump_to_original_doc": "Jump to the original document",
|
|
417
|
-
"Freezed": "Freezed"
|
|
417
|
+
"Freezed": "Freezed",
|
|
418
|
+
"Callout": "Callout",
|
|
419
|
+
"The_current_location_does_not_support_pasting": "The current location does not support pasting ",
|
|
420
|
+
"Please_enter...": "Please enter..."
|
|
418
421
|
}
|
|
@@ -414,5 +414,8 @@
|
|
|
414
414
|
"New": "Erstellen",
|
|
415
415
|
"Table_template": "Table template",
|
|
416
416
|
"Jump_to_original_doc": "Jump to the original document",
|
|
417
|
-
"Freezed": "Freezed"
|
|
417
|
+
"Freezed": "Freezed",
|
|
418
|
+
"Callout": "Callout",
|
|
419
|
+
"The_current_location_does_not_support_pasting": "The current location does not support pasting ",
|
|
420
|
+
"Please_enter...": "Please enter..."
|
|
418
421
|
}
|
|
@@ -414,5 +414,8 @@
|
|
|
414
414
|
"New": "New",
|
|
415
415
|
"Table_template": "Table template",
|
|
416
416
|
"Jump_to_original_doc": "Jump to the original document",
|
|
417
|
-
"Freezed": "Freezed"
|
|
417
|
+
"Freezed": "Freezed",
|
|
418
|
+
"Callout": "Callout",
|
|
419
|
+
"The_current_location_does_not_support_pasting": "The current location does not support pasting ",
|
|
420
|
+
"Please_enter...": "Please enter..."
|
|
418
421
|
}
|
|
@@ -414,5 +414,8 @@
|
|
|
414
414
|
"New": "Nuevo",
|
|
415
415
|
"Table_template": "Table template",
|
|
416
416
|
"Jump_to_original_doc": "Jump to the original document",
|
|
417
|
-
"Freezed": "Freezed"
|
|
417
|
+
"Freezed": "Freezed",
|
|
418
|
+
"Callout": "Callout",
|
|
419
|
+
"The_current_location_does_not_support_pasting": "The current location does not support pasting ",
|
|
420
|
+
"Please_enter...": "Please enter..."
|
|
418
421
|
}
|
|
@@ -414,5 +414,8 @@
|
|
|
414
414
|
"New": "Créer",
|
|
415
415
|
"Table_template": "Table template",
|
|
416
416
|
"Jump_to_original_doc": "Jump to the original document",
|
|
417
|
-
"Freezed": "Freezed"
|
|
417
|
+
"Freezed": "Freezed",
|
|
418
|
+
"Callout": "Callout",
|
|
419
|
+
"The_current_location_does_not_support_pasting": "The current location does not support pasting ",
|
|
420
|
+
"Please_enter...": "Please enter..."
|
|
418
421
|
}
|
|
@@ -414,5 +414,8 @@
|
|
|
414
414
|
"New": "Nuovo",
|
|
415
415
|
"Table_template": "Table template",
|
|
416
416
|
"Jump_to_original_doc": "Jump to the original document",
|
|
417
|
-
"Freezed": "Freezed"
|
|
417
|
+
"Freezed": "Freezed",
|
|
418
|
+
"Callout": "Callout",
|
|
419
|
+
"The_current_location_does_not_support_pasting": "The current location does not support pasting ",
|
|
420
|
+
"Please_enter...": "Please enter..."
|
|
418
421
|
}
|
|
@@ -281,7 +281,7 @@
|
|
|
281
281
|
"Revision": "Пересмотр",
|
|
282
282
|
"Error": "Ошибка",
|
|
283
283
|
"Start_revise": "Начать пересмотр",
|
|
284
|
-
"Revise": "
|
|
284
|
+
"Revise": "Пересмотр",
|
|
285
285
|
"Failed_to_execute_operation_on_server": "Не удалось выполнить операцию на сервере, текущая операция отменена.",
|
|
286
286
|
"Start_revise_tip": "Создайте временный документ и внесите в него изменения, объедините его обратно после просмотра изменений",
|
|
287
287
|
"Load_doc_content_error": "Ошибка загрузки содержимого документа",
|
|
@@ -414,5 +414,8 @@
|
|
|
414
414
|
"New": "Новый",
|
|
415
415
|
"Table_template": "Шаблон таблицы",
|
|
416
416
|
"Jump_to_original_doc": "Перейти к исходному документу",
|
|
417
|
-
"Freezed": "
|
|
417
|
+
"Freezed": "Заморожено",
|
|
418
|
+
"Callout": "Callout",
|
|
419
|
+
"The_current_location_does_not_support_pasting": "The current location does not support pasting ",
|
|
420
|
+
"Please_enter...": "Please enter..."
|
|
418
421
|
}
|
|
@@ -14,16 +14,24 @@
|
|
|
14
14
|
/>
|
|
15
15
|
<missing-glyph />
|
|
16
16
|
|
|
17
|
+
<<<<<<< HEAD
|
|
17
18
|
<glyph glyph-name="sdoc-selected-text" unicode="" d="M48 480h928c25.6 0 48-22.4 48-48s-22.4-48-48-48h-928C22.4 384 0 406.4 0 432S22.4 480 48 480z m0-352h352c25.6 0 48-22.4 48-48s-22.4-48-48-48h-352C22.4 32 0 54.4 0 80S22.4 128 48 128z m0 704h928c25.6 0 48-22.4 48-48S1001.6 736 976 736h-928C22.4 736 0 758.4 0 784S22.4 832 48 832z m675.2-950.4c-12.8 0-28.8 6.4-38.4 16l-124.8 118.4c-22.4 19.2-22.4 51.2 0 73.6s54.4 19.2 76.8 0l86.4-83.2 211.2 204.8c22.4 19.2 54.4 19.2 76.8 0s22.4-51.2 0-73.6l-249.6-240c-12.8-12.8-25.6-16-38.4-16z" horiz-adv-x="1028" />
|
|
18
19
|
|
|
20
|
+
=======
|
|
21
|
+
<<<<<<< HEAD
|
|
22
|
+
>>>>>>> 4ad4d178 (feat: change icon)
|
|
19
23
|
<glyph glyph-name="sdoc-freezed" unicode="" d="M512 384m-512 0a512 512 0 1 1 1024 0 512 512 0 1 1-1024 0ZM316.8 716.8c118.4 70.4 265.6 70.4 384 3.2s192-195.2 192-332.8c0-137.6-73.6-265.6-195.2-332.8-182.4-105.6-416-41.6-521.6 140.8S134.4 608 316.8 716.8z m348.8-604.8c137.6 80 195.2 249.6 131.2 396.8L259.2 195.2c92.8-124.8 268.8-163.2 406.4-83.2zM352 652.8c-137.6-80-192-249.6-128-393.6l537.6 310.4c-96 128-272 163.2-409.6 83.2z" horiz-adv-x="1024" />
|
|
20
24
|
|
|
21
25
|
<glyph glyph-name="sdoc-jump-to" unicode="" d="M361.6 896c32 0 54.4-16 54.4-48S393.6 800 361.6 800H96v-832h832v262.4c0 32 16 57.6 48 57.6s48-25.6 48-57.6v-300.8c0-32-28.8-57.6-60.8-57.6H60.8c-32 0-60.8 25.6-60.8 57.6V835.2C0 870.4 25.6 896 60.8 896h300.8zM992 896c19.2 0 32-12.8 32-32v-332.8c0-28.8-19.2-51.2-48-51.2s-48 22.4-48 51.2V729.6L531.2 336c-6.4-9.6-19.2-16-35.2-16-12.8 0-25.6 6.4-35.2 16-19.2 19.2-19.2 51.2 0 70.4L857.6 800h-198.4c-28.8 0-51.2 19.2-51.2 48S630.4 896 656 896H992z" horiz-adv-x="1024" />
|
|
22
26
|
|
|
27
|
+
=======
|
|
28
|
+
>>>>>>> 0183ac39 (feat: change icon)
|
|
23
29
|
<glyph glyph-name="sdoc-callout" unicode="" d="M992 352H32c-19.2 0-32 12.8-32 32V832c0 19.2 12.8 32 32 32h960c19.2 0 32-12.8 32-32v-448c0-19.2-12.8-32-32-32zM96 448h832V768H96v-320z m-96-224v-96h1024v96H0z m0-224v-96h576v96H0z" horiz-adv-x="1024" />
|
|
24
30
|
|
|
25
31
|
<glyph glyph-name="sdoc-chart" unicode="" d="M992-128H32c-19.2 0-32 12.8-32 32V864c0 19.2 12.8 32 32 32h960c19.2 0 32-12.8 32-32v-960c0-19.2-12.8-32-32-32zM96-32h832V800H96v-832z m0 464v-96h832v96H96zM560 800h-96v-832h96V800z" horiz-adv-x="1024" />
|
|
26
32
|
|
|
33
|
+
<glyph glyph-name="sdoc-notification" unicode="" d="M931.2 80c-3.2 80-44.8 150.4-105.6 198.4V496c0 124.8-89.6 233.6-208 256v6.4C617.6 816 572.8 864 515.2 864S409.6 816 409.6 758.4v-6.4c-118.4-25.6-208-131.2-208-256v-217.6C137.6 233.6 99.2 160 96 80h835.2zM492.8-96h25.6c67.2 0 124.8 51.2 134.4 118.4H377.6c9.6-67.2 64-118.4 134.4-118.4h-19.2z" horiz-adv-x="1024" />
|
|
34
|
+
|
|
27
35
|
<glyph glyph-name="sdoc-add" unicode="" d="M512-128C227.2-128 0 99.2 0 384S227.2 896 512 896s512-227.2 512-512-227.2-512-512-512z m-51.2 563.2H291.2c-19.2 0-35.2-12.8-35.2-35.2v-35.2c0-19.2 12.8-35.2 35.2-35.2h169.6V160c0-19.2 12.8-35.2 35.2-35.2h35.2c19.2 0 35.2 12.8 35.2 35.2v169.6H736c19.2 0 35.2 12.8 35.2 35.2v35.2c0 19.2-12.8 35.2-35.2 35.2h-169.6V604.8c0 19.2-12.8 35.2-35.2 35.2h-35.2c-19.2 0-35.2-12.8-35.2-35.2v-169.6z" horiz-adv-x="1024" />
|
|
28
36
|
|
|
29
37
|
<glyph glyph-name="sdoc-tag" unicode="" d="M521.353986 860.33363l466.979644-466.979644c22.389435-22.389435 35.183398-51.175851 35.183398-83.160758s-12.793963-60.771324-35.183398-83.160759l-323.047562-319.849071c-22.389435-22.389435-51.175851-35.183398-79.962268-35.183398-31.984907 0-60.771324 12.793963-83.160758 35.183398L35.183398 374.163042c-25.587926 25.587926-38.381889 60.771324-31.984907 95.954721l31.984907 291.062655c6.396981 54.374342 47.977361 95.954721 102.351703 102.351703l291.062654 31.984907c31.984907 3.198491 67.168305-9.595472 92.756231-35.183398zM444.590209 767.577399L159.924536 735.592492l-31.984908-281.467182L578.926819-0.060372l316.65058 313.45209L444.590209 767.577399z m12.793963-127.939628c57.572833-57.572833 57.572833-147.130573 0-204.703406-25.587926-25.587926-63.969814-41.580379-102.351703-41.580379-38.381889 0-73.565286 12.793963-102.351703 41.580379-57.572833 57.572833-57.572833 147.130573 0 204.703406 57.572833 57.572833 150.329063 57.572833 204.703406 0z m-102.351703-70.366796c-6.396981 0-15.992454-3.198491-22.389435-9.595472-12.793963-12.793963-12.793963-31.984907 0-44.77887 12.793963-12.793963 31.984907-12.793963 44.77887 0 12.793963 12.793963 12.793963 31.984907 0 44.77887-6.396981 6.396981-12.793963 9.595472-22.389435 9.595472z" horiz-adv-x="1024" />
|