@seafile/seafile-editor 1.0.80 → 1.0.82-alpha
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/editors/simple-slate-editor /index.js +16 -6
- package/dist/extension/commons/expand-editor-menu.js +29 -0
- package/dist/extension/commons/index.js +15 -1
- package/dist/extension/commons/more-menu/index.css +4 -0
- package/dist/extension/commons/more-menu/index.js +46 -0
- package/dist/extension/constants/menus-config.js +13 -1
- package/dist/extension/index.js +6 -0
- package/dist/extension/plugins/html/plugin.js +46 -29
- package/dist/extension/plugins/image/render-element/index.js +1 -1
- package/dist/extension/toolbar/index.js +8 -1
- package/dist/extension/toolbar/inline-toolbar/index.css +40 -0
- package/dist/extension/toolbar/inline-toolbar/index.js +83 -0
- package/dist/pages/inline-longtext-editor/index.css +0 -0
- package/dist/pages/inline-longtext-editor/index.js +122 -0
- package/dist/pages/simple-editor.js +6 -2
- package/package.json +1 -1
- package/public/locales/cs/seafile-editor.json +2 -1
- package/public/locales/de/seafile-editor.json +2 -1
- package/public/locales/en/seafile-editor.json +2 -1
- package/public/locales/es/seafile-editor.json +2 -1
- package/public/locales/fr/seafile-editor.json +2 -1
- package/public/locales/it/seafile-editor.json +2 -1
- package/public/locales/ru/seafile-editor.json +2 -1
- package/public/locales/zh_CN/seafile-editor.json +2 -1
- package/public/media/seafile-editor-font/iconfont.eot +0 -0
- package/public/media/seafile-editor-font/iconfont.svg +2 -0
- package/public/media/seafile-editor-font/iconfont.ttf +0 -0
- package/public/media/seafile-editor-font/iconfont.woff +0 -0
- package/public/media/seafile-editor-font/iconfont.woff2 +0 -0
- package/public/media/seafile-editor-font.css +10 -6
- package/readme.md +203 -9
|
@@ -5,7 +5,7 @@ var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWild
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", {
|
|
6
6
|
value: true
|
|
7
7
|
});
|
|
8
|
-
exports.default =
|
|
8
|
+
exports.default = void 0;
|
|
9
9
|
var _react = _interopRequireWildcard(require("react"));
|
|
10
10
|
var _slateReact = require("slate-react");
|
|
11
11
|
var _slate = require("slate");
|
|
@@ -17,14 +17,16 @@ var _core = require("../../extension/core");
|
|
|
17
17
|
var _common = require("../../utils/common");
|
|
18
18
|
require("./style.css");
|
|
19
19
|
const isMacOS = (0, _common.isMac)();
|
|
20
|
-
|
|
20
|
+
const SimpleSlateEditor = _ref => {
|
|
21
21
|
let {
|
|
22
|
+
isInline,
|
|
22
23
|
value,
|
|
23
24
|
editorApi,
|
|
24
25
|
onSave,
|
|
25
26
|
columns,
|
|
26
27
|
onContentChanged,
|
|
27
|
-
isSupportFormula
|
|
28
|
+
isSupportFormula,
|
|
29
|
+
onExpandEditorToggle
|
|
28
30
|
} = _ref;
|
|
29
31
|
const [slateValue, setSlateValue] = (0, _react.useState)(value);
|
|
30
32
|
const editor = (0, _react.useMemo)(() => (0, _withPropsEditor.default)(_extension.baseEditor, {
|
|
@@ -36,6 +38,9 @@ function SimpleSlateEditor(_ref) {
|
|
|
36
38
|
return new _eventHandler.default(editor);
|
|
37
39
|
}, [editor]);
|
|
38
40
|
const decorate = (0, _extension.useHighlight)(editor);
|
|
41
|
+
const ToolbarComponent = (0, _react.useMemo)(() => {
|
|
42
|
+
return isInline ? _extension.InlineToolbar : _extension.Toolbar;
|
|
43
|
+
}, [isInline]);
|
|
39
44
|
const onChange = (0, _react.useCallback)(value => {
|
|
40
45
|
setSlateValue(value);
|
|
41
46
|
if (editor.forceNormalize) return;
|
|
@@ -113,10 +118,11 @@ function SimpleSlateEditor(_ref) {
|
|
|
113
118
|
}, [editor, focusFirstNode]);
|
|
114
119
|
return /*#__PURE__*/_react.default.createElement("div", {
|
|
115
120
|
className: "sf-simple-slate-editor-container"
|
|
116
|
-
}, /*#__PURE__*/_react.default.createElement(
|
|
121
|
+
}, /*#__PURE__*/_react.default.createElement(ToolbarComponent, {
|
|
117
122
|
editor: editor,
|
|
118
123
|
isSupportFormula: isSupportFormula,
|
|
119
|
-
isSupportColumn: !!columns
|
|
124
|
+
isSupportColumn: !!columns,
|
|
125
|
+
onExpandEditorToggle: onExpandEditorToggle
|
|
120
126
|
}), /*#__PURE__*/_react.default.createElement("div", {
|
|
121
127
|
className: "sf-slate-editor-content",
|
|
122
128
|
onClick: onEditorClick
|
|
@@ -137,4 +143,8 @@ function SimpleSlateEditor(_ref) {
|
|
|
137
143
|
onKeyDown: eventProxy.onKeyDown,
|
|
138
144
|
onCopy: eventProxy.onCopy
|
|
139
145
|
})))))));
|
|
140
|
-
}
|
|
146
|
+
};
|
|
147
|
+
SimpleSlateEditor.defaultProps = {
|
|
148
|
+
isInline: false
|
|
149
|
+
};
|
|
150
|
+
var _default = exports.default = SimpleSlateEditor;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.default = void 0;
|
|
8
|
+
var _react = _interopRequireDefault(require("react"));
|
|
9
|
+
var _constants = require("../constants");
|
|
10
|
+
var _menu = require("./menu");
|
|
11
|
+
require("./index.css");
|
|
12
|
+
const ExpandEditorMenu = _ref => {
|
|
13
|
+
let {
|
|
14
|
+
readonly,
|
|
15
|
+
isRichEditor,
|
|
16
|
+
onExpandEditorToggle,
|
|
17
|
+
className
|
|
18
|
+
} = _ref;
|
|
19
|
+
const config = _constants.MENUS_CONFIG_MAP[_constants.EXPAND_EDITOR];
|
|
20
|
+
return /*#__PURE__*/_react.default.createElement(_menu.MenuItem, Object.assign({
|
|
21
|
+
disabled: readonly,
|
|
22
|
+
isActive: false,
|
|
23
|
+
isRichEditor: isRichEditor,
|
|
24
|
+
type: _constants.EXPAND_EDITOR,
|
|
25
|
+
onMouseDown: onExpandEditorToggle,
|
|
26
|
+
className: className
|
|
27
|
+
}, config));
|
|
28
|
+
};
|
|
29
|
+
var _default = exports.default = ExpandEditorMenu;
|
|
@@ -10,6 +10,12 @@ Object.defineProperty(exports, "ElementPopover", {
|
|
|
10
10
|
return _elementPopover.default;
|
|
11
11
|
}
|
|
12
12
|
});
|
|
13
|
+
Object.defineProperty(exports, "ExpandEditorMenu", {
|
|
14
|
+
enumerable: true,
|
|
15
|
+
get: function () {
|
|
16
|
+
return _expandEditorMenu.default;
|
|
17
|
+
}
|
|
18
|
+
});
|
|
13
19
|
Object.defineProperty(exports, "MenuGroup", {
|
|
14
20
|
enumerable: true,
|
|
15
21
|
get: function () {
|
|
@@ -22,6 +28,12 @@ Object.defineProperty(exports, "MenuItem", {
|
|
|
22
28
|
return _menu.MenuItem;
|
|
23
29
|
}
|
|
24
30
|
});
|
|
31
|
+
Object.defineProperty(exports, "MoreMenu", {
|
|
32
|
+
enumerable: true,
|
|
33
|
+
get: function () {
|
|
34
|
+
return _moreMenu.default;
|
|
35
|
+
}
|
|
36
|
+
});
|
|
25
37
|
Object.defineProperty(exports, "Select", {
|
|
26
38
|
enumerable: true,
|
|
27
39
|
get: function () {
|
|
@@ -30,4 +42,6 @@ Object.defineProperty(exports, "Select", {
|
|
|
30
42
|
});
|
|
31
43
|
var _elementPopover = _interopRequireDefault(require("./element-popover"));
|
|
32
44
|
var _menu = require("./menu");
|
|
33
|
-
var _select = _interopRequireDefault(require("./select"));
|
|
45
|
+
var _select = _interopRequireDefault(require("./select"));
|
|
46
|
+
var _moreMenu = _interopRequireDefault(require("./more-menu"));
|
|
47
|
+
var _expandEditorMenu = _interopRequireDefault(require("./expand-editor-menu"));
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.default = void 0;
|
|
8
|
+
var _react = _interopRequireDefault(require("react"));
|
|
9
|
+
var _classnames = _interopRequireDefault(require("classnames"));
|
|
10
|
+
var _reactstrap = require("reactstrap");
|
|
11
|
+
var _constants = require("../../constants");
|
|
12
|
+
require("./index.css");
|
|
13
|
+
const MoreMenu = _ref => {
|
|
14
|
+
let {
|
|
15
|
+
className,
|
|
16
|
+
disabled,
|
|
17
|
+
isRichEditor,
|
|
18
|
+
children
|
|
19
|
+
} = _ref;
|
|
20
|
+
const validClassName = (0, _classnames.default)(className, {
|
|
21
|
+
'sf-rich-editor': isRichEditor,
|
|
22
|
+
'sf-icon-btn': true,
|
|
23
|
+
'sf-icon-btn-disabled': disabled,
|
|
24
|
+
'sf-icon-btn-hover': !disabled
|
|
25
|
+
});
|
|
26
|
+
const config = _constants.MENUS_CONFIG_MAP[_constants.MORE_OPERATION];
|
|
27
|
+
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("button", {
|
|
28
|
+
className: validClassName,
|
|
29
|
+
type: "button",
|
|
30
|
+
id: config.id
|
|
31
|
+
}, /*#__PURE__*/_react.default.createElement("i", {
|
|
32
|
+
className: config.iconClass
|
|
33
|
+
})), /*#__PURE__*/_react.default.createElement(_reactstrap.UncontrolledPopover, {
|
|
34
|
+
target: config.id,
|
|
35
|
+
className: "sf-editor-menu-popover",
|
|
36
|
+
trigger: "legacy",
|
|
37
|
+
placement: "bottom-end",
|
|
38
|
+
hideArrow: true,
|
|
39
|
+
fade: false
|
|
40
|
+
}, children));
|
|
41
|
+
};
|
|
42
|
+
MoreMenu.defaultProps = {
|
|
43
|
+
isRichEditor: true,
|
|
44
|
+
className: 'sf-menu-group-item'
|
|
45
|
+
};
|
|
46
|
+
var _default = exports.default = MoreMenu;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.TEXT_STYLE_MAP = exports.TABLE_SUBMENU_MAP = exports.MENUS_CONFIG_MAP = exports.CLEAR_FORMAT = void 0;
|
|
6
|
+
exports.TEXT_STYLE_MAP = exports.TABLE_SUBMENU_MAP = exports.MORE_OPERATION = exports.MENUS_CONFIG_MAP = exports.EXPAND_EDITOR = exports.CLEAR_FORMAT = void 0;
|
|
7
7
|
var _elementTypes = require("./element-types");
|
|
8
8
|
const BOLD = 'bold';
|
|
9
9
|
const ITALIC = 'italic';
|
|
@@ -12,6 +12,8 @@ const CODE = 'code';
|
|
|
12
12
|
const DELETE = 'delete';
|
|
13
13
|
const ADD = 'add';
|
|
14
14
|
const CLEAR_FORMAT = exports.CLEAR_FORMAT = 'clear_format';
|
|
15
|
+
const MORE_OPERATION = exports.MORE_OPERATION = 'more_operation';
|
|
16
|
+
const EXPAND_EDITOR = exports.EXPAND_EDITOR = 'expand_editor';
|
|
15
17
|
const TEXT_STYLE_MAP = exports.TEXT_STYLE_MAP = {
|
|
16
18
|
BOLD: BOLD,
|
|
17
19
|
ITALIC: ITALIC,
|
|
@@ -142,5 +144,15 @@ const MENUS_CONFIG_MAP = exports.MENUS_CONFIG_MAP = {
|
|
|
142
144
|
id: "seafile_".concat(_elementTypes.COLUMN),
|
|
143
145
|
iconClass: 'iconfont icon-choose-column',
|
|
144
146
|
text: 'Insert_column'
|
|
147
|
+
},
|
|
148
|
+
[MORE_OPERATION]: {
|
|
149
|
+
id: "seafile_".concat(MORE_OPERATION),
|
|
150
|
+
iconClass: 'iconfont icon-more',
|
|
151
|
+
text: ''
|
|
152
|
+
},
|
|
153
|
+
[EXPAND_EDITOR]: {
|
|
154
|
+
id: "seafile_".concat(EXPAND_EDITOR),
|
|
155
|
+
iconClass: 'iconfont icon-fullscreen',
|
|
156
|
+
text: 'Expand_editor'
|
|
145
157
|
}
|
|
146
158
|
};
|
package/dist/extension/index.js
CHANGED
|
@@ -10,6 +10,12 @@ Object.defineProperty(exports, "ELementTypes", {
|
|
|
10
10
|
return _constants.ELementTypes;
|
|
11
11
|
}
|
|
12
12
|
});
|
|
13
|
+
Object.defineProperty(exports, "InlineToolbar", {
|
|
14
|
+
enumerable: true,
|
|
15
|
+
get: function () {
|
|
16
|
+
return _toolbar.InlineToolbar;
|
|
17
|
+
}
|
|
18
|
+
});
|
|
13
19
|
Object.defineProperty(exports, "SetNodeToDecorations", {
|
|
14
20
|
enumerable: true,
|
|
15
21
|
get: function () {
|
|
@@ -8,44 +8,61 @@ exports.default = void 0;
|
|
|
8
8
|
var _isUrl = _interopRequireDefault(require("is-url"));
|
|
9
9
|
var _slugid = _interopRequireDefault(require("slugid"));
|
|
10
10
|
var _slateConvert = require("../../../slate-convert");
|
|
11
|
-
var _core = require("../../core");
|
|
12
11
|
var _elementTypes = require("../../constants/element-types");
|
|
12
|
+
var _helpers = require("../code-block/helpers");
|
|
13
13
|
const withHtml = editor => {
|
|
14
14
|
const {
|
|
15
15
|
insertData
|
|
16
16
|
} = editor;
|
|
17
17
|
const newEditor = editor;
|
|
18
18
|
newEditor.insertData = data => {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
type: _elementTypes.CODE_LINE,
|
|
29
|
-
children: [{
|
|
30
|
-
text: item,
|
|
31
|
-
id: _slugid.default.nice()
|
|
32
|
-
}]
|
|
33
|
-
};
|
|
34
|
-
fragmentData.push(codeLine);
|
|
35
|
-
});
|
|
36
|
-
newEditor.insertFragment(fragmentData);
|
|
37
|
-
}
|
|
38
|
-
return;
|
|
39
|
-
}
|
|
40
|
-
const htmlContent = data.getData('text/html') || '';
|
|
41
|
-
const text = data.getData('text/plain') || '';
|
|
42
|
-
if (!(0, _isUrl.default)(text) && htmlContent) {
|
|
43
|
-
const content = (0, _slateConvert.deserializeHtml)(htmlContent);
|
|
44
|
-
editor.insertFragment(content);
|
|
45
|
-
return;
|
|
46
|
-
}
|
|
19
|
+
// If the text is a link and is not within the code_block block, it is processed as link
|
|
20
|
+
const text = data.getData('text/plain') || '';
|
|
21
|
+
if ((0, _isUrl.default)(text) && !(0, _helpers.isInCodeBlock)(newEditor)) {
|
|
22
|
+
insertData(data);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// If the copied content contains files, proceed as shown in the image
|
|
27
|
+
if (data.types.includes('Files')) {
|
|
47
28
|
insertData(data);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// If code_block is selected, the copied content will be processed according to code_block
|
|
33
|
+
if (!data.types.includes('text/code-block') && (0, _helpers.isInCodeBlock)(newEditor)) {
|
|
34
|
+
const plaintext = data.getData('text/plain') || '';
|
|
35
|
+
if (plaintext) {
|
|
36
|
+
let fragmentData = [];
|
|
37
|
+
plaintext.split('\n').forEach(item => {
|
|
38
|
+
const codeLine = {
|
|
39
|
+
id: _slugid.default.nice(),
|
|
40
|
+
type: _elementTypes.CODE_LINE,
|
|
41
|
+
children: [{
|
|
42
|
+
text: item,
|
|
43
|
+
id: _slugid.default.nice()
|
|
44
|
+
}]
|
|
45
|
+
};
|
|
46
|
+
fragmentData.push(codeLine);
|
|
47
|
+
});
|
|
48
|
+
newEditor.insertFragment(fragmentData);
|
|
49
|
+
}
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// If it is in slate format, it will be processed in slate format.
|
|
54
|
+
if (newEditor.insertFragmentData(data)) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// If it is in html format, it will be processed in html format.
|
|
59
|
+
const htmlContent = data.getData('text/html') || '';
|
|
60
|
+
if (htmlContent) {
|
|
61
|
+
const content = (0, _slateConvert.deserializeHtml)(htmlContent);
|
|
62
|
+
editor.insertFragment(content);
|
|
63
|
+
return;
|
|
48
64
|
}
|
|
65
|
+
insertData(data);
|
|
49
66
|
};
|
|
50
67
|
return newEditor;
|
|
51
68
|
};
|
|
@@ -111,7 +111,7 @@ const renderImage = (_ref, editor) => {
|
|
|
111
111
|
'selected': isSelected,
|
|
112
112
|
'error': isError
|
|
113
113
|
}),
|
|
114
|
-
alt: (element === null || element === void 0 ? void 0 : (_element$data2 = element.data) === null || _element$data2 === void 0 ? void 0 : _element$data2.alt) || '',
|
|
114
|
+
alt: (element === null || element === void 0 ? void 0 : (_element$data2 = element.data) === null || _element$data2 === void 0 ? void 0 : _element$data2.alt) || ' ' + t('Image_loading_failed'),
|
|
115
115
|
src: element === null || element === void 0 ? void 0 : (_element$data3 = element.data) === null || _element$data3 === void 0 ? void 0 : _element$data3.src,
|
|
116
116
|
width: element === null || element === void 0 ? void 0 : element.data.width,
|
|
117
117
|
height: element === null || element === void 0 ? void 0 : element.data.height
|
|
@@ -4,10 +4,17 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
|
|
|
4
4
|
Object.defineProperty(exports, "__esModule", {
|
|
5
5
|
value: true
|
|
6
6
|
});
|
|
7
|
+
Object.defineProperty(exports, "InlineToolbar", {
|
|
8
|
+
enumerable: true,
|
|
9
|
+
get: function () {
|
|
10
|
+
return _inlineToolbar.default;
|
|
11
|
+
}
|
|
12
|
+
});
|
|
7
13
|
Object.defineProperty(exports, "Toolbar", {
|
|
8
14
|
enumerable: true,
|
|
9
15
|
get: function () {
|
|
10
16
|
return _headerToolbar.default;
|
|
11
17
|
}
|
|
12
18
|
});
|
|
13
|
-
var _headerToolbar = _interopRequireDefault(require("./header-toolbar"));
|
|
19
|
+
var _headerToolbar = _interopRequireDefault(require("./header-toolbar"));
|
|
20
|
+
var _inlineToolbar = _interopRequireDefault(require("./inline-toolbar"));
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
.sf-slate-editor-toolbar {
|
|
2
|
+
background-color: #fcfcfc !important;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
.sf-slate-editor-toolbar .sf-slate-article-info-control {
|
|
6
|
+
position: absolute;
|
|
7
|
+
right: 20px;
|
|
8
|
+
height: 30px;
|
|
9
|
+
width: 30px;
|
|
10
|
+
line-height: 30px;
|
|
11
|
+
display: flex;
|
|
12
|
+
justify-content: center;
|
|
13
|
+
cursor: pointer;
|
|
14
|
+
color: #555;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.sf-slate-editor-toolbar .sf-slate-article-info-control:hover {
|
|
18
|
+
background-color: #e5e5e5;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.sf-slate-editor-toolbar .sf-slate-help-info-control {
|
|
22
|
+
position: absolute;
|
|
23
|
+
right: 20px;
|
|
24
|
+
height: 30px;
|
|
25
|
+
width: 30px;
|
|
26
|
+
line-height: 30px;
|
|
27
|
+
display: flex;
|
|
28
|
+
justify-content: center;
|
|
29
|
+
cursor: pointer;
|
|
30
|
+
color: #555;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.sf-slate-editor-toolbar .sf-slate-help-info-control > span:hover {
|
|
34
|
+
cursor: pointer;
|
|
35
|
+
color: #333;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.sf-slate-editor-toolbar .sf-slate-article-info-control .iconfont {
|
|
39
|
+
font-size: 13px;
|
|
40
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
|
|
4
|
+
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
|
|
5
|
+
Object.defineProperty(exports, "__esModule", {
|
|
6
|
+
value: true
|
|
7
|
+
});
|
|
8
|
+
exports.default = void 0;
|
|
9
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
10
|
+
var _useSelectionUpdate = _interopRequireDefault(require("../../../hooks/use-selection-update"));
|
|
11
|
+
var _commons = require("../../commons");
|
|
12
|
+
var _menu = _interopRequireDefault(require("../../plugins/blockquote/menu"));
|
|
13
|
+
var _menu2 = _interopRequireDefault(require("../../plugins/header/menu"));
|
|
14
|
+
var _menu3 = _interopRequireDefault(require("../../plugins/text-style/menu"));
|
|
15
|
+
var _menu4 = _interopRequireDefault(require("../../plugins/link/menu"));
|
|
16
|
+
var _constants = require("../../constants");
|
|
17
|
+
var _menu5 = _interopRequireDefault(require("../../plugins/image/menu"));
|
|
18
|
+
var _menu6 = _interopRequireDefault(require("../../plugins/code-block/menu"));
|
|
19
|
+
var _menu7 = _interopRequireDefault(require("../../plugins/check-list/menu"));
|
|
20
|
+
var _menu8 = _interopRequireDefault(require("../../plugins/list/menu"));
|
|
21
|
+
var _elementTypes = require("../../constants/element-types");
|
|
22
|
+
var _tableOperator = require("../../plugins/table/menu/table-operator");
|
|
23
|
+
var _helper = require("../../plugins/table/helper");
|
|
24
|
+
var _menu9 = _interopRequireDefault(require("../../plugins/clear-format/menu"));
|
|
25
|
+
var _shortcutDialog = _interopRequireDefault(require("../user-help/shortcut-dialog"));
|
|
26
|
+
require("./index.css");
|
|
27
|
+
// import TableMenu from '../../plugins/table/menu';
|
|
28
|
+
// import FormulaMenu from '../../plugins/formula/menu';
|
|
29
|
+
// import ColumnMenu from '../../plugins/column/menu';
|
|
30
|
+
|
|
31
|
+
const InlineToolbar = _ref => {
|
|
32
|
+
let {
|
|
33
|
+
editor,
|
|
34
|
+
readonly = false,
|
|
35
|
+
isRichEditor = false,
|
|
36
|
+
isSupportFormula = false,
|
|
37
|
+
isSupportInsertSeafileImage = false,
|
|
38
|
+
isSupportColumn = false,
|
|
39
|
+
onExpandEditorToggle
|
|
40
|
+
} = _ref;
|
|
41
|
+
(0, _useSelectionUpdate.default)();
|
|
42
|
+
|
|
43
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
44
|
+
const isShowSubTableMenu = (0, _react.useMemo)(() => (0, _helper.isInTable)(editor), [editor.selection]);
|
|
45
|
+
const [isShowHelpModal, setIsShowHelpModal] = (0, _react.useState)(false);
|
|
46
|
+
const onHelpIconToggle = (0, _react.useCallback)(() => {
|
|
47
|
+
setIsShowHelpModal(!isShowHelpModal);
|
|
48
|
+
}, [isShowHelpModal]);
|
|
49
|
+
const commonProps = {
|
|
50
|
+
editor,
|
|
51
|
+
readonly,
|
|
52
|
+
isRichEditor
|
|
53
|
+
};
|
|
54
|
+
return /*#__PURE__*/_react.default.createElement("div", {
|
|
55
|
+
className: "sf-slate-editor-toolbar"
|
|
56
|
+
}, isRichEditor && /*#__PURE__*/_react.default.createElement(_commons.MenuGroup, null), /*#__PURE__*/_react.default.createElement(_commons.MenuGroup, null, /*#__PURE__*/_react.default.createElement(_menu2.default, commonProps)), /*#__PURE__*/_react.default.createElement(_commons.MenuGroup, null, /*#__PURE__*/_react.default.createElement(_menu3.default, Object.assign({}, commonProps, {
|
|
57
|
+
type: _constants.TEXT_STYLE_MAP.BOLD
|
|
58
|
+
})), /*#__PURE__*/_react.default.createElement(_menu3.default, Object.assign({}, commonProps, {
|
|
59
|
+
type: _constants.TEXT_STYLE_MAP.ITALIC
|
|
60
|
+
})), /*#__PURE__*/_react.default.createElement(_menu3.default, Object.assign({}, commonProps, {
|
|
61
|
+
type: _constants.TEXT_STYLE_MAP.CODE
|
|
62
|
+
})), /*#__PURE__*/_react.default.createElement(_menu4.default, commonProps)), /*#__PURE__*/_react.default.createElement(_commons.MenuGroup, null, /*#__PURE__*/_react.default.createElement(_menu.default, commonProps), /*#__PURE__*/_react.default.createElement(_menu7.default, commonProps), /*#__PURE__*/_react.default.createElement(_menu8.default, Object.assign({}, commonProps, {
|
|
63
|
+
type: _elementTypes.ORDERED_LIST
|
|
64
|
+
})), /*#__PURE__*/_react.default.createElement(_menu8.default, Object.assign({}, commonProps, {
|
|
65
|
+
type: _elementTypes.UNORDERED_LIST
|
|
66
|
+
}))), /*#__PURE__*/_react.default.createElement(_commons.MenuGroup, null, /*#__PURE__*/_react.default.createElement(_menu6.default, commonProps), /*#__PURE__*/_react.default.createElement(_commons.MoreMenu, commonProps, /*#__PURE__*/_react.default.createElement(_commons.MenuGroup, null, /*#__PURE__*/_react.default.createElement(_menu5.default, Object.assign({}, commonProps, {
|
|
67
|
+
isSupportInsertSeafileImage: isSupportInsertSeafileImage
|
|
68
|
+
}))), isShowSubTableMenu && /*#__PURE__*/_react.default.createElement(_commons.MenuGroup, {
|
|
69
|
+
className: "sf-menu-group sf-table-operations-group"
|
|
70
|
+
}, /*#__PURE__*/_react.default.createElement(_tableOperator.AlignmentDropDown, commonProps), /*#__PURE__*/_react.default.createElement(_tableOperator.ColumnOperationDropDownList, commonProps), /*#__PURE__*/_react.default.createElement(_tableOperator.RowOperationDropDownList, commonProps), /*#__PURE__*/_react.default.createElement(_tableOperator.RemoveTableMenu, commonProps)), /*#__PURE__*/_react.default.createElement(_commons.MenuGroup, null, /*#__PURE__*/_react.default.createElement(_menu9.default, commonProps)), !isRichEditor && /*#__PURE__*/_react.default.createElement("div", {
|
|
71
|
+
className: "sf-slate-help-info-control",
|
|
72
|
+
onClick: onHelpIconToggle
|
|
73
|
+
}, /*#__PURE__*/_react.default.createElement("span", {
|
|
74
|
+
className: "iconfont icon-use-help"
|
|
75
|
+
})))), onExpandEditorToggle && /*#__PURE__*/_react.default.createElement(_commons.ExpandEditorMenu, commonProps), isShowHelpModal && /*#__PURE__*/_react.default.createElement(_shortcutDialog.default, {
|
|
76
|
+
isRichEditor: isRichEditor,
|
|
77
|
+
toggleShortcutDialog: onHelpIconToggle
|
|
78
|
+
}));
|
|
79
|
+
};
|
|
80
|
+
InlineToolbar.defaultProps = {
|
|
81
|
+
readonly: false
|
|
82
|
+
};
|
|
83
|
+
var _default = exports.default = InlineToolbar;
|
|
File without changes
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
|
|
4
|
+
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
|
|
5
|
+
Object.defineProperty(exports, "__esModule", {
|
|
6
|
+
value: true
|
|
7
|
+
});
|
|
8
|
+
exports.default = void 0;
|
|
9
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
10
|
+
var _classnames = _interopRequireDefault(require("classnames"));
|
|
11
|
+
var _simpleEditor = _interopRequireDefault(require("../simple-editor"));
|
|
12
|
+
var _getPreviewContent = _interopRequireDefault(require("../../utils/get-preview-content"));
|
|
13
|
+
var _getBrowserInfo = _interopRequireDefault(require("../../utils/get-browser-Info"));
|
|
14
|
+
var _markdownPreview = _interopRequireDefault(require("../markdown-preview"));
|
|
15
|
+
var _longtextEditorDialog = _interopRequireDefault(require("../longtext-editor-dialog"));
|
|
16
|
+
require("./index.css");
|
|
17
|
+
const InlineLongTextEditor = _ref => {
|
|
18
|
+
let {
|
|
19
|
+
lang,
|
|
20
|
+
headerName,
|
|
21
|
+
value,
|
|
22
|
+
autoSave = true,
|
|
23
|
+
saveDelay = 60000,
|
|
24
|
+
isCheckBrowser = false,
|
|
25
|
+
editorApi,
|
|
26
|
+
onSaveEditorValue,
|
|
27
|
+
onEditorValueChanged
|
|
28
|
+
} = _ref;
|
|
29
|
+
const editorRef = useRef(null);
|
|
30
|
+
const [isValueChanged, setValueChanged] = (0, _react.useState)(false);
|
|
31
|
+
const [showExpandEditor, setShowExpandEditor] = (0, _react.useState)(false);
|
|
32
|
+
const {
|
|
33
|
+
isValidBrowser,
|
|
34
|
+
isWindowsWechat
|
|
35
|
+
} = useMemo(() => {
|
|
36
|
+
return (0, _getBrowserInfo.default)(isCheckBrowser);
|
|
37
|
+
}, [isCheckBrowser]);
|
|
38
|
+
const onUpdateEditorValue = (0, _react.useCallback)(() => {
|
|
39
|
+
var _editorRef$current, _editorRef$current2;
|
|
40
|
+
if (!isValueChanged) return;
|
|
41
|
+
const markdownString = (_editorRef$current = editorRef.current) === null || _editorRef$current === void 0 ? void 0 : _editorRef$current.getValue();
|
|
42
|
+
const slateNodes = (_editorRef$current2 = editorRef.current) === null || _editorRef$current2 === void 0 ? void 0 : _editorRef$current2.getSlateValue();
|
|
43
|
+
const {
|
|
44
|
+
previewText,
|
|
45
|
+
images,
|
|
46
|
+
links,
|
|
47
|
+
checklist
|
|
48
|
+
} = (0, _getPreviewContent.default)(slateNodes, false);
|
|
49
|
+
onSaveEditorValue({
|
|
50
|
+
text: markdownString,
|
|
51
|
+
preview: previewText,
|
|
52
|
+
images: images,
|
|
53
|
+
links: links,
|
|
54
|
+
checklist
|
|
55
|
+
});
|
|
56
|
+
setValueChanged(false);
|
|
57
|
+
}, [isValueChanged, onSaveEditorValue]);
|
|
58
|
+
const onContentChanged = (0, _react.useCallback)(() => {
|
|
59
|
+
// delay to update editor's content
|
|
60
|
+
setTimeout(() => {
|
|
61
|
+
// update parent's component cache value
|
|
62
|
+
if (onEditorValueChanged && typeof onEditorValueChanged === 'function') {
|
|
63
|
+
var _editorRef$current3, _editorRef$current4;
|
|
64
|
+
const markdownString = (_editorRef$current3 = editorRef.current) === null || _editorRef$current3 === void 0 ? void 0 : _editorRef$current3.getValue();
|
|
65
|
+
const slateNodes = (_editorRef$current4 = editorRef.current) === null || _editorRef$current4 === void 0 ? void 0 : _editorRef$current4.getSlateValue();
|
|
66
|
+
const {
|
|
67
|
+
previewText,
|
|
68
|
+
images,
|
|
69
|
+
links,
|
|
70
|
+
checklist
|
|
71
|
+
} = (0, _getPreviewContent.default)(slateNodes, false);
|
|
72
|
+
onEditorValueChanged({
|
|
73
|
+
text: markdownString,
|
|
74
|
+
preview: previewText,
|
|
75
|
+
images: images,
|
|
76
|
+
links: links,
|
|
77
|
+
checklist
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
setValueChanged(true);
|
|
81
|
+
}, 0);
|
|
82
|
+
}, [onEditorValueChanged]);
|
|
83
|
+
const openEditorDialog = (0, _react.useCallback)(() => {
|
|
84
|
+
setShowExpandEditor(true);
|
|
85
|
+
}, []);
|
|
86
|
+
const onCloseEditorDialog = (0, _react.useCallback)(() => {
|
|
87
|
+
onUpdateEditorValue();
|
|
88
|
+
setShowExpandEditor(false);
|
|
89
|
+
}, [onUpdateEditorValue]);
|
|
90
|
+
useEffect(() => {
|
|
91
|
+
let timer = null;
|
|
92
|
+
if (autoSave) {
|
|
93
|
+
timer = setTimeout(() => {
|
|
94
|
+
onUpdateEditorValue();
|
|
95
|
+
}, saveDelay);
|
|
96
|
+
}
|
|
97
|
+
return () => {
|
|
98
|
+
timer && clearTimeout(timer);
|
|
99
|
+
};
|
|
100
|
+
}, [autoSave, saveDelay, onUpdateEditorValue]);
|
|
101
|
+
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("div", null, !readOnly && !isWindowsWechat && /*#__PURE__*/_react.default.createElement(_simpleEditor.default, {
|
|
102
|
+
isInline: true,
|
|
103
|
+
ref: editorRef,
|
|
104
|
+
value: value,
|
|
105
|
+
editorApi: editorApi,
|
|
106
|
+
onContentChanged: onContentChanged,
|
|
107
|
+
onExpandEditorToggle: openEditorDialog
|
|
108
|
+
})), showExpandEditor && /*#__PURE__*/_react.default.createElement(_longtextEditorDialog.default, {
|
|
109
|
+
lang: lang,
|
|
110
|
+
readOnly: false,
|
|
111
|
+
headerName: headerName,
|
|
112
|
+
value: value,
|
|
113
|
+
autoSave: autoSave,
|
|
114
|
+
saveDelay: saveDelay,
|
|
115
|
+
isCheckBrowser: isCheckBrowser,
|
|
116
|
+
editorApi: editorApi,
|
|
117
|
+
onSaveEditorValue: onSaveEditorValue,
|
|
118
|
+
onEditorValueChanged: onEditorValueChanged,
|
|
119
|
+
onCloseEditorDialog: onCloseEditorDialog
|
|
120
|
+
}));
|
|
121
|
+
};
|
|
122
|
+
var _default = exports.default = InlineLongTextEditor;
|
|
@@ -13,12 +13,14 @@ var _useMathjax = _interopRequireDefault(require("../hooks/use-mathjax"));
|
|
|
13
13
|
var _simpleSlateEditor = _interopRequireDefault(require("../editors/simple-slate-editor "));
|
|
14
14
|
const SimpleEditor = /*#__PURE__*/(0, _react.forwardRef)((_ref, ref) => {
|
|
15
15
|
let {
|
|
16
|
+
isInline,
|
|
16
17
|
isFetching,
|
|
17
18
|
value,
|
|
18
19
|
editorApi,
|
|
19
20
|
mathJaxSource,
|
|
20
21
|
onSave: propsOnSave,
|
|
21
|
-
onContentChanged: propsOnContentChanged
|
|
22
|
+
onContentChanged: propsOnContentChanged,
|
|
23
|
+
...otherProps
|
|
22
24
|
} = _ref;
|
|
23
25
|
const [richValue, setRichValue] = (0, _react.useState)([]);
|
|
24
26
|
const [isLoading, setIsLoading] = (0, _react.useState)(true);
|
|
@@ -49,11 +51,13 @@ const SimpleEditor = /*#__PURE__*/(0, _react.forwardRef)((_ref, ref) => {
|
|
|
49
51
|
propsOnContentChanged && propsOnContentChanged();
|
|
50
52
|
}, [propsOnContentChanged]);
|
|
51
53
|
const props = {
|
|
54
|
+
isInline,
|
|
52
55
|
isSupportFormula: !!mathJaxSource,
|
|
53
56
|
value: richValue,
|
|
54
57
|
editorApi: editorApi,
|
|
55
58
|
onSave: propsOnSave,
|
|
56
|
-
onContentChanged: onContentChanged
|
|
59
|
+
onContentChanged: onContentChanged,
|
|
60
|
+
...otherProps
|
|
57
61
|
};
|
|
58
62
|
if (isFetching || isLoading || isLoadingMathJax) {
|
|
59
63
|
return /*#__PURE__*/_react.default.createElement(_loading.default, null);
|
package/package.json
CHANGED
|
@@ -221,5 +221,6 @@
|
|
|
221
221
|
"Select_field": "Выбрать поле",
|
|
222
222
|
"Font_style": "Стиль шрифта",
|
|
223
223
|
"Open_link": "Открыть ссылку",
|
|
224
|
-
"Image_is_uploading": "Изображение загружается"
|
|
224
|
+
"Image_is_uploading": "Изображение загружается",
|
|
225
|
+
"Image_loading_failed": "Image loading failed"
|
|
225
226
|
}
|
|
Binary file
|
|
@@ -14,6 +14,8 @@
|
|
|
14
14
|
/>
|
|
15
15
|
<missing-glyph />
|
|
16
16
|
|
|
17
|
+
<glyph glyph-name="more" unicode="" d="M835.2 387.2c0-54.4 41.6-96 96-96s96 41.6 96 96-41.6 96-96 96c-51.2 0-96-41.6-96-96z m-416 0c0-54.4 41.6-96 96-96s96 41.6 96 96-41.6 96-96 96c-51.2 0-96-41.6-96-96z m-416 0c0-54.4 41.6-96 96-96s96 41.6 96 96-41.6 96-96 96c-51.2 0-96-41.6-96-96z" horiz-adv-x="1027" />
|
|
18
|
+
|
|
17
19
|
<glyph glyph-name="drop-down" unicode="" d="M550.4 169.6l265.6 336c32 38.4 6.4 102.4-38.4 102.4H246.4c-44.8 0-70.4-60.8-38.4-102.4l265.6-336c19.2-25.6 57.6-25.6 76.8 0z" horiz-adv-x="1024" />
|
|
18
20
|
|
|
19
21
|
<glyph glyph-name="caret-up" unicode="" d="M550.4 588.8l265.6-336c32-38.4 6.4-102.4-38.4-102.4H246.4c-44.8 0-70.4 60.8-38.4 102.4l265.6 336c19.2 25.6 57.6 25.6 76.8 0z" horiz-adv-x="1024" />
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
@font-face {
|
|
2
2
|
font-family: "iconfont"; /* Project id 4375832 */
|
|
3
|
-
src: url('./seafile-editor-font/iconfont.eot?t=
|
|
4
|
-
src: url('./seafile-editor-font/iconfont.eot?t=
|
|
5
|
-
url('./seafile-editor-font/iconfont.woff2?t=
|
|
6
|
-
url('./seafile-editor-font/iconfont.woff?t=
|
|
7
|
-
url('./seafile-editor-font/iconfont.ttf?t=
|
|
8
|
-
url('./seafile-editor-font/iconfont.svg?t=
|
|
3
|
+
src: url('./seafile-editor-font/iconfont.eot?t=1714979485064'); /* IE9 */
|
|
4
|
+
src: url('./seafile-editor-font/iconfont.eot?t=1714979485064#iefix') format('embedded-opentype'), /* IE6-IE8 */
|
|
5
|
+
url('./seafile-editor-font/iconfont.woff2?t=1714979485064') format('woff2'),
|
|
6
|
+
url('./seafile-editor-font/iconfont.woff?t=1714979485064') format('woff'),
|
|
7
|
+
url('./seafile-editor-font/iconfont.ttf?t=1714979485064') format('truetype'),
|
|
8
|
+
url('./seafile-editor-font/iconfont.svg?t=1714979485064#iconfont') format('svg');
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
.iconfont {
|
|
@@ -16,6 +16,10 @@
|
|
|
16
16
|
-moz-osx-font-smoothing: grayscale;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
+
.icon-more:before {
|
|
20
|
+
content: "\e626";
|
|
21
|
+
}
|
|
22
|
+
|
|
19
23
|
.icon-drop-down:before {
|
|
20
24
|
content: "\e685";
|
|
21
25
|
}
|
package/readme.md
CHANGED
|
@@ -2,25 +2,219 @@
|
|
|
2
2
|
|
|
3
3
|
SeaMarkdown editor is a WYSIWYG Markdown editor based on slate.js. It is used in Seafile and SeaTable project.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Markdown editor UI
|
|
6
|
+

|
|
6
7
|
|
|
8
|
+
## Integrated markdown editor UI
|
|
9
|
+
> An integrated demo. You can customize it according to the style you design.
|
|
10
|
+
|
|
11
|
+

|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
To install via npm:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install @seafile/seafile-editor --save
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Import the library into your project:
|
|
21
|
+
```javascript
|
|
22
|
+
import { MarkdownEditor } from '@seafile/seafile-editor';
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Provide components and functions
|
|
26
|
+
|
|
27
|
+
### Components
|
|
28
|
+
|
|
29
|
+
|Name|Explain|
|
|
30
|
+
|-|-|
|
|
31
|
+
|MarkdownEditor|Markdown rich text editor component|
|
|
32
|
+
|MarkdownViewer|Markdown content preview component|
|
|
33
|
+
|
|
34
|
+
### Functions
|
|
7
35
|
|Name|Explain|
|
|
8
36
|
|-|-|
|
|
9
|
-
|
|
|
10
|
-
|
|
|
37
|
+
|mdStringToSlate|Convert markdown strings to the data format used by the editor|
|
|
38
|
+
|slateToMdString|Convert the data format used by the editor to a markdown string|
|
|
39
|
+
|processor|Convert markdown string to html format content|
|
|
40
|
+
|
|
41
|
+
## MarkdownEditor usage
|
|
42
|
+
|
|
43
|
+
### Define api
|
|
44
|
+
|
|
45
|
+
```javascript
|
|
46
|
+
import axios from 'axios';
|
|
47
|
+
|
|
48
|
+
class API {
|
|
49
|
+
|
|
50
|
+
getFileContent() {
|
|
51
|
+
const fileUrl = '';
|
|
52
|
+
return axios.get(fileUrl);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
saveFileContent(content) {
|
|
56
|
+
const updateLink = '';
|
|
57
|
+
const formData = new FormData();
|
|
58
|
+
const blob = new Blob([data], { type: 'text/plain' });
|
|
59
|
+
formData.append('file', blob);
|
|
60
|
+
axios.post(updateLink, formData);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
uploadLocalImage(file) {
|
|
64
|
+
const uploadLink = '';
|
|
65
|
+
const formData = new FormData();
|
|
66
|
+
formData.append('file', file);
|
|
67
|
+
return axios.post(uploadLink, formData);
|
|
68
|
+
}
|
|
11
69
|
|
|
12
|
-
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const editorApi = new API();
|
|
73
|
+
|
|
74
|
+
export default editorApi;
|
|
75
|
+
```
|
|
13
76
|
|
|
14
|
-
|
|
15
|
-
2. code demo
|
|
77
|
+
### Integrate simple into your own page
|
|
16
78
|
```javascript
|
|
79
|
+
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
|
80
|
+
import { Button } from 'reactstrap';
|
|
17
81
|
import { MarkdownEditor } from '@seafile/seafile-editor';
|
|
82
|
+
import editorApi from './api';
|
|
18
83
|
|
|
19
|
-
export default
|
|
84
|
+
export default function SimpleMarkdownEditor() {
|
|
20
85
|
|
|
21
|
-
|
|
22
|
-
|
|
86
|
+
const editorRef = useRef(null);
|
|
87
|
+
const [fileContent, setFileContent] = useState('');
|
|
88
|
+
const [isFetching, setIsFetching] = useState(true);
|
|
89
|
+
const [contentVersion, setContentVersion] = useState(0);
|
|
90
|
+
|
|
91
|
+
const mathJaxSource = '';
|
|
92
|
+
|
|
93
|
+
useEffect(() => {
|
|
94
|
+
editorApi.getFileContent().then(res => {
|
|
95
|
+
setFileContent(res.data);
|
|
96
|
+
setIsFetching(false);
|
|
97
|
+
});
|
|
98
|
+
}, []);
|
|
99
|
+
|
|
100
|
+
const onSave = useCallback(() => {
|
|
101
|
+
const content = editorRef.current.getValue();
|
|
102
|
+
editorApi.saveFileContent(content).then(res => {
|
|
103
|
+
window.alert('Saved successfully')
|
|
104
|
+
});
|
|
105
|
+
}, []);
|
|
106
|
+
|
|
107
|
+
const onContentChanged = useCallback(() => {
|
|
108
|
+
setContentVersion(contentVersion + 1);
|
|
109
|
+
}, [contentVersion]);
|
|
110
|
+
|
|
111
|
+
return (
|
|
112
|
+
<div className='seafile-editor'>
|
|
113
|
+
<MarkdownEditor
|
|
114
|
+
ref={editorRef}
|
|
115
|
+
isFetching={isFetching}
|
|
116
|
+
value={fileContent}
|
|
117
|
+
initValue={''}
|
|
118
|
+
editorApi={editorApi}
|
|
119
|
+
onSave={onSave}
|
|
120
|
+
onContentChanged={onContentChanged}
|
|
121
|
+
mathJaxSource={mathJaxSource}
|
|
122
|
+
/>
|
|
123
|
+
</div>
|
|
124
|
+
);
|
|
23
125
|
}
|
|
126
|
+
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Props
|
|
130
|
+
|
|
131
|
+
Common props you may want to specify include:
|
|
132
|
+
|
|
133
|
+
* ref: A reference to the editor, used to obtain the current content in the editor
|
|
134
|
+
* ref.current.getValue: Get the current markdown string value in the editor
|
|
135
|
+
* ref.current.getSlateValue: Get the value of the current slate data format in the editor
|
|
136
|
+
* isFetching: Whether the value of the editor is being obtained, if the loading effect is displayed while obtaining, and if the acquisition is completed, the corresponding content obtained is displayed in the editor.
|
|
137
|
+
* value: The text content obtained
|
|
138
|
+
* initValue: If value does not exist, a default value can be provided via initValue
|
|
139
|
+
* onSave: When the editor content changes, the onSave callback event is triggered externally. The user can save the document by implementing this callback function.
|
|
140
|
+
* onContentChanged: When the editor content changes, a change event is triggered to facilitate the user to record whether the document
|
|
141
|
+
* mathJaxSource: Supports inserting formulas. If you want to support inserting formulas, please provide a path that can load formula resources. If support is not required, you can ignore this parameter. [math-jax document](https://docs.mathjax.org/en/stable/start.html)
|
|
142
|
+
|
|
143
|
+
## Functions
|
|
144
|
+
|
|
145
|
+
### `mdStringToSlate(mdString)`
|
|
146
|
+
Convert markdown string to data structure supported by editor (slate)
|
|
147
|
+
|
|
148
|
+
**Params**
|
|
149
|
+
|
|
150
|
+
* mdString: markdown string
|
|
151
|
+
|
|
152
|
+
**Returns**
|
|
153
|
+
|
|
154
|
+
  Slate nodes
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
### `slateToMdString(slateNodes)`
|
|
158
|
+
Convert editor (slate) supported data structures to markdown string
|
|
159
|
+
|
|
160
|
+
**Params**
|
|
161
|
+
|
|
162
|
+
* slateNodes: slate nodes
|
|
163
|
+
|
|
164
|
+
**Returns**
|
|
165
|
+
|
|
166
|
+
  Markdown string
|
|
167
|
+
|
|
168
|
+
### `processor` processor.process(mdString)
|
|
169
|
+
Convert markdown string to html
|
|
170
|
+
|
|
171
|
+
**Params**
|
|
172
|
+
|
|
173
|
+
* mdString: markdown string
|
|
174
|
+
|
|
175
|
+
**Returns**
|
|
176
|
+
|
|
177
|
+
 Promise
|
|
178
|
+
|
|
179
|
+
Demo
|
|
180
|
+
```javascript
|
|
181
|
+
const string = '# Hello, I am first level title'
|
|
182
|
+
processor.process(string).then(result => {
|
|
183
|
+
const html = String(result);
|
|
184
|
+
...
|
|
185
|
+
})
|
|
186
|
+
|
|
24
187
|
```
|
|
25
188
|
|
|
26
189
|
|
|
190
|
+
## 🖥 Environment Support
|
|
191
|
+
|
|
192
|
+
* Modern browsers
|
|
193
|
+
* Software built-in browser
|
|
194
|
+
|
|
195
|
+
### Modern browsers
|
|
196
|
+
|
|
197
|
+
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)<br>Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)<br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)<br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)<br>Safari |
|
|
198
|
+
| --- | --- | --- | --- |
|
|
199
|
+
| Edge | false | last 2 versions | false |
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
### Software built-in browser
|
|
203
|
+
|
|
204
|
+
**Mac OS**
|
|
205
|
+
|
|
206
|
+
| software | browser | version | internal | isSupport |
|
|
207
|
+
|-|-|-|-|-|
|
|
208
|
+
|<img src="./assets/imgs/wechat.png" width='16'> WeChat| Chrome |107.0.0.0| AppleWebKit/537.36 |false|
|
|
209
|
+
|<img src="./assets/imgs/wecom.png" width='16'> WeCom|Safari||AppleWebKit/605.1.15 |false|
|
|
210
|
+
|
|
211
|
+
**Windows OS**
|
|
212
|
+
> windows 11
|
|
213
|
+
|
|
214
|
+
| software | browser | version | internal | isSupport |
|
|
215
|
+
|-|-|-|-|-|
|
|
216
|
+
|<img src="./assets/imgs/wechat.png" width='16'> WeChat| Chrome |106.0.0.0| AppleWebKit/537.36 |false|
|
|
217
|
+
|<img src="./assets/imgs/wecom.png" width='16'> WeCom|Chrome|108.0.5993.119|AppleWebKit/537.36 |false|
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
|