@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.
Files changed (40) hide show
  1. package/dist/basic-sdk/cursor/helper.js +7 -9
  2. package/dist/basic-sdk/cursor/use-cursors.js +24 -0
  3. package/dist/basic-sdk/editor.js +113 -114
  4. package/dist/basic-sdk/extension/constants/index.js +1 -1
  5. package/dist/basic-sdk/extension/index.js +4 -3
  6. package/dist/basic-sdk/extension/menu/context-menu/index.css +1 -0
  7. package/dist/basic-sdk/extension/menu/context-menu/index.js +37 -0
  8. package/dist/basic-sdk/extension/menu/index.js +2 -1
  9. package/dist/basic-sdk/extension/plugins/table/index.js +3 -2
  10. package/dist/basic-sdk/extension/plugins/table/menu/context-menu/index.css +27 -0
  11. package/dist/basic-sdk/extension/plugins/table/menu/context-menu/index.js +124 -0
  12. package/dist/basic-sdk/extension/plugins/table/menu/context-menu/insert-table-element.js +93 -0
  13. package/dist/basic-sdk/extension/plugins/table/menu/index.js +2 -1
  14. package/dist/basic-sdk/extension/plugins/table/plugin.js +19 -12
  15. package/dist/basic-sdk/extension/plugins/table/render/render-table/index.css +8 -0
  16. package/dist/basic-sdk/extension/render/render-element.js +6 -1
  17. package/dist/basic-sdk/extension/render/render-leaf.js +7 -1
  18. package/dist/basic-sdk/index.js +1 -1
  19. package/dist/basic-sdk/socket/helpers.js +10 -8
  20. package/dist/basic-sdk/socket/socket-client.js +14 -4
  21. package/dist/basic-sdk/socket/socket-manager.js +14 -7
  22. package/dist/basic-sdk/socket/with-socket-io.js +11 -2
  23. package/dist/basic-sdk/utils/diff.js +1 -0
  24. package/dist/components/doc-operations/style.css +1 -0
  25. package/dist/components/modal-portal.js +41 -0
  26. package/dist/pages/simple-editor.js +0 -4
  27. package/package.json +2 -2
  28. package/public/locales/cs/sdoc-editor.json +1 -1
  29. package/public/locales/de/sdoc-editor.json +1 -1
  30. package/public/locales/en/sdoc-editor.json +8 -2
  31. package/public/locales/es/sdoc-editor.json +1 -1
  32. package/public/locales/es-AR/sdoc-editor.json +1 -1
  33. package/public/locales/es-MX/sdoc-editor.json +1 -1
  34. package/public/locales/fr/sdoc-editor.json +1 -1
  35. package/public/locales/it/sdoc-editor.json +1 -1
  36. package/public/locales/ru/sdoc-editor.json +1 -1
  37. package/public/locales/zh-CN/sdoc-editor.json +8 -2
  38. package/dist/basic-sdk/cursor/decorate-cursors.js +0 -32
  39. package/dist/basic-sdk/decorates/index.js +0 -25
  40. 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, operations, user, selection, cursorData) {
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
- var oldCursor = editor.cursors[clientId] ? editor.cursors[clientId] : {};
14
- var lastCursorOp = cursorOps[cursorOps.length - 1];
15
- if (selection) {
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
+ };
@@ -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 _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
3
- import _createClass from "@babel/runtime/helpers/esm/createClass";
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 { Editor } from '@seafile/slate';
10
- import editor, { renderLeaf, renderElement, Toolbar } from './extension';
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 { focusEditor } from './extension/core';
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 = /*#__PURE__*/function (_React$Component) {
20
- _inherits(SDocEditor, _React$Component);
21
- var _super = _createSuper(SDocEditor);
22
- function SDocEditor(props) {
23
- var _this;
24
- _classCallCheck(this, SDocEditor);
25
- _this = _super.call(this, props);
26
- _this.onChange = function (slateValue) {
27
- var onValueChanged = _this.props.onValueChanged;
28
- _this.setState({
29
- slateValue: slateValue
30
- });
31
- onValueChanged && onValueChanged(slateValue);
32
- };
33
- _this.onDOMBeforeInput = function (e) {
34
- var slateValue = _this.state.slateValue;
35
- if (e.data && e.data !== '') {
36
- var _node$;
37
- var node = Editor.parent(_this.editor, editor.selection);
38
- _this.editor.onDOMBeforeInputId = (_node$ = node[0]) === null || _node$ === void 0 ? void 0 : _node$.id;
39
- _this.setState({
40
- slateValue: _toConsumableArray(slateValue)
41
- });
42
- } else {
43
- _this.editor.onDOMBeforeInputId = null;
44
- _this.setState({
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
- _this.decorate = uiDecorate(_this.editor);
75
- return _this;
76
- }
77
- _createClass(SDocEditor, [{
78
- key: "componentDidMount",
79
- value: function componentDidMount() {
80
- this.editor.openConnection();
81
- if (Node.string(editor) === '') {
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
- key: "componentWillUnmount",
88
- value: function componentWillUnmount() {
89
- this.editor.closeConnection();
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
- key: "render",
93
- value: function render() {
94
- var slateValue = this.state.slateValue;
95
- var config = this.props.config;
96
- var docUuid = config.docUuid;
97
- return /*#__PURE__*/React.createElement("div", {
98
- className: "sdoc-editor-container"
99
- }, /*#__PURE__*/React.createElement(Toolbar, {
100
- editor: this.editor
101
- }), /*#__PURE__*/React.createElement("div", {
102
- className: "sdoc-editor-content"
103
- }, /*#__PURE__*/React.createElement(SDocOutline, {
104
- doc: slateValue,
105
- docUuid: docUuid
106
- }), /*#__PURE__*/React.createElement("div", {
107
- className: "flex-fill o-auto"
108
- }, /*#__PURE__*/React.createElement(Slate, {
109
- editor: this.editor,
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
- return SDocEditor;
124
- }(React.Component);
125
- SDocEditor.defaultProps = {
126
- isOpenSocket: false
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: 'remove_table'
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 editor2 = Plugins.reduce(function (editor, pluginItem) {
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 editor2;
17
- export { renderLeaf, renderElement, Toolbar };
17
+ export default defaultEditor;
18
+ export { renderLeaf, renderElement, Toolbar, ContextMenu };
@@ -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,4 +1,5 @@
1
1
  import MenuGroup from './menu-group';
2
2
  import MenuItem from './menu-item';
3
+ import ContextMenu from './context-menu';
3
4
  import './menu.css';
4
- export { MenuGroup, MenuItem };
5
+ export { MenuGroup, MenuItem, 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);
@@ -1,3 +1,4 @@
1
1
  import TableMenu from './table-menu';
2
2
  import ActiveTableMenu from './active-table-menu';
3
- export { TableMenu, ActiveTableMenu };
3
+ import ContextMenu from './context-menu';
4
+ export { TableMenu, ActiveTableMenu, ContextMenu };