@seafile/sdoc-editor 0.1.49 → 0.1.51
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/cursor/helper.js +7 -9
- package/dist/basic-sdk/cursor/use-cursors.js +24 -0
- package/dist/basic-sdk/editor.js +113 -114
- package/dist/basic-sdk/extension/constants/index.js +1 -1
- package/dist/basic-sdk/extension/index.js +4 -3
- package/dist/basic-sdk/extension/menu/context-menu/index.css +1 -0
- package/dist/basic-sdk/extension/menu/context-menu/index.js +37 -0
- package/dist/basic-sdk/extension/menu/index.js +2 -1
- package/dist/basic-sdk/extension/plugins/table/index.js +3 -2
- package/dist/basic-sdk/extension/plugins/table/menu/context-menu/index.css +27 -0
- package/dist/basic-sdk/extension/plugins/table/menu/context-menu/index.js +124 -0
- package/dist/basic-sdk/extension/plugins/table/menu/context-menu/insert-table-element.js +93 -0
- package/dist/basic-sdk/extension/plugins/table/menu/index.js +2 -1
- package/dist/basic-sdk/extension/plugins/table/plugin.js +19 -12
- package/dist/basic-sdk/extension/plugins/table/render/render-table/index.css +8 -0
- package/dist/basic-sdk/extension/render/render-element.js +6 -1
- package/dist/basic-sdk/extension/render/render-leaf.js +7 -1
- package/dist/basic-sdk/index.js +1 -1
- package/dist/basic-sdk/socket/helpers.js +10 -8
- package/dist/basic-sdk/socket/socket-client.js +14 -4
- package/dist/basic-sdk/socket/socket-manager.js +14 -7
- package/dist/basic-sdk/socket/with-socket-io.js +11 -2
- package/dist/basic-sdk/utils/diff.js +1 -0
- package/dist/components/doc-operations/style.css +1 -0
- package/dist/components/modal-portal.js +41 -0
- package/dist/pages/simple-editor.js +0 -4
- package/package.json +2 -2
- package/public/locales/cs/sdoc-editor.json +1 -1
- package/public/locales/de/sdoc-editor.json +1 -1
- package/public/locales/en/sdoc-editor.json +8 -2
- package/public/locales/es/sdoc-editor.json +1 -1
- package/public/locales/es-AR/sdoc-editor.json +1 -1
- package/public/locales/es-MX/sdoc-editor.json +1 -1
- package/public/locales/fr/sdoc-editor.json +1 -1
- package/public/locales/it/sdoc-editor.json +1 -1
- package/public/locales/ru/sdoc-editor.json +1 -1
- package/public/locales/zh-CN/sdoc-editor.json +8 -2
- package/dist/basic-sdk/cursor/decorate-cursors.js +0 -32
- package/dist/basic-sdk/decorates/index.js +0 -25
- package/dist/basic-sdk/editor2.js +0 -107
|
@@ -4,25 +4,23 @@ import randomColor from 'randomcolor';
|
|
|
4
4
|
// selection: { anchor, focus }
|
|
5
5
|
// cursor: { anchor, focus }
|
|
6
6
|
|
|
7
|
-
export var setCursor = function setCursor(editor,
|
|
7
|
+
export var setCursor = function setCursor(editor, user, location, cursorData) {
|
|
8
8
|
var clientId = user.username;
|
|
9
|
-
var cursorOps = operations.filter(function (operation) {
|
|
10
|
-
return operation.type === 'set_selection';
|
|
11
|
-
});
|
|
12
9
|
if (!editor.cursors) editor.cursors = {};
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
var newCursor = lastCursorOp && lastCursorOp.newProperties || {};
|
|
17
|
-
var newCursorData = _objectSpread(_objectSpread(_objectSpread(_objectSpread({}, oldCursor), newCursor), selection), cursorData);
|
|
10
|
+
if (location) {
|
|
11
|
+
var oldCursor = editor.cursors[clientId] ? editor.cursors[clientId] : {};
|
|
12
|
+
var newCursorData = _objectSpread(_objectSpread(_objectSpread({}, oldCursor), location), cursorData);
|
|
18
13
|
editor.cursors[clientId] = newCursorData;
|
|
19
14
|
} else {
|
|
20
15
|
delete editor.cursors[clientId];
|
|
21
16
|
}
|
|
17
|
+
editor.cursors = _objectSpread({}, editor.cursors);
|
|
22
18
|
return editor;
|
|
23
19
|
};
|
|
24
20
|
export var deleteCursor = function deleteCursor(editor, username) {
|
|
25
21
|
delete editor.cursors[username];
|
|
22
|
+
editor.cursors = _objectSpread({}, editor.cursors);
|
|
23
|
+
return editor;
|
|
26
24
|
};
|
|
27
25
|
export var generateCursorData = function generateCursorData(config) {
|
|
28
26
|
var user = config.user;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
|
2
|
+
import { useEffect, useState } from 'react';
|
|
3
|
+
export var useCursors = function useCursors(editor) {
|
|
4
|
+
var _useState = useState([]),
|
|
5
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
6
|
+
cursors = _useState2[0],
|
|
7
|
+
setCursors = _useState2[1];
|
|
8
|
+
useEffect(function () {
|
|
9
|
+
var cursors = Object.values(editor.cursors) || [];
|
|
10
|
+
setCursors(cursors);
|
|
11
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
12
|
+
}, []);
|
|
13
|
+
useEffect(function () {
|
|
14
|
+
editor.onCursor = function (editorCursors) {
|
|
15
|
+
var cursors = Object.values(editorCursors) || [];
|
|
16
|
+
setCursors(cursors);
|
|
17
|
+
};
|
|
18
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
19
|
+
}, []);
|
|
20
|
+
return {
|
|
21
|
+
cursors: cursors,
|
|
22
|
+
setCursors: setCursors
|
|
23
|
+
};
|
|
24
|
+
};
|
package/dist/basic-sdk/editor.js
CHANGED
|
@@ -1,128 +1,127 @@
|
|
|
1
|
+
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
|
1
2
|
import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import _inherits from "@babel/runtime/helpers/esm/inherits";
|
|
5
|
-
import _createSuper from "@babel/runtime/helpers/esm/createSuper";
|
|
6
|
-
import React from 'react';
|
|
7
|
-
import { Node } from '@seafile/slate';
|
|
3
|
+
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
|
4
|
+
import { Node, Editor } from '@seafile/slate';
|
|
8
5
|
import { Editable, Slate, ReactEditor } from '@seafile/slate-react';
|
|
9
|
-
import {
|
|
10
|
-
import
|
|
6
|
+
import defaultEditor, { renderLeaf, renderElement, Toolbar, ContextMenu } from './extension';
|
|
7
|
+
import { focusEditor } from './extension/core';
|
|
11
8
|
import { withSocketIO } from './socket';
|
|
12
9
|
import withNodeId from './node-id';
|
|
13
10
|
import SDocOutline from './outline';
|
|
14
11
|
import EventProxy from './utils/event-handler';
|
|
15
|
-
import {
|
|
16
|
-
import { uiDecorate } from './decorates';
|
|
12
|
+
import { useCursors } from './cursor/use-cursors';
|
|
17
13
|
import './assets/css/layout.css';
|
|
18
14
|
import './assets/css/sdoc-editor-plugins.css';
|
|
19
|
-
var SDocEditor =
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
slateValue: _toConsumableArray(slateValue)
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
var _props$document = props.document,
|
|
50
|
-
children = _props$document.children,
|
|
51
|
-
cursors = _props$document.cursors;
|
|
52
|
-
_this.state = {
|
|
53
|
-
slateValue: children,
|
|
54
|
-
isLoading: true
|
|
55
|
-
};
|
|
56
|
-
_this.socketManager = null;
|
|
57
|
-
_this.editor = withNodeId(editor);
|
|
58
|
-
if (props.isOpenSocket) {
|
|
59
|
-
var document = props.document,
|
|
60
|
-
config = props.config;
|
|
61
|
-
_this.editor = withSocketIO(_this.editor, {
|
|
62
|
-
document: document,
|
|
63
|
-
config: config
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
_this.editor.cursors = cursors;
|
|
67
|
-
_this.eventProxy = new EventProxy(_this.editor);
|
|
68
|
-
_this.renderElement = function (props) {
|
|
69
|
-
return renderElement(props, _this.editor);
|
|
70
|
-
};
|
|
71
|
-
_this.renderLeaf = function (props) {
|
|
72
|
-
return renderLeaf(props, _this.editor);
|
|
15
|
+
var SDocEditor = function SDocEditor(_ref) {
|
|
16
|
+
var document = _ref.document,
|
|
17
|
+
config = _ref.config;
|
|
18
|
+
// init editor
|
|
19
|
+
var editor = useMemo(function () {
|
|
20
|
+
var newEditor = withNodeId(withSocketIO(defaultEditor, {
|
|
21
|
+
document: document,
|
|
22
|
+
config: config
|
|
23
|
+
}));
|
|
24
|
+
var cursors = document.cursors;
|
|
25
|
+
newEditor.cursors = cursors || {};
|
|
26
|
+
return newEditor;
|
|
27
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
28
|
+
}, []);
|
|
29
|
+
|
|
30
|
+
// init eventHandler
|
|
31
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
32
|
+
var eventProxy = useMemo(function () {
|
|
33
|
+
return new EventProxy(editor);
|
|
34
|
+
}, []);
|
|
35
|
+
|
|
36
|
+
// useMount: init socket connection
|
|
37
|
+
useEffect(function () {
|
|
38
|
+
editor.openConnection();
|
|
39
|
+
return function () {
|
|
40
|
+
editor.closeConnection();
|
|
73
41
|
};
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
var firstNodePath = ReactEditor.findPath(editor, this.editor.children[0]);
|
|
83
|
-
focusEditor(this.editor, firstNodePath);
|
|
84
|
-
}
|
|
42
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
43
|
+
}, []);
|
|
44
|
+
|
|
45
|
+
// useMount: focus editor
|
|
46
|
+
useEffect(function () {
|
|
47
|
+
if (Node.string(editor) === '') {
|
|
48
|
+
var firstNodePath = ReactEditor.findPath(editor, editor.children[0]);
|
|
49
|
+
focusEditor(editor, firstNodePath);
|
|
85
50
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
51
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
52
|
+
}, []);
|
|
53
|
+
|
|
54
|
+
// handle placeholder
|
|
55
|
+
var onDOMBeforeInput = useCallback(function (e) {
|
|
56
|
+
if (e.data && e.data !== '') {
|
|
57
|
+
var _node$;
|
|
58
|
+
var node = Editor.parent(editor, editor.selection);
|
|
59
|
+
editor.onDOMBeforeInputId = (_node$ = node[0]) === null || _node$ === void 0 ? void 0 : _node$.id;
|
|
60
|
+
setSlateValue(_toConsumableArray(slateValue));
|
|
61
|
+
} else {
|
|
62
|
+
editor.onDOMBeforeInputId = null;
|
|
63
|
+
setSlateValue(_toConsumableArray(slateValue));
|
|
90
64
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
value: slateValue,
|
|
111
|
-
onChange: this.onChange
|
|
112
|
-
}, /*#__PURE__*/React.createElement("div", {
|
|
113
|
-
className: "article"
|
|
114
|
-
}, /*#__PURE__*/React.createElement(Editable, {
|
|
115
|
-
renderElement: this.renderElement,
|
|
116
|
-
renderLeaf: this.renderLeaf,
|
|
117
|
-
onKeyDown: this.eventProxy.onKeyDown,
|
|
118
|
-
onDOMBeforeInput: this.onDOMBeforeInput,
|
|
119
|
-
decorate: this.decorate
|
|
120
|
-
}))))));
|
|
65
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
66
|
+
}, []);
|
|
67
|
+
var _useState = useState(false),
|
|
68
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
69
|
+
isShowContextMenu = _useState2[0],
|
|
70
|
+
setContextMenu = _useState2[1];
|
|
71
|
+
var _useState3 = useState({}),
|
|
72
|
+
_useState4 = _slicedToArray(_useState3, 2),
|
|
73
|
+
menuPosition = _useState4[0],
|
|
74
|
+
setMenuPosition = _useState4[1];
|
|
75
|
+
var onContextMenu = useCallback(function (event) {
|
|
76
|
+
if (editor.isAllInTable()) {
|
|
77
|
+
event.preventDefault();
|
|
78
|
+
var contextMenuPosition = {
|
|
79
|
+
left: event.clientX,
|
|
80
|
+
top: event.clientY
|
|
81
|
+
};
|
|
82
|
+
setContextMenu(true);
|
|
83
|
+
setMenuPosition(contextMenuPosition);
|
|
121
84
|
}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
85
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
86
|
+
}, []);
|
|
87
|
+
var _useState5 = useState(document.children),
|
|
88
|
+
_useState6 = _slicedToArray(_useState5, 2),
|
|
89
|
+
slateValue = _useState6[0],
|
|
90
|
+
setSlateValue = _useState6[1];
|
|
91
|
+
var onChange = useCallback(function (slateValue) {
|
|
92
|
+
setSlateValue(slateValue);
|
|
93
|
+
setContextMenu(false);
|
|
94
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
95
|
+
}, []);
|
|
96
|
+
var _useCursors = useCursors(editor),
|
|
97
|
+
cursors = _useCursors.cursors;
|
|
98
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
|
|
99
|
+
className: "sdoc-editor-container"
|
|
100
|
+
}, /*#__PURE__*/React.createElement(Toolbar, {
|
|
101
|
+
editor: editor
|
|
102
|
+
}), /*#__PURE__*/React.createElement("div", {
|
|
103
|
+
className: "sdoc-editor-content"
|
|
104
|
+
}, /*#__PURE__*/React.createElement(SDocOutline, {
|
|
105
|
+
doc: slateValue,
|
|
106
|
+
docUuid: config.docUuid
|
|
107
|
+
}), /*#__PURE__*/React.createElement("div", {
|
|
108
|
+
className: "flex-fill o-auto"
|
|
109
|
+
}, /*#__PURE__*/React.createElement(Slate, {
|
|
110
|
+
editor: editor,
|
|
111
|
+
value: slateValue,
|
|
112
|
+
onChange: onChange
|
|
113
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
114
|
+
className: "article"
|
|
115
|
+
}, /*#__PURE__*/React.createElement(Editable, {
|
|
116
|
+
renderElement: renderElement,
|
|
117
|
+
renderLeaf: renderLeaf,
|
|
118
|
+
onKeyDown: eventProxy.onKeyDown,
|
|
119
|
+
onDOMBeforeInput: onDOMBeforeInput,
|
|
120
|
+
cursors: cursors,
|
|
121
|
+
onContextMenu: onContextMenu
|
|
122
|
+
})))))), isShowContextMenu && /*#__PURE__*/React.createElement(ContextMenu, {
|
|
123
|
+
editor: editor,
|
|
124
|
+
contextMenuPosition: menuPosition
|
|
125
|
+
}));
|
|
127
126
|
};
|
|
128
127
|
export default SDocEditor;
|
|
@@ -48,7 +48,7 @@ export var MENUS_CONFIG_MAP = (_MENUS_CONFIG_MAP = {}, _defineProperty(_MENUS_CO
|
|
|
48
48
|
}), _defineProperty(_MENUS_CONFIG_MAP, REMOVE_TABLE, {
|
|
49
49
|
id: "sdoc_".concat(REMOVE_TABLE),
|
|
50
50
|
iconClass: 'sdocfont sdoc-delete-table',
|
|
51
|
-
text: '
|
|
51
|
+
text: 'Remove_table'
|
|
52
52
|
}), _defineProperty(_MENUS_CONFIG_MAP, TEXT_STYLE, [{
|
|
53
53
|
id: ITALIC,
|
|
54
54
|
iconClass: 'sdocfont sdoc-italic',
|
|
@@ -5,13 +5,14 @@ import Plugins from './plugins';
|
|
|
5
5
|
import renderElement from './render/render-element';
|
|
6
6
|
import renderLeaf from './render/render-leaf';
|
|
7
7
|
import Toolbar from './toolbar';
|
|
8
|
+
import { ContextMenu } from './menu';
|
|
8
9
|
var baseEditor = withHistory(withReact(createEditor()));
|
|
9
|
-
var
|
|
10
|
+
var defaultEditor = Plugins.reduce(function (editor, pluginItem) {
|
|
10
11
|
var withPlugin = pluginItem.editorPlugin;
|
|
11
12
|
if (withPlugin) {
|
|
12
13
|
return withPlugin(editor);
|
|
13
14
|
}
|
|
14
15
|
return editor;
|
|
15
16
|
}, baseEditor);
|
|
16
|
-
export default
|
|
17
|
-
export { renderLeaf, renderElement, Toolbar };
|
|
17
|
+
export default defaultEditor;
|
|
18
|
+
export { renderLeaf, renderElement, Toolbar, ContextMenu };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
|
|
2
|
+
import _createClass from "@babel/runtime/helpers/esm/createClass";
|
|
3
|
+
import _inherits from "@babel/runtime/helpers/esm/inherits";
|
|
4
|
+
import _createSuper from "@babel/runtime/helpers/esm/createSuper";
|
|
5
|
+
import React, { Component } from 'react';
|
|
6
|
+
import ModalPortal from '../../../../components/modal-portal';
|
|
7
|
+
import { TablePlugin } from '../../plugins';
|
|
8
|
+
var ContextMenu = /*#__PURE__*/function (_Component) {
|
|
9
|
+
_inherits(ContextMenu, _Component);
|
|
10
|
+
var _super = _createSuper(ContextMenu);
|
|
11
|
+
function ContextMenu() {
|
|
12
|
+
var _this;
|
|
13
|
+
_classCallCheck(this, ContextMenu);
|
|
14
|
+
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
15
|
+
args[_key] = arguments[_key];
|
|
16
|
+
}
|
|
17
|
+
_this = _super.call.apply(_super, [this].concat(args));
|
|
18
|
+
_this.renderContextMenu = function () {
|
|
19
|
+
var editor = _this.props.editor;
|
|
20
|
+
if (editor.isAllInTable()) {
|
|
21
|
+
var ContextMenuComponent = TablePlugin.contextMenu;
|
|
22
|
+
return /*#__PURE__*/React.createElement(ContextMenuComponent, _this.props);
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
return _this;
|
|
26
|
+
}
|
|
27
|
+
_createClass(ContextMenu, [{
|
|
28
|
+
key: "render",
|
|
29
|
+
value: function render() {
|
|
30
|
+
return /*#__PURE__*/React.createElement(ModalPortal, {
|
|
31
|
+
className: "sdoc-context-menu"
|
|
32
|
+
}, this.renderContextMenu());
|
|
33
|
+
}
|
|
34
|
+
}]);
|
|
35
|
+
return ContextMenu;
|
|
36
|
+
}(Component);
|
|
37
|
+
export default ContextMenu;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { TABLE } from '../../constants';
|
|
2
|
-
import { TableMenu } from './menu';
|
|
2
|
+
import { TableMenu, ContextMenu } from './menu';
|
|
3
3
|
import Table from './model';
|
|
4
4
|
import withTable from './plugin';
|
|
5
5
|
import { renderTable, renderTableRow, renderTableCell } from './render-elem';
|
|
@@ -9,6 +9,7 @@ var TablePlugin = {
|
|
|
9
9
|
model: Table,
|
|
10
10
|
editorMenus: [TableMenu],
|
|
11
11
|
editorPlugin: withTable,
|
|
12
|
-
renderElements: [renderTable, renderTableRow, renderTableCell]
|
|
12
|
+
renderElements: [renderTable, renderTableRow, renderTableCell],
|
|
13
|
+
contextMenu: ContextMenu
|
|
13
14
|
};
|
|
14
15
|
export default TablePlugin;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
.sdoc-context-menu .sdoc-table-context-menu {
|
|
2
|
+
display: block;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
.sdoc-table-context-menu .insert-number {
|
|
6
|
+
margin-left: 50px;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.sdoc-table-context-menu .insert-number-input {
|
|
10
|
+
width: 36px;
|
|
11
|
+
height: 20px;
|
|
12
|
+
margin-right: .25rem;
|
|
13
|
+
padding-left: 4px;
|
|
14
|
+
padding-right: 4px;
|
|
15
|
+
text-align: center;
|
|
16
|
+
transition: none;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.sdoc-table-context-menu .dropdown-item:hover .insert-number-input {
|
|
20
|
+
background-color: transparent;
|
|
21
|
+
border: 1px solid #fff;
|
|
22
|
+
color: #fff;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.sdoc-table-context-menu .dropdown-item:disabled .insert-number-input {
|
|
26
|
+
color: #adb5bd;
|
|
27
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
|
|
2
|
+
import _createClass from "@babel/runtime/helpers/esm/createClass";
|
|
3
|
+
import _assertThisInitialized from "@babel/runtime/helpers/esm/assertThisInitialized";
|
|
4
|
+
import _inherits from "@babel/runtime/helpers/esm/inherits";
|
|
5
|
+
import _createSuper from "@babel/runtime/helpers/esm/createSuper";
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import { withTranslation } from 'react-i18next';
|
|
8
|
+
import ObjectUtils from '../../../../../utils/object-utils';
|
|
9
|
+
import { TABLE_ELEMENT, TABLE_ELEMENT_POSITION, ELEMENT_TYPE } from '../../../../constants';
|
|
10
|
+
import InsertTableElement from './insert-table-element';
|
|
11
|
+
import { getSelectedNodeByType } from '../../../../core';
|
|
12
|
+
import './index.css';
|
|
13
|
+
var ContextMenu = /*#__PURE__*/function (_React$Component) {
|
|
14
|
+
_inherits(ContextMenu, _React$Component);
|
|
15
|
+
var _super = _createSuper(ContextMenu);
|
|
16
|
+
function ContextMenu(props) {
|
|
17
|
+
var _this;
|
|
18
|
+
_classCallCheck(this, ContextMenu);
|
|
19
|
+
_this = _super.call(this, props);
|
|
20
|
+
_this.updateMenuPosition = function () {
|
|
21
|
+
var menuHeight = _this.menu.offsetHeight;
|
|
22
|
+
|
|
23
|
+
// get height of context menu when the menu is drawing completed in this page
|
|
24
|
+
// if (menuHeight === 0) {
|
|
25
|
+
// requestAnimationFrame(this.updateMenuPosition);
|
|
26
|
+
// }
|
|
27
|
+
var top = 0;
|
|
28
|
+
if (_this.position.top + menuHeight > document.body.clientHeight) {
|
|
29
|
+
top = document.body.clientHeight - menuHeight - 5;
|
|
30
|
+
} else {
|
|
31
|
+
top = _this.position.top;
|
|
32
|
+
}
|
|
33
|
+
var left = _this.position.left + 3;
|
|
34
|
+
_this.setState({
|
|
35
|
+
contextStyle: {
|
|
36
|
+
top: top,
|
|
37
|
+
left: left
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
};
|
|
41
|
+
_this.insertTableElement = function (type, position, count) {
|
|
42
|
+
var editor = _this.props.editor;
|
|
43
|
+
editor.insertTableElement(type, position, count);
|
|
44
|
+
};
|
|
45
|
+
_this.removeTableElement = function (type) {
|
|
46
|
+
var editor = _this.props.editor;
|
|
47
|
+
editor.removeTableElement(type);
|
|
48
|
+
};
|
|
49
|
+
_this.renderRemoveBtn = function (type, title) {
|
|
50
|
+
return /*#__PURE__*/React.createElement("button", {
|
|
51
|
+
onMouseDown: _this.removeTableElement.bind(_assertThisInitialized(_this), type),
|
|
52
|
+
className: "dropdown-item"
|
|
53
|
+
}, _this.props.t(title));
|
|
54
|
+
};
|
|
55
|
+
_this.state = {
|
|
56
|
+
contextStyle: {}
|
|
57
|
+
};
|
|
58
|
+
_this.position = null;
|
|
59
|
+
return _this;
|
|
60
|
+
}
|
|
61
|
+
_createClass(ContextMenu, [{
|
|
62
|
+
key: "componentDidMount",
|
|
63
|
+
value: function componentDidMount() {
|
|
64
|
+
this.position = this.props.contextMenuPosition;
|
|
65
|
+
this.updateMenuPosition();
|
|
66
|
+
}
|
|
67
|
+
}, {
|
|
68
|
+
key: "UNSAFE_componentWillReceiveProps",
|
|
69
|
+
value: function UNSAFE_componentWillReceiveProps(nextProps) {
|
|
70
|
+
var nextContextMenuPosition = nextProps.contextMenuPosition;
|
|
71
|
+
if (!ObjectUtils.isSameObject(nextContextMenuPosition, this.props.contextMenuPosition)) {
|
|
72
|
+
this.position = nextContextMenuPosition;
|
|
73
|
+
this.updateMenuPosition();
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}, {
|
|
77
|
+
key: "componentWillUnmount",
|
|
78
|
+
value: function componentWillUnmount() {
|
|
79
|
+
this.menu = null;
|
|
80
|
+
}
|
|
81
|
+
}, {
|
|
82
|
+
key: "render",
|
|
83
|
+
value: function render() {
|
|
84
|
+
var _this2 = this;
|
|
85
|
+
var contextStyle = this.state.contextStyle;
|
|
86
|
+
var editor = this.props.editor;
|
|
87
|
+
var currentTable = getSelectedNodeByType(editor, ELEMENT_TYPE.TABLE);
|
|
88
|
+
var currentRow = getSelectedNodeByType(editor, ELEMENT_TYPE.TABLE_ROW);
|
|
89
|
+
var currentRowsCount = currentTable.children.length;
|
|
90
|
+
var currentColumnsCount = currentRow.children.length;
|
|
91
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
92
|
+
style: contextStyle,
|
|
93
|
+
ref: function ref(_ref) {
|
|
94
|
+
return _this2.menu = _ref;
|
|
95
|
+
},
|
|
96
|
+
className: "sdoc-table-context-menu dropdown-menu"
|
|
97
|
+
}, /*#__PURE__*/React.createElement(InsertTableElement, {
|
|
98
|
+
type: TABLE_ELEMENT.ROW,
|
|
99
|
+
currentCount: currentRowsCount,
|
|
100
|
+
position: TABLE_ELEMENT_POSITION.BEFORE,
|
|
101
|
+
insertTableElement: this.insertTableElement
|
|
102
|
+
}), /*#__PURE__*/React.createElement(InsertTableElement, {
|
|
103
|
+
type: TABLE_ELEMENT.ROW,
|
|
104
|
+
currentCount: currentRowsCount,
|
|
105
|
+
position: TABLE_ELEMENT_POSITION.AFTER,
|
|
106
|
+
insertTableElement: this.insertTableElement
|
|
107
|
+
}), /*#__PURE__*/React.createElement(InsertTableElement, {
|
|
108
|
+
type: TABLE_ELEMENT.COLUMN,
|
|
109
|
+
currentCount: currentColumnsCount,
|
|
110
|
+
position: TABLE_ELEMENT_POSITION.BEFORE,
|
|
111
|
+
insertTableElement: this.insertTableElement
|
|
112
|
+
}), /*#__PURE__*/React.createElement(InsertTableElement, {
|
|
113
|
+
type: TABLE_ELEMENT.COLUMN,
|
|
114
|
+
currentCount: currentColumnsCount,
|
|
115
|
+
position: TABLE_ELEMENT_POSITION.AFTER,
|
|
116
|
+
insertTableElement: this.insertTableElement
|
|
117
|
+
}), /*#__PURE__*/React.createElement("div", {
|
|
118
|
+
className: 'seafile-divider dropdown-divider'
|
|
119
|
+
}), this.renderRemoveBtn(TABLE_ELEMENT.ROW, 'Remove_Row'), this.renderRemoveBtn(TABLE_ELEMENT.COLUMN, 'Remove_Column'), this.renderRemoveBtn(TABLE_ELEMENT.TABLE, 'Remove_table'));
|
|
120
|
+
}
|
|
121
|
+
}]);
|
|
122
|
+
return ContextMenu;
|
|
123
|
+
}(React.Component);
|
|
124
|
+
export default withTranslation('sdoc-editor')(ContextMenu);
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
|
|
2
|
+
import _createClass from "@babel/runtime/helpers/esm/createClass";
|
|
3
|
+
import _inherits from "@babel/runtime/helpers/esm/inherits";
|
|
4
|
+
import _createSuper from "@babel/runtime/helpers/esm/createSuper";
|
|
5
|
+
import React, { Component } from 'react';
|
|
6
|
+
import { withTranslation } from 'react-i18next';
|
|
7
|
+
import { Input } from 'reactstrap';
|
|
8
|
+
import isHotkey from 'is-hotkey';
|
|
9
|
+
import { TABLE_ELEMENT, TABLE_ELEMENT_POSITION } from '../../../../constants';
|
|
10
|
+
import { TABLE_MAX_COLUMNS, TABLE_MAX_ROWS } from '../../constants';
|
|
11
|
+
var InsertTableElement = /*#__PURE__*/function (_Component) {
|
|
12
|
+
_inherits(InsertTableElement, _Component);
|
|
13
|
+
var _super = _createSuper(InsertTableElement);
|
|
14
|
+
function InsertTableElement(props) {
|
|
15
|
+
var _this;
|
|
16
|
+
_classCallCheck(this, InsertTableElement);
|
|
17
|
+
_this = _super.call(this, props);
|
|
18
|
+
_this.insertTableElement = function () {
|
|
19
|
+
var _this$props = _this.props,
|
|
20
|
+
type = _this$props.type,
|
|
21
|
+
position = _this$props.position;
|
|
22
|
+
var count = _this.state.count;
|
|
23
|
+
_this.props.insertTableElement(type, position, count);
|
|
24
|
+
};
|
|
25
|
+
_this.getTip = function () {
|
|
26
|
+
var _this$props2 = _this.props,
|
|
27
|
+
type = _this$props2.type,
|
|
28
|
+
position = _this$props2.position,
|
|
29
|
+
t = _this$props2.t;
|
|
30
|
+
if (type === TABLE_ELEMENT.ROW) {
|
|
31
|
+
return position === TABLE_ELEMENT_POSITION.AFTER ? t('Insert_below') : t('Insert_above');
|
|
32
|
+
}
|
|
33
|
+
return position === TABLE_ELEMENT_POSITION.AFTER ? t('Insert_on_the_right') : t('Insert_on_the_left');
|
|
34
|
+
};
|
|
35
|
+
_this.onKeyDown = function (event) {
|
|
36
|
+
if (isHotkey('enter', event)) {
|
|
37
|
+
event.preventDefault();
|
|
38
|
+
_this.insertTableElement();
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
_this.onChange = function (event) {
|
|
43
|
+
var value = event.target.value || '0';
|
|
44
|
+
var newValue = value ? value.replace(/[^\d,]/g, '') : value;
|
|
45
|
+
if (newValue === _this.state.count) return;
|
|
46
|
+
var currentCount = _this.props.currentCount;
|
|
47
|
+
var numberValue = parseInt(newValue);
|
|
48
|
+
if (currentCount + numberValue > _this.maxCount) {
|
|
49
|
+
_this.setState({
|
|
50
|
+
count: _this.maxCount - currentCount
|
|
51
|
+
});
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
_this.setState({
|
|
55
|
+
count: numberValue
|
|
56
|
+
});
|
|
57
|
+
};
|
|
58
|
+
_this.state = {
|
|
59
|
+
count: 1
|
|
60
|
+
};
|
|
61
|
+
_this.maxCount = props.type === TABLE_ELEMENT.ROW ? TABLE_MAX_ROWS : TABLE_MAX_COLUMNS;
|
|
62
|
+
return _this;
|
|
63
|
+
}
|
|
64
|
+
_createClass(InsertTableElement, [{
|
|
65
|
+
key: "render",
|
|
66
|
+
value: function render() {
|
|
67
|
+
var count = this.state.count;
|
|
68
|
+
var _this$props3 = this.props,
|
|
69
|
+
t = _this$props3.t,
|
|
70
|
+
type = _this$props3.type,
|
|
71
|
+
currentCount = _this$props3.currentCount;
|
|
72
|
+
var isDisabled = currentCount >= this.maxCount;
|
|
73
|
+
return /*#__PURE__*/React.createElement("button", {
|
|
74
|
+
onMouseDown: this.insertTableElement,
|
|
75
|
+
className: "dropdown-item d-flex align-items-center justify-content-between",
|
|
76
|
+
disabled: isDisabled
|
|
77
|
+
}, this.getTip(), /*#__PURE__*/React.createElement("div", {
|
|
78
|
+
className: "insert-number d-flex align-items-center"
|
|
79
|
+
}, /*#__PURE__*/React.createElement(Input, {
|
|
80
|
+
disabled: isDisabled,
|
|
81
|
+
className: "insert-number-input",
|
|
82
|
+
onMouseDown: function onMouseDown(e) {
|
|
83
|
+
e.stopPropagation();
|
|
84
|
+
},
|
|
85
|
+
onKeyDown: this.onKeyDown,
|
|
86
|
+
value: count,
|
|
87
|
+
onChange: this.onChange
|
|
88
|
+
}), /*#__PURE__*/React.createElement("span", null, type === TABLE_ELEMENT.ROW ? t('row(s)') : t('column(s)'))));
|
|
89
|
+
}
|
|
90
|
+
}]);
|
|
91
|
+
return InsertTableElement;
|
|
92
|
+
}(Component);
|
|
93
|
+
export default withTranslation('sdoc-editor')(InsertTableElement);
|