@seafile/seafile-editor 1.0.4 → 1.0.5-1
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/constants/event-types.js +4 -1
- package/dist/editors/plain-markdown-editor/code-mirror.js +10 -9
- package/dist/editors/plain-markdown-editor/index.js +22 -21
- package/dist/editors/simple-slate-editor /index.js +16 -4
- package/dist/editors/simple-slate-editor /style.css +72 -0
- package/dist/editors/slate-editor/index.js +20 -4
- package/dist/editors/slate-editor/style.css +126 -0
- package/dist/editors/slate-viewer/index.js +12 -3
- package/dist/editors/slate-viewer/style.css +24 -2
- package/dist/extension/commons/element-popover/index.js +3 -2
- package/dist/extension/commons/menu/menu.css +1 -1
- package/dist/extension/constants/index.js +9 -8
- package/dist/extension/core/utils/index.js +12 -1
- package/dist/extension/plugins/image/helper.js +28 -2
- package/dist/extension/plugins/image/menu/image-menu-popover.js +20 -9
- package/dist/extension/plugins/image/menu/index.js +4 -2
- package/dist/extension/plugins/image/menu/style.css +2 -0
- package/dist/extension/plugins/link/helper.js +43 -4
- package/dist/extension/plugins/link/render-elem/index.js +9 -5
- package/dist/extension/toolbar/header-toolbar/index.js +6 -3
- package/dist/extension/toolbar/header-toolbar/style.css +1 -2
- package/dist/extension/toolbar/user-help/shortcut-dialog.js +5 -4
- package/dist/hooks/use-insert-image.js +36 -0
- package/dist/pages/markdown-editor.js +7 -5
- package/dist/pages/markdown-view.js +3 -1
- package/dist/pages/rich-markdown-editor.js +15 -6
- package/dist/pages/simple-editor.js +7 -5
- package/dist/slate-convert/md-to-slate/transform.js +18 -5
- package/dist/slate-convert/slate-to-md/transform.js +3 -0
- package/dist/utils/event-handler.js +9 -4
- package/dist/utils/object-utils.js +5 -4
- package/package.json +3 -1
- package/public/locales/cs/seafile-editor.json +170 -116
- package/public/locales/de/seafile-editor.json +184 -130
- package/public/locales/es/seafile-editor.json +171 -117
- package/public/locales/fr/seafile-editor.json +174 -120
- package/public/locales/it/seafile-editor.json +171 -117
- package/public/locales/ru/seafile-editor.json +171 -117
- package/public/locales/zh-CN/seafile-editor.json +4 -4
- package/dist/assets/css/slate-editor.css +0 -57
|
@@ -6,5 +6,8 @@ export const INTERNAL_EVENTS = {
|
|
|
6
6
|
ON_OPEN_FORMULA_DIALOG: 'on_open_formula_dialog'
|
|
7
7
|
};
|
|
8
8
|
export const EXTERNAL_EVENTS = {
|
|
9
|
-
ON_HELP_INFO_TOGGLE: 'on_help_info_toggle'
|
|
9
|
+
ON_HELP_INFO_TOGGLE: 'on_help_info_toggle',
|
|
10
|
+
ON_LINK_CLICK: 'on_link_click',
|
|
11
|
+
ON_INSERT_IMAGE: 'on_insert_image',
|
|
12
|
+
INSERT_IMAGE: 'insert_image'
|
|
10
13
|
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
|
|
1
2
|
import React from 'react';
|
|
2
3
|
import className from 'classnames';
|
|
3
4
|
import { basicSetup } from 'codemirror';
|
|
@@ -8,7 +9,7 @@ import './code-mirror.css';
|
|
|
8
9
|
class SeafileCodeMirror extends React.Component {
|
|
9
10
|
constructor() {
|
|
10
11
|
super(...arguments);
|
|
11
|
-
this
|
|
12
|
+
_defineProperty(this, "onValueChanged", viewUpdate => {
|
|
12
13
|
const {
|
|
13
14
|
onChange
|
|
14
15
|
} = this.props;
|
|
@@ -17,16 +18,16 @@ class SeafileCodeMirror extends React.Component {
|
|
|
17
18
|
const value = doc.toString();
|
|
18
19
|
onChange(value);
|
|
19
20
|
}
|
|
20
|
-
};
|
|
21
|
-
this
|
|
21
|
+
});
|
|
22
|
+
_defineProperty(this, "focus", () => {
|
|
22
23
|
this.view.focus();
|
|
23
|
-
};
|
|
24
|
-
this
|
|
24
|
+
});
|
|
25
|
+
_defineProperty(this, "scrollIntoView", pos => {
|
|
25
26
|
EditorView.scrollIntoView(pos);
|
|
26
|
-
};
|
|
27
|
-
this
|
|
27
|
+
});
|
|
28
|
+
_defineProperty(this, "setCodeMirrorRef", ref => {
|
|
28
29
|
this.codeMirrorRef = ref;
|
|
29
|
-
};
|
|
30
|
+
});
|
|
30
31
|
}
|
|
31
32
|
componentDidMount() {
|
|
32
33
|
const {
|
|
@@ -39,7 +40,7 @@ class SeafileCodeMirror extends React.Component {
|
|
|
39
40
|
codeLanguages: languages
|
|
40
41
|
}), EditorView.updateListener.of(viewUpdate => {
|
|
41
42
|
this.onValueChanged(viewUpdate);
|
|
42
|
-
})],
|
|
43
|
+
}), EditorView.lineWrapping],
|
|
43
44
|
parent: this.codeMirrorRef
|
|
44
45
|
});
|
|
45
46
|
if (autoFocus) this.focus();
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
|
|
1
2
|
import React from 'react';
|
|
2
3
|
import isHotkey from 'is-hotkey';
|
|
3
4
|
import processor from '../../slate-convert/md-to-html';
|
|
@@ -10,12 +11,12 @@ class PlainMarkdownEditor extends React.Component {
|
|
|
10
11
|
* the data about scroll, these variable has nothing to width react
|
|
11
12
|
* they are not state
|
|
12
13
|
* */
|
|
13
|
-
this
|
|
14
|
+
_defineProperty(this, "scrollData", {
|
|
14
15
|
scrollPercentage: 0,
|
|
15
16
|
leftPanel: null,
|
|
16
17
|
rightPanel: null
|
|
17
|
-
};
|
|
18
|
-
this
|
|
18
|
+
});
|
|
19
|
+
_defineProperty(this, "setContent", markdownContent => {
|
|
19
20
|
this.setState({
|
|
20
21
|
editorValue: markdownContent
|
|
21
22
|
});
|
|
@@ -25,22 +26,22 @@ class PlainMarkdownEditor extends React.Component {
|
|
|
25
26
|
previewValue: html
|
|
26
27
|
});
|
|
27
28
|
});
|
|
28
|
-
};
|
|
29
|
-
this
|
|
29
|
+
});
|
|
30
|
+
_defineProperty(this, "updateCode", newCode => {
|
|
30
31
|
this.setContent(newCode);
|
|
31
|
-
this.props.
|
|
32
|
-
};
|
|
33
|
-
this
|
|
32
|
+
this.props.onContentChanged && this.props.onContentChanged(newCode);
|
|
33
|
+
});
|
|
34
|
+
_defineProperty(this, "onEnterLeftPanel", () => {
|
|
34
35
|
this.setState({
|
|
35
36
|
isMouseInLeftSide: true
|
|
36
37
|
});
|
|
37
|
-
};
|
|
38
|
-
this
|
|
38
|
+
});
|
|
39
|
+
_defineProperty(this, "onLeaveLeftPanel", () => {
|
|
39
40
|
this.setState({
|
|
40
41
|
isMouseInLeftSide: false
|
|
41
42
|
});
|
|
42
|
-
};
|
|
43
|
-
this
|
|
43
|
+
});
|
|
44
|
+
_defineProperty(this, "onLeftScroll", e => {
|
|
44
45
|
const {
|
|
45
46
|
isMouseInLeftSide
|
|
46
47
|
} = this.state;
|
|
@@ -48,18 +49,18 @@ class PlainMarkdownEditor extends React.Component {
|
|
|
48
49
|
let srcElement = this.scrollData.leftPanel;
|
|
49
50
|
this.scrollData.scrollPercentage = srcElement.scrollTop / srcElement.scrollHeight;
|
|
50
51
|
this.scrollData.rightPanel.scrollTop = this.scrollData.scrollPercentage * this.scrollData.rightPanel.scrollHeight;
|
|
51
|
-
};
|
|
52
|
-
this
|
|
52
|
+
});
|
|
53
|
+
_defineProperty(this, "onEnterRightPanel", () => {
|
|
53
54
|
this.setState({
|
|
54
55
|
isMouseInRightSide: true
|
|
55
56
|
});
|
|
56
|
-
};
|
|
57
|
-
this
|
|
57
|
+
});
|
|
58
|
+
_defineProperty(this, "onLeaveRightPanel", () => {
|
|
58
59
|
this.setState({
|
|
59
60
|
isMouseInRightSide: false
|
|
60
61
|
});
|
|
61
|
-
};
|
|
62
|
-
this
|
|
62
|
+
});
|
|
63
|
+
_defineProperty(this, "onRightScroll", e => {
|
|
63
64
|
const {
|
|
64
65
|
isMouseInRightSide
|
|
65
66
|
} = this.state;
|
|
@@ -67,8 +68,8 @@ class PlainMarkdownEditor extends React.Component {
|
|
|
67
68
|
let srcElement = this.scrollData.rightPanel;
|
|
68
69
|
this.scrollData.scrollPercentage = srcElement.scrollTop / srcElement.scrollHeight;
|
|
69
70
|
this.scrollData.leftPanel.scrollTop = this.scrollData.scrollPercentage * this.scrollData.leftPanel.scrollHeight;
|
|
70
|
-
};
|
|
71
|
-
this
|
|
71
|
+
});
|
|
72
|
+
_defineProperty(this, "onHotKey", event => {
|
|
72
73
|
const {
|
|
73
74
|
onSave
|
|
74
75
|
} = this.props;
|
|
@@ -77,7 +78,7 @@ class PlainMarkdownEditor extends React.Component {
|
|
|
77
78
|
onSave && onSave(this.state.editorValue);
|
|
78
79
|
return true;
|
|
79
80
|
}
|
|
80
|
-
};
|
|
81
|
+
});
|
|
81
82
|
this.state = {
|
|
82
83
|
editorValue: props.value,
|
|
83
84
|
previewValue: '',
|
|
@@ -6,12 +6,13 @@ import EventBus from '../../utils/event-bus';
|
|
|
6
6
|
import EventProxy from '../../utils/event-handler';
|
|
7
7
|
import withPropsEditor from './with-props-editor';
|
|
8
8
|
import { focusEditor } from '../../extension/core';
|
|
9
|
-
import '
|
|
9
|
+
import './style.css';
|
|
10
10
|
export default function SimpleSlateEditor(_ref) {
|
|
11
11
|
let {
|
|
12
12
|
value,
|
|
13
13
|
editorApi,
|
|
14
14
|
onSave,
|
|
15
|
+
onContentChanged,
|
|
15
16
|
isSupportFormula
|
|
16
17
|
} = _ref;
|
|
17
18
|
const [slateValue, setSlateValue] = useState(value);
|
|
@@ -24,10 +25,14 @@ export default function SimpleSlateEditor(_ref) {
|
|
|
24
25
|
}, [editor]);
|
|
25
26
|
const onChange = useCallback(value => {
|
|
26
27
|
setSlateValue(value);
|
|
27
|
-
|
|
28
|
+
const operations = editor.operations;
|
|
29
|
+
const modifyOps = operations.filter(o => o.type !== 'set_selection');
|
|
30
|
+
if (modifyOps.length > 0) {
|
|
31
|
+
onContentChanged && onContentChanged(value);
|
|
32
|
+
}
|
|
28
33
|
const eventBus = EventBus.getInstance();
|
|
29
34
|
eventBus.dispatch('change');
|
|
30
|
-
}, [
|
|
35
|
+
}, [editor.operations, onContentChanged]);
|
|
31
36
|
|
|
32
37
|
// useMount: focus editor
|
|
33
38
|
useEffect(() => {
|
|
@@ -50,8 +55,15 @@ export default function SimpleSlateEditor(_ref) {
|
|
|
50
55
|
};
|
|
51
56
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
52
57
|
}, []);
|
|
58
|
+
|
|
59
|
+
// willUnmount
|
|
60
|
+
useEffect(() => {
|
|
61
|
+
return () => {
|
|
62
|
+
editor.selection = null;
|
|
63
|
+
};
|
|
64
|
+
});
|
|
53
65
|
return /*#__PURE__*/React.createElement("div", {
|
|
54
|
-
className: "sf-slate-editor-container"
|
|
66
|
+
className: "sf-simple-slate-editor-container"
|
|
55
67
|
}, /*#__PURE__*/React.createElement(Toolbar, {
|
|
56
68
|
editor: editor,
|
|
57
69
|
isSupportFormula: isSupportFormula
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
.sf-simple-slate-editor-container {
|
|
2
|
+
flex: 1;
|
|
3
|
+
display: flex;
|
|
4
|
+
flex-direction: column;
|
|
5
|
+
min-height: 0;
|
|
6
|
+
min-width: 0;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.sf-simple-slate-editor-container .sf-slate-editor-toolbar {
|
|
10
|
+
display: flex;
|
|
11
|
+
justify-content: flex-start;
|
|
12
|
+
height: 44px;
|
|
13
|
+
align-items: center;
|
|
14
|
+
padding: 0 10px;
|
|
15
|
+
background-color: #fff;
|
|
16
|
+
user-select: none;
|
|
17
|
+
border-bottom: 1px solid #e5e6e8;
|
|
18
|
+
position: relative;
|
|
19
|
+
z-index: 102;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.sf-simple-slate-editor-container .sf-slate-editor-content {
|
|
23
|
+
width: 100%;
|
|
24
|
+
height: calc(100% - 44px);
|
|
25
|
+
display: flex;
|
|
26
|
+
background: #f5f5f5;
|
|
27
|
+
position: relative;
|
|
28
|
+
min-height: 0;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.sf-simple-slate-editor-container .sf-slate-scroll-container,
|
|
32
|
+
.sf-simple-slate-editor-container .sf-slate-article-container {
|
|
33
|
+
height: 100%;
|
|
34
|
+
width: 100%;
|
|
35
|
+
overflow: auto;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/* .sf-simple-slate-editor-container .sf-slate-article-container {
|
|
39
|
+
flex: 1;
|
|
40
|
+
position: relative;
|
|
41
|
+
max-width: 950px;
|
|
42
|
+
min-width: 400px;
|
|
43
|
+
margin: 0 auto;
|
|
44
|
+
padding-top: 20px;
|
|
45
|
+
padding-bottom: 20px;
|
|
46
|
+
} */
|
|
47
|
+
|
|
48
|
+
.sf-simple-slate-editor-container .sf-slate-editor-content .article {
|
|
49
|
+
margin: 0;
|
|
50
|
+
padding: 10px;
|
|
51
|
+
height: 100%;
|
|
52
|
+
border: none;
|
|
53
|
+
background-color: #fff;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.sf-simple-slate-editor-container .sf-slate-editor-content .article div:first-child {
|
|
57
|
+
outline: none;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.sf-simple-slate-editor-container ::-webkit-scrollbar{
|
|
61
|
+
width: 8px;
|
|
62
|
+
height: 8px;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.sf-simple-slate-editor-container ::-webkit-scrollbar-button {
|
|
66
|
+
display: none;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.sf-simple-slate-editor-container ::-webkit-scrollbar-thumb {
|
|
70
|
+
background-color: rgb(206, 206, 212);
|
|
71
|
+
border-radius: 10px;
|
|
72
|
+
}
|
|
@@ -8,13 +8,16 @@ import withPropsEditor from './with-props-editor';
|
|
|
8
8
|
import EditorHelp from './editor-help';
|
|
9
9
|
import { focusEditor } from '../../extension/core';
|
|
10
10
|
import { ScrollContext } from '../../hooks/use-scroll-context';
|
|
11
|
-
import '
|
|
11
|
+
import './style.css';
|
|
12
|
+
import useSeafileUtils from '../../hooks/use-insert-image';
|
|
12
13
|
export default function SlateEditor(_ref) {
|
|
13
14
|
let {
|
|
14
15
|
value,
|
|
15
16
|
editorApi,
|
|
16
17
|
onSave,
|
|
18
|
+
onContentChanged,
|
|
17
19
|
isSupportFormula,
|
|
20
|
+
isSupportInsertSeafileImage,
|
|
18
21
|
children
|
|
19
22
|
} = _ref;
|
|
20
23
|
const [slateValue, setSlateValue] = useState(value);
|
|
@@ -26,12 +29,17 @@ export default function SlateEditor(_ref) {
|
|
|
26
29
|
const eventProxy = useMemo(() => {
|
|
27
30
|
return new EventProxy(editor);
|
|
28
31
|
}, [editor]);
|
|
32
|
+
useSeafileUtils(editor);
|
|
29
33
|
const onChange = useCallback(value => {
|
|
30
34
|
setSlateValue(value);
|
|
31
|
-
|
|
35
|
+
const operations = editor.operations;
|
|
36
|
+
const modifyOps = operations.filter(o => o.type !== 'set_selection');
|
|
37
|
+
if (modifyOps.length > 0) {
|
|
38
|
+
onContentChanged && onContentChanged(value);
|
|
39
|
+
}
|
|
32
40
|
const eventBus = EventBus.getInstance();
|
|
33
41
|
eventBus.dispatch('change');
|
|
34
|
-
}, [
|
|
42
|
+
}, [editor.operations, onContentChanged]);
|
|
35
43
|
|
|
36
44
|
// useMount: focus editor
|
|
37
45
|
useEffect(() => {
|
|
@@ -54,12 +62,20 @@ export default function SlateEditor(_ref) {
|
|
|
54
62
|
};
|
|
55
63
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
56
64
|
}, []);
|
|
65
|
+
|
|
66
|
+
// willUnmount
|
|
67
|
+
useEffect(() => {
|
|
68
|
+
return () => {
|
|
69
|
+
editor.selection = null;
|
|
70
|
+
};
|
|
71
|
+
});
|
|
57
72
|
return /*#__PURE__*/React.createElement("div", {
|
|
58
73
|
className: "sf-slate-editor-container"
|
|
59
74
|
}, /*#__PURE__*/React.createElement(Toolbar, {
|
|
60
75
|
editor: editor,
|
|
61
76
|
isRichEditor: true,
|
|
62
|
-
isSupportFormula: isSupportFormula
|
|
77
|
+
isSupportFormula: isSupportFormula,
|
|
78
|
+
isSupportInsertSeafileImage: isSupportInsertSeafileImage
|
|
63
79
|
}), /*#__PURE__*/React.createElement("div", {
|
|
64
80
|
className: "sf-slate-editor-content"
|
|
65
81
|
}, /*#__PURE__*/React.createElement(ScrollContext.Provider, {
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
.sf-slate-editor-container {
|
|
2
|
+
flex: 1;
|
|
3
|
+
display: flex;
|
|
4
|
+
flex-direction: column;
|
|
5
|
+
min-height: 0;
|
|
6
|
+
min-width: 0;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.sf-slate-editor-container .sf-slate-editor-toolbar {
|
|
10
|
+
display: flex;
|
|
11
|
+
justify-content: center;
|
|
12
|
+
height: 44px;
|
|
13
|
+
align-items: center;
|
|
14
|
+
padding: 0 10px;
|
|
15
|
+
background-color: #fff;
|
|
16
|
+
user-select: none;
|
|
17
|
+
border-bottom: 1px solid #e5e6e8;
|
|
18
|
+
position: relative;
|
|
19
|
+
z-index: 102;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.sf-slate-editor-container .sf-slate-editor-content {
|
|
23
|
+
width: 100%;
|
|
24
|
+
height: calc(100% - 44px);
|
|
25
|
+
display: flex;
|
|
26
|
+
background: #f5f5f5;
|
|
27
|
+
position: relative;
|
|
28
|
+
min-height: 0;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.sf-slate-editor-container .sf-slate-scroll-container {
|
|
32
|
+
height: 100%;
|
|
33
|
+
width: 100%;
|
|
34
|
+
overflow: auto;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.sf-slate-editor-container .sf-slate-article-container {
|
|
38
|
+
flex: 1;
|
|
39
|
+
position: relative;
|
|
40
|
+
max-width: 950px;
|
|
41
|
+
min-width: 400px;
|
|
42
|
+
margin: 0 auto;
|
|
43
|
+
padding-top: 20px;
|
|
44
|
+
padding-bottom: 20px;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.sf-slate-editor-container .sf-slate-editor-content .article {
|
|
48
|
+
max-width: 950px;
|
|
49
|
+
min-height: 1200px;
|
|
50
|
+
padding: 40px 60px;
|
|
51
|
+
background-color: #fff;
|
|
52
|
+
border: 1px solid #e5e6e8;
|
|
53
|
+
box-shadow: 0 0 15px rgba(0, 0, 0, 0.06);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.sf-slate-editor-container .sf-slate-editor-content .article div:first-child {
|
|
57
|
+
outline: none;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.sf-slate-editor-container ::-webkit-scrollbar{
|
|
61
|
+
width: 8px;
|
|
62
|
+
height: 8px;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.sf-slate-editor-container ::-webkit-scrollbar-button {
|
|
66
|
+
display: none;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.sf-slate-editor-container ::-webkit-scrollbar-thumb {
|
|
70
|
+
background-color: rgb(206, 206, 212);
|
|
71
|
+
border-radius: 10px;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
@media (max-width: 991.8px) {
|
|
75
|
+
.sf-slate-editor-toolbar {
|
|
76
|
+
overflow-x: auto;
|
|
77
|
+
padding-right: 40px !important;
|
|
78
|
+
justify-content: flex-start !important;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.sf-slate-editor-toolbar::-webkit-scrollbar{
|
|
82
|
+
display: none;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.sf-slate-editor-toolbar .sf-slate-article-info-control,
|
|
86
|
+
.sf-slate-editor-toolbar .sf-slate-help-info-control {
|
|
87
|
+
right: 0;
|
|
88
|
+
padding: 0 20px;
|
|
89
|
+
height: 43px;
|
|
90
|
+
align-items: center;
|
|
91
|
+
background-color: #fcfcfc;
|
|
92
|
+
position: fixed;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.sf-slate-article-container {
|
|
96
|
+
width: 100%;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.sf-slate-article-container .article {
|
|
100
|
+
margin: 20px !important;
|
|
101
|
+
padding: 20px 30px;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.sf-markdown-help-wrapper {
|
|
105
|
+
width: 250px !important;
|
|
106
|
+
flex: 0 0 250px;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
@media (max-width: 768px) {
|
|
111
|
+
.sf-slate-editor-container .sf-slate-article-container {
|
|
112
|
+
flex: 1;
|
|
113
|
+
position: relative;
|
|
114
|
+
max-width: 950px;
|
|
115
|
+
min-width: auto;
|
|
116
|
+
margin: 0 auto;
|
|
117
|
+
padding-top: 0;
|
|
118
|
+
padding-bottom: 0;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.sf-slate-article-container .article {
|
|
122
|
+
margin: 0 !important;
|
|
123
|
+
padding: 10px 15px !important;
|
|
124
|
+
border: 0 !important;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useRef } from 'react';
|
|
1
|
+
import React, { useEffect, useRef } from 'react';
|
|
2
2
|
import { baseEditor, renderElement, renderLeaf } from '../../extension';
|
|
3
3
|
import { Editable, Slate } from 'slate-react';
|
|
4
4
|
import Outline from '../../containers/outline';
|
|
@@ -7,15 +7,24 @@ import './style.css';
|
|
|
7
7
|
export default function SlateViewer(_ref) {
|
|
8
8
|
let {
|
|
9
9
|
value,
|
|
10
|
-
isShowOutline
|
|
10
|
+
isShowOutline,
|
|
11
|
+
scrollRef: externalScrollRef
|
|
11
12
|
} = _ref;
|
|
12
13
|
const scrollRef = useRef(null);
|
|
14
|
+
const containerScrollRef = externalScrollRef ? externalScrollRef : scrollRef;
|
|
15
|
+
|
|
16
|
+
// willUnmount
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
return () => {
|
|
19
|
+
baseEditor.selection = null;
|
|
20
|
+
};
|
|
21
|
+
});
|
|
13
22
|
return /*#__PURE__*/React.createElement(Slate, {
|
|
14
23
|
editor: baseEditor,
|
|
15
24
|
initialValue: value
|
|
16
25
|
}, /*#__PURE__*/React.createElement(ScrollContext.Provider, {
|
|
17
26
|
value: {
|
|
18
|
-
scrollRef
|
|
27
|
+
scrollRef: containerScrollRef
|
|
19
28
|
}
|
|
20
29
|
}, /*#__PURE__*/React.createElement("div", {
|
|
21
30
|
ref: scrollRef,
|
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
min-width: 0;
|
|
6
6
|
overflow: auto;
|
|
7
7
|
background: #f4f4f4;
|
|
8
|
-
border: 1px solid #ededed;
|
|
9
8
|
padding: 30px 0 15px;
|
|
10
9
|
}
|
|
11
10
|
|
|
@@ -20,7 +19,7 @@
|
|
|
20
19
|
|
|
21
20
|
.sf-slate-viewer-scroll-container .sf-slate-viewer-outline {
|
|
22
21
|
height: 80%;
|
|
23
|
-
overflow:
|
|
22
|
+
overflow-y: hidden;
|
|
24
23
|
padding-right: 1rem;
|
|
25
24
|
position: fixed;
|
|
26
25
|
right: 0;
|
|
@@ -28,6 +27,10 @@
|
|
|
28
27
|
width: 300px;
|
|
29
28
|
}
|
|
30
29
|
|
|
30
|
+
.sf-slate-viewer-scroll-container .sf-slate-viewer-outline:hover {
|
|
31
|
+
overflow-y: auto;
|
|
32
|
+
}
|
|
33
|
+
|
|
31
34
|
.sf-slate-viewer-scroll-container .article {
|
|
32
35
|
margin: 0 auto;
|
|
33
36
|
padding: 40px 60px;
|
|
@@ -37,4 +40,23 @@
|
|
|
37
40
|
background: #fff;
|
|
38
41
|
}
|
|
39
42
|
|
|
43
|
+
@media (max-width: 991.98px) {
|
|
44
|
+
.sf-slate-viewer-article-container {
|
|
45
|
+
padding: 0 10px;
|
|
46
|
+
width: 100%;
|
|
47
|
+
margin: 0 !important;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.sf-slate-viewer-outline {
|
|
51
|
+
display: none !important;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
@media (max-width: 768px) {
|
|
56
|
+
.sf-slate-viewer-article-container .article {
|
|
57
|
+
margin: 0 !important;
|
|
58
|
+
padding: 20px !important;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
40
62
|
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
+
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
|
|
1
2
|
import React from 'react';
|
|
2
3
|
import ReactDOM from 'react-dom';
|
|
3
4
|
class ElementPopover extends React.Component {
|
|
4
5
|
constructor(props) {
|
|
5
6
|
super(props);
|
|
6
|
-
this
|
|
7
|
+
_defineProperty(this, "state", {
|
|
7
8
|
isMounted: false
|
|
8
|
-
};
|
|
9
|
+
});
|
|
9
10
|
this.el = document.createElement('div');
|
|
10
11
|
if (props.className) {
|
|
11
12
|
this.el.className = props.className;
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import { HEADER1, HEADER2, HEADER3, HEADER4, HEADER5, HEADER6, PARAGRAPH } from './element-types';
|
|
2
|
-
|
|
2
|
+
import * as _ELementTypes from './element-types';
|
|
3
|
+
export { _ELementTypes as ELementTypes };
|
|
3
4
|
export * from './menus-config';
|
|
4
5
|
export const HEADERS = [HEADER1, HEADER2, HEADER3, HEADER4, HEADER5, HEADER6];
|
|
5
6
|
export const HEADER_TITLE_MAP = {
|
|
6
|
-
[HEADER1]: '
|
|
7
|
-
[HEADER2]: '
|
|
8
|
-
[HEADER3]: '
|
|
9
|
-
[HEADER4]: '
|
|
10
|
-
[HEADER5]: '
|
|
11
|
-
[HEADER6]: '
|
|
12
|
-
[PARAGRAPH]: '
|
|
7
|
+
[HEADER1]: 'Header_one',
|
|
8
|
+
[HEADER2]: 'Header_two',
|
|
9
|
+
[HEADER3]: 'Header_three',
|
|
10
|
+
[HEADER4]: 'Header_four',
|
|
11
|
+
[HEADER5]: 'Header_five',
|
|
12
|
+
[HEADER6]: 'Header_six',
|
|
13
|
+
[PARAGRAPH]: 'Paragraph'
|
|
13
14
|
};
|
|
14
15
|
export const LIST_TYPE_ARRAY = ['unordered_list', 'ordered_list'];
|
|
15
16
|
export const INSERT_POSITION = {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import slugid from 'slugid';
|
|
2
2
|
import { useTranslation } from 'react-i18next';
|
|
3
|
-
import { PARAGRAPH } from '../../constants/element-types';
|
|
3
|
+
import { HEADER1, PARAGRAPH } from '../../constants/element-types';
|
|
4
4
|
export const match = (node, path, predicate) => {
|
|
5
5
|
if (!predicate) return true;
|
|
6
6
|
if (typeof predicate === 'object') {
|
|
@@ -35,6 +35,17 @@ export const generateEmptyElement = type => {
|
|
|
35
35
|
children: [generateDefaultText()]
|
|
36
36
|
};
|
|
37
37
|
};
|
|
38
|
+
export const generateHeaderElement = text => {
|
|
39
|
+
const headerText = {
|
|
40
|
+
id: slugid.nice(),
|
|
41
|
+
text: text
|
|
42
|
+
};
|
|
43
|
+
return {
|
|
44
|
+
id: slugid.nice(),
|
|
45
|
+
type: HEADER1,
|
|
46
|
+
children: [headerText]
|
|
47
|
+
};
|
|
48
|
+
};
|
|
38
49
|
|
|
39
50
|
/**
|
|
40
51
|
* @param {String} type
|
|
@@ -11,12 +11,15 @@ export const isMenuDisabled = (editor, readonly) => {
|
|
|
11
11
|
if (isInCodeBlock(editor)) return true;
|
|
12
12
|
return false;
|
|
13
13
|
};
|
|
14
|
-
export const insertImage = (editor, url) => {
|
|
14
|
+
export const insertImage = (editor, url, title) => {
|
|
15
15
|
const imageNode = {
|
|
16
16
|
type: IMAGE,
|
|
17
17
|
id: slugid.nice(),
|
|
18
18
|
data: {
|
|
19
|
-
src: url
|
|
19
|
+
src: url,
|
|
20
|
+
...(title && {
|
|
21
|
+
title
|
|
22
|
+
})
|
|
20
23
|
},
|
|
21
24
|
children: [generateDefaultText()]
|
|
22
25
|
};
|
|
@@ -25,6 +28,29 @@ export const insertImage = (editor, url) => {
|
|
|
25
28
|
select: true
|
|
26
29
|
});
|
|
27
30
|
};
|
|
31
|
+
export const insertSeafileImage = _ref => {
|
|
32
|
+
let {
|
|
33
|
+
editor,
|
|
34
|
+
url,
|
|
35
|
+
title,
|
|
36
|
+
selection
|
|
37
|
+
} = _ref;
|
|
38
|
+
const imageNode = {
|
|
39
|
+
type: IMAGE,
|
|
40
|
+
id: slugid.nice(),
|
|
41
|
+
data: {
|
|
42
|
+
src: url,
|
|
43
|
+
...(title && {
|
|
44
|
+
title
|
|
45
|
+
})
|
|
46
|
+
},
|
|
47
|
+
children: [generateDefaultText()]
|
|
48
|
+
};
|
|
49
|
+
Transforms.insertNodes(editor, imageNode, {
|
|
50
|
+
at: selection,
|
|
51
|
+
select: true
|
|
52
|
+
});
|
|
53
|
+
};
|
|
28
54
|
export const updateImage = (editor, data) => {
|
|
29
55
|
Transforms.setNodes(editor, {
|
|
30
56
|
data
|