@seafile/sdoc-editor 0.4.11 → 0.4.13

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 (22) hide show
  1. package/dist/basic-sdk/assets/css/layout.css +1 -1
  2. package/dist/basic-sdk/extension/plugins/blockquote/render-elem.js +1 -2
  3. package/dist/basic-sdk/extension/plugins/callout/plugin.js +21 -1
  4. package/dist/basic-sdk/extension/plugins/callout/render-elem/index.js +0 -1
  5. package/dist/basic-sdk/extension/plugins/check-list/render-elem.js +1 -2
  6. package/dist/basic-sdk/extension/plugins/code-block/render-elem.js +1 -2
  7. package/dist/basic-sdk/extension/plugins/header/render-elem.js +2 -6
  8. package/dist/basic-sdk/extension/plugins/image/hover-menu/index.js +4 -1
  9. package/dist/basic-sdk/extension/plugins/list/render-elem.js +2 -5
  10. package/dist/basic-sdk/extension/plugins/paragraph/render-elem.js +1 -4
  11. package/dist/basic-sdk/extension/plugins/table/helpers.js +93 -0
  12. package/dist/basic-sdk/extension/plugins/table/plugin.js +33 -3
  13. package/dist/basic-sdk/extension/plugins/table/render/index.js +25 -28
  14. package/dist/basic-sdk/extension/plugins/table/render/resize-handlers/column-resize-handler.js +11 -3
  15. package/dist/basic-sdk/extension/plugins/table/render/resize-handlers/first-column-left-resize-handler.js +11 -3
  16. package/dist/basic-sdk/extension/plugins/table/render/resize-handlers/index.js +16 -8
  17. package/dist/basic-sdk/extension/plugins/table/render/resize-handlers/row-resize-handler.js +11 -6
  18. package/dist/basic-sdk/extension/plugins/table/render/table-root.js +0 -1
  19. package/dist/basic-sdk/extension/render/helper.js +1 -0
  20. package/dist/basic-sdk/extension/toolbar/side-toolbar/transform-menus.js +10 -2
  21. package/dist/basic-sdk/utils/event-handler.js +1 -0
  22. package/package.json +1 -1
@@ -24,7 +24,7 @@
24
24
  display: flex;
25
25
  flex-direction: row-reverse;
26
26
  position: absolute;
27
- right: 20px;
27
+ right: 8px;
28
28
  border-right: none;
29
29
  }
30
30
 
@@ -9,8 +9,7 @@ const renderBlockquote = (props, editor) => {
9
9
  textAlign: element.align
10
10
  };
11
11
  return /*#__PURE__*/React.createElement("blockquote", Object.assign({
12
- "data-id": element.id,
13
- "data-root": "true"
12
+ "data-id": element.id
14
13
  }, attributes, {
15
14
  style: style
16
15
  }), children);
@@ -1,4 +1,5 @@
1
1
  import isHotkey from 'is-hotkey';
2
+ import { Editor, Transforms } from '@seafile/slate';
2
3
  import { PARAGRAPH, INSERT_POSITION, CODE_BLOCK } from '../../constants';
3
4
  import { isSelectionAtBlockStart } from '../../core';
4
5
  import { getCalloutEntry, isCalloutContentEmpty, unwrapCallout } from './helper';
@@ -52,7 +53,9 @@ const withCallout = editor => {
52
53
  return insertFragment(data);
53
54
  };
54
55
  newEditor.onHotKeyDown = event => {
55
- if (getCalloutEntry(editor)) {
56
+ const calloutEntry = getCalloutEntry(editor);
57
+ if (calloutEntry) {
58
+ const [, calloutPath] = calloutEntry;
56
59
  // Close color picker
57
60
  const eventBus = EventBus.getInstance();
58
61
  eventBus.dispatch(INTERNAL_EVENT.CLOSE_CALLOUT_COLOR_PICKER);
@@ -60,9 +63,26 @@ const withCallout = editor => {
60
63
  insertElement(newEditor, PARAGRAPH, INSERT_POSITION.AFTER);
61
64
  return true;
62
65
  }
66
+ if (isHotkey('mod+a', event)) {
67
+ event.preventDefault();
68
+ try {
69
+ const startPoint = Editor.start(newEditor, calloutPath);
70
+ const endPoint = Editor.end(newEditor, calloutPath);
71
+ const selectRange = Editor.range(newEditor, startPoint, endPoint);
72
+ Transforms.select(newEditor, selectRange);
73
+ return true;
74
+ } catch (error) {
75
+ return true;
76
+ }
77
+ }
63
78
  }
64
79
  return onHotKeyDown && onHotKeyDown(event);
65
80
  };
81
+ newEditor.onCopy = event => {
82
+ if (getCalloutEntry(editor)) {
83
+ event.stopPropagation();
84
+ }
85
+ };
66
86
  return newEditor;
67
87
  };
68
88
  export default withCallout;
@@ -100,7 +100,6 @@ const renderCallout = (_ref, editor) => {
100
100
  }, [editor, element, isFocusOnCallout]);
101
101
  return /*#__PURE__*/React.createElement("div", Object.assign({}, attributes, {
102
102
  "data-id": element.id,
103
- "data-root": "true",
104
103
  className: "sdoc-callout-white-wrapper",
105
104
  onMouseLeave: handleCloseColorSelector
106
105
  }), /*#__PURE__*/React.createElement("div", {
@@ -33,8 +33,7 @@ class CheckListItem extends React.PureComponent {
33
33
  textAlign: align
34
34
  };
35
35
  return /*#__PURE__*/React.createElement("div", Object.assign({
36
- "data-id": id,
37
- "data-root": "true"
36
+ "data-id": id
38
37
  }, attributes, {
39
38
  className: "sdoc-checkbox-container ".concat(attributes.className),
40
39
  style: style
@@ -134,8 +134,7 @@ const CodeBlock = _ref => {
134
134
  EventBus.getInstance().dispatch(INTERNAL_EVENT.UPDATE_SEARCH_REPLACE_HIGHLIGHT);
135
135
  };
136
136
  return /*#__PURE__*/React.createElement("div", Object.assign({
137
- "data-id": element.id,
138
- "data-root": "true"
137
+ "data-id": element.id
139
138
  }, attributes, {
140
139
  className: "sdoc-code-block-container ".concat(attributes.className),
141
140
  onClick: onFocusCodeBlock,
@@ -14,8 +14,7 @@ export const renderTitle = (props, editor) => {
14
14
  textAlign: element.align
15
15
  };
16
16
  return /*#__PURE__*/React.createElement("div", Object.assign({
17
- "data-id": element.id,
18
- "data-root": "true"
17
+ "data-id": element.id
19
18
  }, attributes, {
20
19
  className: "sdoc-header-title ".concat(attributes.className),
21
20
  style: _objectSpread({}, style)
@@ -33,8 +32,7 @@ export const renderSubtitle = (props, editor) => {
33
32
  textAlign: element.align
34
33
  };
35
34
  return /*#__PURE__*/React.createElement("div", Object.assign({
36
- "data-id": element.id,
37
- "data-root": "true"
35
+ "data-id": element.id
38
36
  }, attributes, {
39
37
  className: "sdoc-header-subtitle ".concat(attributes.className),
40
38
  style: _objectSpread({}, style)
@@ -65,8 +63,6 @@ export const renderHeader = (props, editor) => {
65
63
  return /*#__PURE__*/React.createElement("div", Object.assign({
66
64
  "data-id": element.id,
67
65
  id: element.id // used for click left outline item, page scroll this element
68
- ,
69
- "data-root": "true"
70
66
  }, attributes, {
71
67
  className: "sdoc-header-".concat(level, " ").concat(attributes.className),
72
68
  style: _objectSpread({
@@ -89,7 +89,10 @@ const ImageHoverMenu = _ref => {
89
89
  at: [p]
90
90
  });
91
91
  p = p + 1;
92
- if (!afterLeaf.every(item => item.text.length === 0)) {
92
+ if (!afterLeaf.every(item => {
93
+ var _item$text;
94
+ return (item === null || item === void 0 ? void 0 : (_item$text = item.text) === null || _item$text === void 0 ? void 0 : _item$text.length) === 0;
95
+ })) {
93
96
  afterNode = generateEmptyElement(PARAGRAPH);
94
97
  afterNode.children = afterLeaf;
95
98
  Transforms.insertNodes(editor, afterNode, {
@@ -10,7 +10,6 @@ const renderList = (props, editor) => {
10
10
  const Tag = node.type === ORDERED_LIST ? 'ol' : 'ul';
11
11
  return /*#__PURE__*/React.createElement(Tag, Object.assign({
12
12
  "data-id": node.id,
13
- "data-root": "true",
14
13
  className: "list-container d-flex flex-column"
15
14
  }, attributes), children);
16
15
  };
@@ -36,8 +35,7 @@ const renderListItem = (props, editor) => {
36
35
  }
37
36
  const isBlod = element.children[0].children.every(item => item.bold === true);
38
37
  return /*#__PURE__*/React.createElement("li", Object.assign({
39
- "data-id": element.id,
40
- "data-root": "true"
38
+ "data-id": element.id
41
39
  }, attributes, {
42
40
  className: classnames(className, {
43
41
  'sdoc-li-blod': isBlod
@@ -51,8 +49,7 @@ const renderListLic = (props, editor) => {
51
49
  element
52
50
  } = props;
53
51
  return /*#__PURE__*/React.createElement("div", Object.assign({
54
- "data-id": element.id,
55
- "data-root": "true"
52
+ "data-id": element.id
56
53
  }, attributes), children);
57
54
  };
58
55
  export { renderList, renderListItem, renderListLic };
@@ -26,12 +26,9 @@ const Paragraph = _ref => {
26
26
  textAlign: element.align,
27
27
  paddingLeft: indent ? '28px' : ''
28
28
  };
29
- const newAttributes = _objectSpread(_objectSpread({}, attributes), typeof attributes.onMouseEnter === 'function' && {
30
- 'data-root': 'true'
31
- });
32
29
  return /*#__PURE__*/React.createElement("p", Object.assign({
33
30
  "data-id": element.id
34
- }, newAttributes, {
31
+ }, attributes, {
35
32
  style: _objectSpread({
36
33
  position: isShowPlaceHolder ? 'relative' : ''
37
34
  }, style)
@@ -1398,4 +1398,97 @@ export const getCellHighlightClassName = (primaryColorClassName, rowIndex) => {
1398
1398
  className = TABLE_ALTERNATE_HIGHLIGHT_CLASS_MAP[primaryColorClassName];
1399
1399
  }
1400
1400
  return className;
1401
+ };
1402
+ export const getRowBottomPositions = (editor, rows) => {
1403
+ const recorder = [];
1404
+ let bottomPosition = 0;
1405
+ rows.forEach(row => {
1406
+ let cellHeight;
1407
+ row.children.forEach(cell => {
1408
+ const currentCellHeight = ReactEditor.toDOMNode(editor, cell).getBoundingClientRect().height;
1409
+ if (!cellHeight || currentCellHeight < cellHeight) cellHeight = currentCellHeight;
1410
+ });
1411
+ bottomPosition += cellHeight;
1412
+ recorder.push(bottomPosition);
1413
+ });
1414
+ return recorder;
1415
+ };
1416
+ export const focusClosestCellWhenJustifyCellSize = _ref => {
1417
+ let {
1418
+ editor,
1419
+ rowIndex,
1420
+ columnIndex,
1421
+ table,
1422
+ mouseDownInfo,
1423
+ rowBottoms
1424
+ } = _ref;
1425
+ if (!editor) return;
1426
+ const {
1427
+ columns
1428
+ } = table;
1429
+ // Get cursor position in table, calculate columnIndex and rowIndex
1430
+ const tableDom = ReactEditor.toDOMNode(editor, table);
1431
+ const {
1432
+ left,
1433
+ top
1434
+ } = tableDom.getBoundingClientRect();
1435
+ const {
1436
+ positionY,
1437
+ positionX
1438
+ } = mouseDownInfo;
1439
+ const tableScrollWrapper = document.querySelector('.sdoc-table-scroll-wrapper');
1440
+ const scrollX = tableScrollWrapper.scrollLeft;
1441
+ const tableInnerX = positionX - left + scrollX;
1442
+ const tableInnerY = positionY - top;
1443
+ // Calculate columnIndex
1444
+ if (columnIndex === undefined) {
1445
+ let passedColumnsWidth = 0;
1446
+ columns.some((_ref2, index) => {
1447
+ let {
1448
+ width
1449
+ } = _ref2;
1450
+ passedColumnsWidth += width;
1451
+ if (passedColumnsWidth > tableInnerX) {
1452
+ columnIndex = index;
1453
+ return true;
1454
+ }
1455
+ return false;
1456
+ });
1457
+ }
1458
+ // Calculate rowIndex
1459
+ if (rowIndex === undefined) {
1460
+ rowBottoms.some((bottom, index) => {
1461
+ if (bottom >= tableInnerY) {
1462
+ rowIndex = index;
1463
+ return true;
1464
+ }
1465
+ return false;
1466
+ });
1467
+ }
1468
+ // Correct focus position
1469
+ const is_combined = table.children[rowIndex].children[columnIndex].is_combined;
1470
+ if (is_combined) {
1471
+ for (let i = columnIndex - 1; i >= 0; i--) {
1472
+ const {
1473
+ is_combined: ci_is_combined,
1474
+ colspan: ci_colspan
1475
+ } = table.children[rowIndex].children[i];
1476
+ if (!ci_is_combined && ci_colspan && i + ci_colspan - 1 >= columnIndex) {
1477
+ columnIndex = i;
1478
+ break;
1479
+ }
1480
+ }
1481
+ for (let j = rowIndex - 1; j >= 0; j--) {
1482
+ const {
1483
+ is_combined: ri_is_combined,
1484
+ rowspan: ri_rowspan
1485
+ } = table.children[j].children[columnIndex];
1486
+ if (!ri_is_combined && ri_rowspan && j + ri_rowspan - 1 >= rowIndex) {
1487
+ rowIndex = j;
1488
+ break;
1489
+ }
1490
+ }
1491
+ }
1492
+ const focusPath = ReactEditor.findPath(editor, table.children[rowIndex].children[columnIndex]);
1493
+ focusEditor(editor, Editor.end(editor, focusPath));
1401
1494
  };
@@ -88,17 +88,47 @@ const withTable = editor => {
88
88
  if (selection) {
89
89
  const before = Editor.before(newEditor, selection);
90
90
  if (before) {
91
- // If the current is not a table and the previous one is a table, no deletion will be performed. Otherwise, the last cell of the table will be deleted
92
- // If deleting node is empty check-list, order-list, unordered-list, change to paragraph
93
91
  const isTableOnBeforeLocation = isTableLocation(newEditor, before);
94
92
  const isTableOnCurSelection = isTableLocation(newEditor, selection);
93
+ // If the current is not a table and the previous one is a table.
95
94
  if (isTableOnBeforeLocation && !isTableOnCurSelection) {
96
- const transformTypes = [CHECK_LIST_ITEM, ORDERED_LIST, UNORDERED_LIST];
97
95
  const [currentNodeEntry] = Editor.nodes(editor, {
98
96
  match: n => Element.isElement(n) && !Editor.parent(n, ReactEditor.findPath(editor, n))[1].length
99
97
  });
100
98
  if (!currentNodeEntry) return;
101
99
  const [currentNode, currentPath] = Array.from(currentNodeEntry);
100
+
101
+ // If the current is paragraph.
102
+ if (currentNode.type === PARAGRAPH) {
103
+ const {
104
+ path
105
+ } = before;
106
+ Transforms.select(editor, {
107
+ anchor: {
108
+ offset: 0,
109
+ path: [path[0], 0, 0, 0]
110
+ },
111
+ focus: {
112
+ offset: 0,
113
+ path: [path[0], 0, 0, 0]
114
+ }
115
+ });
116
+ const beforeTable = Editor.node(editor, [path[0]]);
117
+ const beforeRow = Editor.node(editor, [path[0], path[1]]);
118
+ const tableSize = [beforeTable[0].children.length, beforeRow[0].children.length];
119
+ const allTableRange = {
120
+ minRowIndex: 0,
121
+ maxRowIndex: tableSize[0] - 1,
122
+ minColIndex: 0,
123
+ maxColIndex: tableSize[1] - 1
124
+ };
125
+ newEditor.tableSelectedRange = allTableRange;
126
+ eventBus.dispatch(INTERNAL_EVENT.SET_TABLE_SELECT_RANGE, beforeTable[0], allTableRange);
127
+ return;
128
+ }
129
+
130
+ // If deleting node is empty check-list, order-list, unordered-list, change to paragraph
131
+ const transformTypes = [CHECK_LIST_ITEM, ORDERED_LIST, UNORDERED_LIST];
102
132
  if (transformTypes.includes(currentNode.type)) {
103
133
  Transforms.delete(newEditor, {
104
134
  at: currentPath
@@ -59,19 +59,33 @@ const Table = _ref => {
59
59
 
60
60
  // eslint-disable-next-line react-hooks/exhaustive-deps
61
61
  }, []);
62
+ const setSelectedRangeByClick = useCallback(range => {
63
+ setSelectedRange(range);
64
+ setTableSelectedRange(editor, range);
65
+ const {
66
+ maxRowIndex,
67
+ maxColIndex
68
+ } = range;
69
+ const selection = {
70
+ offset: 0,
71
+ path: [...path, maxRowIndex, maxColIndex, 0]
72
+ };
73
+ Transforms.setSelection(editor, {
74
+ anchor: selection,
75
+ focus: selection
76
+ });
77
+ // eslint-disable-next-line react-hooks/exhaustive-deps
78
+ }, [editor, path]);
62
79
  useEffect(() => {
63
- if (isSelected) {
64
- const eventBus = EventBus.getInstance();
65
- const cancelTableSelectRangeSubscribe = eventBus.subscribe(INTERNAL_EVENT.CANCEL_TABLE_SELECT_RANGE, clearRange);
66
- const setTableSelectRangeSubscribe = eventBus.subscribe(INTERNAL_EVENT.SET_TABLE_SELECT_RANGE, setRange);
67
- return () => {
68
- cancelTableSelectRangeSubscribe();
69
- setTableSelectRangeSubscribe();
70
- };
71
- }
72
-
80
+ const eventBus = EventBus.getInstance();
81
+ const cancelTableSelectRangeSubscribe = eventBus.subscribe(INTERNAL_EVENT.CANCEL_TABLE_SELECT_RANGE, clearRange);
82
+ const setTableSelectRangeSubscribe = eventBus.subscribe(INTERNAL_EVENT.SET_TABLE_SELECT_RANGE, setRange);
83
+ return () => {
84
+ cancelTableSelectRangeSubscribe();
85
+ setTableSelectRangeSubscribe();
86
+ };
73
87
  // eslint-disable-next-line react-hooks/exhaustive-deps
74
- }, [isSelected]);
88
+ }, []);
75
89
  useEffect(() => {
76
90
  setColumns(getTableColumns(editor, element));
77
91
  if (isSettingSelectRange) {
@@ -150,23 +164,6 @@ const Table = _ref => {
150
164
 
151
165
  // eslint-disable-next-line react-hooks/exhaustive-deps
152
166
  }, []);
153
- const setSelectedRangeByClick = useCallback(range => {
154
- setSelectedRange(range);
155
- setTableSelectedRange(editor, range);
156
- const {
157
- maxRowIndex,
158
- maxColIndex
159
- } = range;
160
- const selection = {
161
- offset: 0,
162
- path: [...path, maxRowIndex, maxColIndex, 0]
163
- };
164
- Transforms.setSelection(editor, {
165
- anchor: selection,
166
- focus: selection
167
- });
168
- // eslint-disable-next-line react-hooks/exhaustive-deps
169
- }, [editor, path]);
170
167
  const tableContainerClassName = classnames('sdoc-table-container position-relative', attributes.className, className, {
171
168
  'sdoc-table-selected': isSelected,
172
169
  'sdoc-table-selected-range': !ObjectUtils.isSameObject(selectedRange, EMPTY_SELECTED_RANGE)
@@ -4,14 +4,15 @@ import { useSlateStatic } from '@seafile/slate-react';
4
4
  import classnames from 'classnames';
5
5
  import { useTableRootContext } from '../hooks';
6
6
  import { TABLE_CELL_MIN_WIDTH } from '../../constants';
7
- import { getTableColumns, updateColumnWidth } from '../../helpers';
7
+ import { getTableColumns, updateColumnWidth, focusClosestCellWhenJustifyCellSize } from '../../helpers';
8
8
  import { eventStopPropagation, getMouseDownInfo, getMouseMoveInfo, registerResizeEvents, unregisterResizeEvents } from '../../../../../utils/mouse-event';
9
9
  const ColumnResizeHandler = _ref => {
10
10
  let {
11
11
  column,
12
12
  left: initLeft,
13
13
  element,
14
- index
14
+ index,
15
+ rowBottoms
15
16
  } = _ref;
16
17
  const editor = useSlateStatic();
17
18
  const resizeHandler = useRef(null);
@@ -85,6 +86,13 @@ const ColumnResizeHandler = _ref => {
85
86
  });
86
87
  }
87
88
  updateColumnWidth(editor, element, newColumns);
89
+ focusClosestCellWhenJustifyCellSize({
90
+ editor,
91
+ columnIndex: index,
92
+ table: element,
93
+ mouseDownInfo,
94
+ rowBottoms
95
+ });
88
96
  };
89
97
  registerResizeEvents({
90
98
  'mousemove': onMouseMove,
@@ -98,7 +106,7 @@ const ColumnResizeHandler = _ref => {
98
106
  };
99
107
 
100
108
  // eslint-disable-next-line react-hooks/exhaustive-deps
101
- }, [isResizing, mouseDownInfo, left, width, column, editor, element, index, initLeft]);
109
+ }, [isResizing, mouseDownInfo, left, width, column, editor, element, index, initLeft, rowBottoms]);
102
110
  return /*#__PURE__*/React.createElement("div", {
103
111
  className: classnames('table-cell-width-just ', {
104
112
  'resizing position-fixed': isResizing,
@@ -4,14 +4,15 @@ import { useSlateStatic } from '@seafile/slate-react';
4
4
  import classnames from 'classnames';
5
5
  import { useTableRootContext } from '../hooks';
6
6
  import { TABLE_CELL_MIN_WIDTH } from '../../constants';
7
- import { getTableColumns, updateColumnWidth } from '../../helpers';
7
+ import { focusClosestCellWhenJustifyCellSize, getTableColumns, updateColumnWidth } from '../../helpers';
8
8
  import { eventStopPropagation, getMouseDownInfo, getMouseMoveInfo, registerResizeEvents, unregisterResizeEvents } from '../../../../../utils/mouse-event';
9
9
  const FirstColumnResizeHandler = _ref => {
10
10
  let {
11
11
  column,
12
12
  left: initLeft,
13
13
  element,
14
- index
14
+ index,
15
+ rowBottoms
15
16
  } = _ref;
16
17
  const editor = useSlateStatic();
17
18
  const resizeHandler = useRef(null);
@@ -72,6 +73,13 @@ const FirstColumnResizeHandler = _ref => {
72
73
  width: newWidth
73
74
  });
74
75
  updateColumnWidth(editor, element, newColumns);
76
+ focusClosestCellWhenJustifyCellSize({
77
+ editor,
78
+ columnIndex: index,
79
+ table: element,
80
+ mouseDownInfo,
81
+ rowBottoms
82
+ });
75
83
  };
76
84
  registerResizeEvents({
77
85
  'mousemove': onMouseMove,
@@ -85,7 +93,7 @@ const FirstColumnResizeHandler = _ref => {
85
93
  };
86
94
 
87
95
  // eslint-disable-next-line react-hooks/exhaustive-deps
88
- }, [isResizing, mouseDownInfo, left, width, column, editor, element, index, initLeft]);
96
+ }, [isResizing, mouseDownInfo, left, width, column, editor, element, index, initLeft, rowBottoms]);
89
97
  return /*#__PURE__*/React.createElement("div", {
90
98
  className: classnames('table-cell-width-just ', {
91
99
  'resizing position-fixed': isResizing,
@@ -1,31 +1,37 @@
1
- import React from 'react';
1
+ /* eslint-disable react-hooks/rules-of-hooks */
2
+ import React, { useCallback, useEffect, useState } from 'react';
2
3
  import { useSlateStatic } from '@seafile/slate-react';
3
4
  import FirstColumnResizeHandler from './first-column-left-resize-handler';
4
5
  import ColumnResizeHandler from './column-resize-handler';
5
6
  import RowResizeHandler from './row-resize-handler';
6
7
  import { getNode, findPath } from '../../../../core';
7
8
  import { useResizeHandlersContext } from '../hooks';
8
- import { getRowHeight, getTableColumns } from '../../helpers';
9
- import { TABLE_ROW_STYLE } from '../../constants';
9
+ import { getRowBottomPositions, getTableColumns } from '../../helpers';
10
10
  const ResizeHandlers = _ref => {
11
11
  let {
12
12
  element
13
13
  } = _ref;
14
14
  const editor = useSlateStatic();
15
15
  const tablePath = findPath(editor, element);
16
- const columns = useResizeHandlersContext() || getTableColumns(editor, element);
17
16
  if (!tablePath) return null;
18
17
  const table = getNode(editor, tablePath);
19
18
  if (!table) return null;
19
+ const [rowBottoms, setRowBottoms] = useState([]);
20
+ const columns = useResizeHandlersContext() || getTableColumns(editor, element);
20
21
  const rows = element.children;
21
- let rowBottom = 0;
22
+ const calculateRowBottom = useCallback(() => {
23
+ const rowBottomPositions = getRowBottomPositions(editor, rows);
24
+ setRowBottoms(rowBottomPositions);
25
+ }, [editor, rows]);
26
+ useEffect(() => {
27
+ calculateRowBottom();
28
+ }, [calculateRowBottom, element]);
22
29
  let columnLeft = 0;
23
30
  return /*#__PURE__*/React.createElement(React.Fragment, null, rows.map((row, index) => {
24
- rowBottom += getRowHeight(row, index);
25
31
  return /*#__PURE__*/React.createElement(RowResizeHandler, {
26
32
  key: index,
27
33
  row: row,
28
- rowBottom: rowBottom,
34
+ rowBottoms: rowBottoms[index],
29
35
  index: index,
30
36
  element: element
31
37
  });
@@ -34,10 +40,12 @@ const ResizeHandlers = _ref => {
34
40
  column: columns[0],
35
41
  left: 0,
36
42
  index: 0,
37
- element: element
43
+ element: element,
44
+ rowBottoms: rowBottoms
38
45
  }), columns.map((column, columnIndex) => {
39
46
  columnLeft = columnLeft + column.width;
40
47
  return /*#__PURE__*/React.createElement(ColumnResizeHandler, {
48
+ rowBottoms: rowBottoms,
41
49
  key: columnIndex,
42
50
  column: column,
43
51
  left: columnLeft,
@@ -3,14 +3,14 @@ import classnames from 'classnames';
3
3
  import { useSlateStatic } from '@seafile/slate-react';
4
4
  import { ReactEditor } from '@seafile/slate-react';
5
5
  import { TABLE_ROW_MIN_HEIGHT } from '../../constants';
6
- import { getRowHeight, updateTableRowHeight } from '../../helpers';
6
+ import { focusClosestCellWhenJustifyCellSize, getRowHeight, updateTableRowHeight } from '../../helpers';
7
7
  import { eventStopPropagation, getMouseDownInfo, getMouseMoveInfo, registerResizeEvents, unregisterResizeEvents } from '../../../../../utils/mouse-event';
8
8
  import { useScrollContext } from '../../../../../hooks/use-scroll-context';
9
9
  const RowResizeHandler = _ref => {
10
10
  let {
11
11
  row,
12
12
  index,
13
- rowBottom: initRowBottom,
13
+ rowBottoms: initRowBottom = 0,
14
14
  element
15
15
  } = _ref;
16
16
  const editor = useSlateStatic();
@@ -27,12 +27,11 @@ const RowResizeHandler = _ref => {
27
27
  const mouseDownInfo = getMouseDownInfo(event, scrollContent.current);
28
28
  setMouseDownInfo(mouseDownInfo);
29
29
  setStyle({
30
- top: initRowBottom - 2.5
30
+ top: rowBottom - 2.5
31
31
  });
32
32
  setIsResizing(true);
33
-
34
33
  // eslint-disable-next-line react-hooks/exhaustive-deps
35
- }, []);
34
+ }, [rowBottom]);
36
35
  useEffect(() => {
37
36
  if (!isResizing) return;
38
37
  const onMouseMove = event => {
@@ -50,6 +49,12 @@ const RowResizeHandler = _ref => {
50
49
  setIsResizing(false);
51
50
  tableRow.current = height;
52
51
  updateTableRowHeight(editor, row, height);
52
+ focusClosestCellWhenJustifyCellSize({
53
+ editor,
54
+ rowIndex: index,
55
+ table: element,
56
+ mouseDownInfo
57
+ });
53
58
  };
54
59
  registerResizeEvents({
55
60
  'mousemove': onMouseMove,
@@ -70,7 +75,7 @@ const RowResizeHandler = _ref => {
70
75
  const rowDom = ReactEditor.toDOMNode(editor, cell);
71
76
  if (!rowDom) return;
72
77
  tableRow.current = rowDom.clientHeight;
73
- setRowBottom(initRowBottom - height + tableRow.current);
78
+ setRowBottom(initRowBottom);
74
79
  // eslint-disable-next-line react-hooks/exhaustive-deps
75
80
  }, [row, initRowBottom]);
76
81
  return /*#__PURE__*/React.createElement("div", {
@@ -30,7 +30,6 @@ const TableRoot = _ref => {
30
30
  className: classnames('sdoc-table-wrapper position-relative', attributes.className, {
31
31
  'scroll': allWidth > editor.width
32
32
  }),
33
- "data-root": "true",
34
33
  style: _objectSpread(_objectSpread({}, attributes.style), {}, {
35
34
  maxWidth: editor.width ? editor.width : '100%'
36
35
  })
@@ -18,4 +18,5 @@ const isNeedAddMouseEnterEvent = (editor, element) => {
18
18
  export const setMouseEnter = (editor, element, attributes) => {
19
19
  if (!isNeedAddMouseEnterEvent(editor, element)) return;
20
20
  attributes['onMouseEnter'] = e => onMouseEnter(e, element);
21
+ attributes['data-root'] = 'true';
21
22
  };
@@ -1,9 +1,9 @@
1
1
  import React, { useCallback } from 'react';
2
2
  import { UncontrolledPopover } from 'reactstrap';
3
3
  import { withTranslation } from 'react-i18next';
4
- import { useSlateStatic } from '@seafile/slate-react';
4
+ import { ReactEditor, useSlateStatic } from '@seafile/slate-react';
5
5
  import { onSetNodeType } from './helpers';
6
- import { SIDE_TRANSFORM_MENUS_CONFIG, LIST_ITEM_SUPPORTED_TRANSFORMATION, LIST_ITEM_CORRELATION_TYPE } from '../../constants';
6
+ import { SIDE_TRANSFORM_MENUS_CONFIG, LIST_ITEM_SUPPORTED_TRANSFORMATION, LIST_ITEM_CORRELATION_TYPE, BLOCKQUOTE, CALL_OUT } from '../../constants';
7
7
  import DropdownMenuItem from '../../commons/dropdown-menu-item';
8
8
  const TransformMenus = _ref => {
9
9
  let {
@@ -23,6 +23,14 @@ const TransformMenus = _ref => {
23
23
  if (LIST_ITEM_CORRELATION_TYPE.includes(slateNode.type)) {
24
24
  newSideMenusConfig = SIDE_TRANSFORM_MENUS_CONFIG.filter(item => LIST_ITEM_SUPPORTED_TRANSFORMATION.includes(item.type));
25
25
  }
26
+ const path = ReactEditor.findPath(editor, slateNode);
27
+ if (path && path.length > 1) {
28
+ const nodeIndex = path[0];
29
+ const highestNode = editor.children[nodeIndex];
30
+ if (highestNode.type === BLOCKQUOTE) {
31
+ newSideMenusConfig = SIDE_TRANSFORM_MENUS_CONFIG.filter(item => item.type !== CALL_OUT);
32
+ }
33
+ }
26
34
  return newSideMenusConfig;
27
35
  // eslint-disable-next-line react-hooks/exhaustive-deps
28
36
  }, [slateNode]);
@@ -81,6 +81,7 @@ class EventProxy {
81
81
  }
82
82
  };
83
83
  this.onCopy = event => {
84
+ if (this.editor.onCopy) this.editor.onCopy(event);
84
85
  setOriginSdocKey(event);
85
86
  };
86
87
  this.onCut = event => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seafile/sdoc-editor",
3
- "version": "0.4.11",
3
+ "version": "0.4.13",
4
4
  "private": false,
5
5
  "description": "This is a sdoc editor",
6
6
  "main": "dist/index.js",