@seafile/sdoc-editor 0.1.71 → 0.1.72

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.
@@ -1,8 +1,8 @@
1
1
  import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
2
2
  import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
3
- import { Editable, Slate } from '@seafile/slate-react';
3
+ import { Editable, ReactEditor, Slate } from '@seafile/slate-react';
4
4
  import defaultEditor, { renderLeaf, renderElement, Toolbar, ContextMenu } from './extension';
5
- import { focusEditor } from './extension/core';
5
+ import { focusEditor, getNextNode, getPrevNode, isSelectionAtBlockEnd, isSelectionAtBlockStart } from './extension/core';
6
6
  import { withSocketIO } from './socket';
7
7
  import withNodeId from './node-id';
8
8
  import SDocOutline from './outline';
@@ -16,6 +16,7 @@ import { ScrollContext } from './hooks/use-scroll-context';
16
16
  import CommentContextProvider from './comment/comment-context-provider';
17
17
  import CommentWrapper from './comment';
18
18
  import { usePipDecorate } from './decorates';
19
+ import { getCursorPosition, getDomHeight } from './utils/dom-utils';
19
20
  import './assets/css/layout.css';
20
21
  import './assets/css/sdoc-editor-plugins.css';
21
22
  var SDocEditor = function SDocEditor(_ref) {
@@ -100,6 +101,44 @@ var SDocEditor = function SDocEditor(_ref) {
100
101
  }
101
102
  // eslint-disable-next-line react-hooks/exhaustive-deps
102
103
  }, []);
104
+ var onKeyDown = useCallback(function (event) {
105
+ var _scrollRef$current = scrollRef.current,
106
+ scrollTop = _scrollRef$current.scrollTop,
107
+ clientHeight = _scrollRef$current.clientHeight;
108
+ if (event.key === 'ArrowLeft') {
109
+ if (!isSelectionAtBlockStart(editor)) return;
110
+ }
111
+ if (event.key === 'ArrowUp' || event.key === 'ArrowLeft') {
112
+ if (scrollTop === 0) return;
113
+ var prevNode = getPrevNode(editor);
114
+ if (!prevNode) return;
115
+ var domNode = ReactEditor.toDOMNode(editor, prevNode[0]);
116
+ var domHeight = getDomHeight(domNode);
117
+ var isScrollUp = true;
118
+ var _getCursorPosition = getCursorPosition(isScrollUp),
119
+ y = _getCursorPosition.y;
120
+ if (y >= domHeight) return;
121
+ scrollRef.current.scroll(0, Math.max(0, scrollTop - domHeight));
122
+ return;
123
+ }
124
+ if (event.key === 'ArrowRight') {
125
+ if (!isSelectionAtBlockEnd(editor)) return;
126
+ }
127
+ if (event.key === 'ArrowDown' || event.key === 'ArrowRight') {
128
+ var nextNode = getNextNode(editor);
129
+ if (!nextNode) return;
130
+ var _domNode = ReactEditor.toDOMNode(editor, nextNode[0]);
131
+ var _domHeight = getDomHeight(_domNode);
132
+ var _isScrollUp = false;
133
+ var _getCursorPosition2 = getCursorPosition(_isScrollUp),
134
+ _y = _getCursorPosition2.y;
135
+ if (clientHeight - _y >= _domHeight) return;
136
+ scrollRef.current.scroll(0, Math.max(0, scrollTop + _domHeight));
137
+ return;
138
+ }
139
+ eventProxy.onKeyDown(event);
140
+ // eslint-disable-next-line react-hooks/exhaustive-deps
141
+ }, []);
103
142
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
104
143
  className: "sdoc-editor-container"
105
144
  }, /*#__PURE__*/React.createElement(Toolbar, {
@@ -124,10 +163,10 @@ var SDocEditor = function SDocEditor(_ref) {
124
163
  className: "article",
125
164
  ref: articleRef
126
165
  }, /*#__PURE__*/React.createElement(SetNodeToDecorations, null), /*#__PURE__*/React.createElement(Editable, {
166
+ cursors: cursors,
127
167
  renderElement: renderElement,
128
168
  renderLeaf: renderLeaf,
129
- onKeyDown: eventProxy.onKeyDown,
130
- cursors: cursors,
169
+ onKeyDown: onKeyDown,
131
170
  onContextMenu: onContextMenu,
132
171
  onMouseDown: onMouseDown,
133
172
  decorate: decorate
@@ -216,6 +216,94 @@ export var getAboveBlockNode = function getAboveBlockNode(editor, options) {
216
216
  block: true
217
217
  }));
218
218
  };
219
+ export var getPrevNode = function getPrevNode(editor) {
220
+ var _getAboveNode = getAboveNode(editor, {
221
+ mode: 'lowest',
222
+ match: function match(n) {
223
+ return Element.isElement(n) && Editor.isBlock(editor, n);
224
+ }
225
+ }),
226
+ _getAboveNode2 = _slicedToArray(_getAboveNode, 2),
227
+ lowerNode = _getAboveNode2[0],
228
+ lowerPath = _getAboveNode2[1];
229
+ var _getAboveNode3 = getAboveNode(editor, {
230
+ mode: 'highest',
231
+ match: function match(n) {
232
+ return Element.isElement(n) && Editor.isBlock(editor, n);
233
+ }
234
+ }),
235
+ _getAboveNode4 = _slicedToArray(_getAboveNode3, 2),
236
+ heightNode = _getAboveNode4[0],
237
+ heightPath = _getAboveNode4[1];
238
+ var prevNode = null;
239
+ try {
240
+ prevNode = Editor.previous(editor, {
241
+ at: lowerPath,
242
+ match: function match(n) {
243
+ return Element.isElement(n) && Editor.isBlock(editor, n);
244
+ }
245
+ });
246
+ } catch (error) {
247
+ prevNode = null;
248
+ }
249
+ if (lowerNode.id !== heightNode.id && !prevNode) {
250
+ try {
251
+ prevNode = Editor.previous(editor, {
252
+ at: heightPath,
253
+ match: function match(n) {
254
+ return Element.isElement(n) && Editor.isBlock(editor, n);
255
+ }
256
+ });
257
+ } catch (error) {
258
+ prevNode = null;
259
+ }
260
+ }
261
+ return prevNode;
262
+ };
263
+ export var getNextNode = function getNextNode(editor) {
264
+ var _getAboveNode5 = getAboveNode(editor, {
265
+ mode: 'lowest',
266
+ match: function match(n) {
267
+ return Element.isElement(n) && Editor.isBlock(editor, n);
268
+ }
269
+ }),
270
+ _getAboveNode6 = _slicedToArray(_getAboveNode5, 2),
271
+ lowerNode = _getAboveNode6[0],
272
+ lowerPath = _getAboveNode6[1];
273
+ var _getAboveNode7 = getAboveNode(editor, {
274
+ mode: 'highest',
275
+ match: function match(n) {
276
+ return Element.isElement(n) && Editor.isBlock(editor, n);
277
+ }
278
+ }),
279
+ _getAboveNode8 = _slicedToArray(_getAboveNode7, 2),
280
+ heightNode = _getAboveNode8[0],
281
+ heightPath = _getAboveNode8[1];
282
+ var nextNode = null;
283
+ try {
284
+ nextNode = Editor.next(editor, {
285
+ at: lowerPath,
286
+ match: function match(n) {
287
+ return Element.isElement(n) && Editor.isBlock(editor, n);
288
+ }
289
+ });
290
+ } catch (error) {
291
+ nextNode = null;
292
+ }
293
+ if (lowerNode.id !== heightNode.id && !nextNode) {
294
+ try {
295
+ nextNode = Editor.next(editor, {
296
+ at: heightPath,
297
+ match: function match(n) {
298
+ return Element.isElement(n) && Editor.isBlock(editor, n);
299
+ }
300
+ });
301
+ } catch (error) {
302
+ nextNode = null;
303
+ }
304
+ }
305
+ return nextNode;
306
+ };
219
307
 
220
308
  // find node
221
309
  export var findNode = function findNode(editor, options) {
@@ -362,6 +450,11 @@ export var isSelectionAtBlockStart = function isSelectionAtBlockStart(editor, op
362
450
  if (!path) return false;
363
451
  return isStartPoint(editor, selection.focus, path) || Range.isExpanded(editor.selection) && isStartPoint(editor, selection.anchor, path);
364
452
  };
453
+ export var isSelectionAtBlockEnd = function isSelectionAtBlockEnd(editor, options) {
454
+ var _getAboveBlockNode3, _editor$selection;
455
+ var path = (_getAboveBlockNode3 = getAboveBlockNode(editor, options)) === null || _getAboveBlockNode3 === void 0 ? void 0 : _getAboveBlockNode3[1];
456
+ return !!path && isEndPoint(editor, (_editor$selection = editor.selection) === null || _editor$selection === void 0 ? void 0 : _editor$selection.focus, path);
457
+ };
365
458
  export var isLastNode = function isLastNode(editor, node) {
366
459
  var editorChildren = editor.children || [];
367
460
  var editorChildrenLength = editorChildren.length;
@@ -0,0 +1,116 @@
1
+ import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
2
+ import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
3
+ import React, { useRef, useState, useEffect, useCallback } from 'react';
4
+ import { Transforms } from '@seafile/slate';
5
+ import { useSlateStatic } from '@seafile/slate-react';
6
+ import classnames from 'classnames';
7
+ import { useTableRootContext } from '../hooks';
8
+ import { TABLE_CELL_MIN_WIDTH } from '../../constants';
9
+ import { getTableColumns, updateColumnWidth } from '../../helpers';
10
+ import { eventStopPropagation, getMouseDownInfo, getMouseMoveInfo, registerResizeEvents, unregisterResizeEvents } from '../../../../../utils/mouse-event';
11
+ var FirstColumnResizeHandler = function FirstColumnResizeHandler(_ref) {
12
+ var column = _ref.column,
13
+ initLeft = _ref.left,
14
+ element = _ref.element,
15
+ index = _ref.index;
16
+ var editor = useSlateStatic();
17
+ var resizeHandler = useRef(null);
18
+ var _useState = useState(initLeft),
19
+ _useState2 = _slicedToArray(_useState, 2),
20
+ left = _useState2[0],
21
+ setLeft = _useState2[1];
22
+ var _useState3 = useState(false),
23
+ _useState4 = _slicedToArray(_useState3, 2),
24
+ isResizing = _useState4[0],
25
+ setIsResizing = _useState4[1];
26
+ var _useState5 = useState({}),
27
+ _useState6 = _slicedToArray(_useState5, 2),
28
+ mouseDownInfo = _useState6[0],
29
+ setMouseDownInfo = _useState6[1];
30
+ var _useState7 = useState({}),
31
+ _useState8 = _slicedToArray(_useState7, 2),
32
+ style = _useState8[0],
33
+ setStyle = _useState8[1];
34
+ var width = column.width;
35
+ var tableRootScrollContainer = useTableRootContext();
36
+ var onMouseDown = useCallback(function (event) {
37
+ eventStopPropagation(event);
38
+ Transforms.deselect(editor);
39
+ var mouseDownInfo = getMouseDownInfo(event, tableRootScrollContainer);
40
+ var _tableRootScrollConta = tableRootScrollContainer.getBoundingClientRect(),
41
+ top = _tableRootScrollConta.top;
42
+ setStyle({
43
+ left: mouseDownInfo.positionX - 2,
44
+ height: tableRootScrollContainer.clientHeight,
45
+ top: top
46
+ });
47
+ setMouseDownInfo(mouseDownInfo);
48
+ setIsResizing(true);
49
+
50
+ // eslint-disable-next-line react-hooks/exhaustive-deps
51
+ }, [tableRootScrollContainer]);
52
+ useEffect(function () {
53
+ if (!isResizing) {
54
+ if (initLeft !== left) {
55
+ setLeft(initLeft);
56
+ }
57
+ return;
58
+ }
59
+ var onMouseMove = function onMouseMove(event) {
60
+ eventStopPropagation(event);
61
+ var mouseMoveInfo = getMouseMoveInfo(event, mouseDownInfo, tableRootScrollContainer);
62
+ var newWidth = width - mouseMoveInfo.displacementX;
63
+ if (newWidth < TABLE_CELL_MIN_WIDTH) return;
64
+ var left = initLeft - mouseMoveInfo.displacementX;
65
+ var _tableRootScrollConta2 = tableRootScrollContainer.getBoundingClientRect(),
66
+ top = _tableRootScrollConta2.top;
67
+ setStyle({
68
+ left: event.clientX - 2,
69
+ height: tableRootScrollContainer.clientHeight,
70
+ top: top
71
+ });
72
+ setLeft(left);
73
+ };
74
+ var onMouseUp = function onMouseUp(event) {
75
+ eventStopPropagation(event);
76
+ setIsResizing(false);
77
+ setStyle({});
78
+ var columns = getTableColumns(editor, element);
79
+ var newColumns = columns.slice(0);
80
+ var column = newColumns[index];
81
+ var newWidth = width + left - initLeft;
82
+ newColumns[index] = _objectSpread(_objectSpread({}, column), {}, {
83
+ width: newWidth
84
+ });
85
+ updateColumnWidth(editor, element, newColumns);
86
+ };
87
+ registerResizeEvents({
88
+ 'mousemove': onMouseMove,
89
+ 'mouseup': onMouseUp
90
+ });
91
+ return function () {
92
+ unregisterResizeEvents({
93
+ 'mousemove': onMouseMove,
94
+ 'mouseup': onMouseUp
95
+ });
96
+ };
97
+
98
+ // eslint-disable-next-line react-hooks/exhaustive-deps
99
+ }, [isResizing, mouseDownInfo, left, width, column, editor, element, index, initLeft]);
100
+ return /*#__PURE__*/React.createElement("div", {
101
+ className: classnames('table-cell-width-just ', {
102
+ 'resizing position-fixed': isResizing,
103
+ 'position-absolute': !isResizing
104
+ }),
105
+ contentEditable: false,
106
+ style: isResizing ? style : {
107
+ left: -3.5,
108
+ top: 0
109
+ },
110
+ onMouseDown: onMouseDown,
111
+ ref: resizeHandler
112
+ }, /*#__PURE__*/React.createElement("div", {
113
+ className: "table-cell-width-just-color-tip"
114
+ }));
115
+ };
116
+ export default FirstColumnResizeHandler;
@@ -1,9 +1,10 @@
1
1
  import React from 'react';
2
2
  import { useSlateStatic } from '@seafile/slate-react';
3
+ import FirstColumnResizeHandler from './first-column-left-resize-handler';
3
4
  import ResizeHandler from './resize-handler';
4
- import { getNode, findPath } from '../../../core';
5
- import { useResizeHandlersContext } from './hooks';
6
- import { getTableColumns } from '../helpers';
5
+ import { getNode, findPath } from '../../../../core';
6
+ import { useResizeHandlersContext } from '../hooks';
7
+ import { getTableColumns } from '../../helpers';
7
8
  var ResizeHandlers = function ResizeHandlers(props) {
8
9
  var element = props.element;
9
10
  var editor = useSlateStatic();
@@ -13,7 +14,13 @@ var ResizeHandlers = function ResizeHandlers(props) {
13
14
  var table = getNode(editor, tablePath);
14
15
  if (!table) return null;
15
16
  var columnLeft = 0;
16
- return /*#__PURE__*/React.createElement(React.Fragment, null, columns.map(function (column, columnIndex) {
17
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(FirstColumnResizeHandler, {
18
+ key: "column-0-left",
19
+ column: columns[0],
20
+ left: 0,
21
+ index: 0,
22
+ element: element
23
+ }), columns.map(function (column, columnIndex) {
17
24
  columnLeft = columnLeft + column.width;
18
25
  return /*#__PURE__*/React.createElement(ResizeHandler, {
19
26
  key: columnIndex,
@@ -4,10 +4,10 @@ import React, { useRef, useState, useEffect, useCallback } from 'react';
4
4
  import { Transforms } from '@seafile/slate';
5
5
  import { useSlateStatic } from '@seafile/slate-react';
6
6
  import classnames from 'classnames';
7
- import { useTableRootContext } from './hooks';
8
- import { TABLE_CELL_MIN_WIDTH } from '../constants';
9
- import { getTableColumns, updateColumnWidth } from '../helpers';
10
- import { eventStopPropagation, getMouseDownInfo, getMouseMoveInfo, registerResizeEvents, unregisterResizeEvents } from '../../../../utils/mouse-event';
7
+ import { useTableRootContext } from '../hooks';
8
+ import { TABLE_CELL_MIN_WIDTH } from '../../constants';
9
+ import { getTableColumns, updateColumnWidth } from '../../helpers';
10
+ import { eventStopPropagation, getMouseDownInfo, getMouseMoveInfo, registerResizeEvents, unregisterResizeEvents } from '../../../../../utils/mouse-event';
11
11
  var ResizeHandler = function ResizeHandler(_ref) {
12
12
  var column = _ref.column,
13
13
  initLeft = _ref.left,
@@ -27,17 +27,28 @@ var ResizeHandler = function ResizeHandler(_ref) {
27
27
  _useState6 = _slicedToArray(_useState5, 2),
28
28
  mouseDownInfo = _useState6[0],
29
29
  setMouseDownInfo = _useState6[1];
30
+ var _useState7 = useState({}),
31
+ _useState8 = _slicedToArray(_useState7, 2),
32
+ style = _useState8[0],
33
+ setStyle = _useState8[1];
30
34
  var width = column.width;
31
35
  var tableRootScrollContainer = useTableRootContext();
32
36
  var onMouseDown = useCallback(function (event) {
33
37
  eventStopPropagation(event);
34
38
  Transforms.deselect(editor);
35
39
  var mouseDownInfo = getMouseDownInfo(event, tableRootScrollContainer);
40
+ var _tableRootScrollConta = tableRootScrollContainer.getBoundingClientRect(),
41
+ top = _tableRootScrollConta.top;
42
+ setStyle({
43
+ left: mouseDownInfo.positionX - 2,
44
+ height: tableRootScrollContainer.clientHeight,
45
+ top: top
46
+ });
36
47
  setMouseDownInfo(mouseDownInfo);
37
48
  setIsResizing(true);
38
49
 
39
50
  // eslint-disable-next-line react-hooks/exhaustive-deps
40
- }, []);
51
+ }, [tableRootScrollContainer]);
41
52
  useEffect(function () {
42
53
  if (!isResizing) {
43
54
  if (initLeft !== left) {
@@ -49,19 +60,27 @@ var ResizeHandler = function ResizeHandler(_ref) {
49
60
  eventStopPropagation(event);
50
61
  var mouseMoveInfo = getMouseMoveInfo(event, mouseDownInfo, tableRootScrollContainer);
51
62
  var newWidth = width + mouseMoveInfo.displacementX;
52
- if (newWidth < TABLE_CELL_MIN_WIDTH) return;
53
63
  var columns = getTableColumns(editor, element);
64
+ if (newWidth < TABLE_CELL_MIN_WIDTH) return;
54
65
  var nextColumn = columns[index + 1];
55
66
  if (nextColumn) {
56
67
  var nextColumnWidth = nextColumn.width - mouseMoveInfo.displacementX;
57
68
  if (nextColumnWidth < TABLE_CELL_MIN_WIDTH) return;
58
69
  }
59
70
  var left = initLeft + mouseMoveInfo.displacementX;
71
+ var _tableRootScrollConta2 = tableRootScrollContainer.getBoundingClientRect(),
72
+ top = _tableRootScrollConta2.top;
73
+ setStyle({
74
+ left: event.clientX - 2,
75
+ height: tableRootScrollContainer.clientHeight,
76
+ top: top
77
+ });
60
78
  setLeft(left);
61
79
  };
62
80
  var onMouseUp = function onMouseUp(event) {
63
81
  eventStopPropagation(event);
64
82
  setIsResizing(false);
83
+ setStyle({});
65
84
  var columns = getTableColumns(editor, element);
66
85
  var newColumns = columns.slice(0);
67
86
  var column = newColumns[index];
@@ -92,11 +111,12 @@ var ResizeHandler = function ResizeHandler(_ref) {
92
111
  // eslint-disable-next-line react-hooks/exhaustive-deps
93
112
  }, [isResizing, mouseDownInfo, left, width, column, editor, element, index, initLeft]);
94
113
  return /*#__PURE__*/React.createElement("div", {
95
- className: classnames('table-cell-width-just position-absolute', {
96
- 'resizing': isResizing
114
+ className: classnames('table-cell-width-just ', {
115
+ 'resizing position-fixed': isResizing,
116
+ 'position-absolute': !isResizing
97
117
  }),
98
118
  contentEditable: false,
99
- style: {
119
+ style: isResizing ? style : {
100
120
  left: left - 3.5,
101
121
  top: 0
102
122
  },
@@ -0,0 +1,40 @@
1
+ export var getDomHeight = function getDomHeight(dom) {
2
+ var styles = window.getComputedStyle(dom);
3
+ var rect = dom.getBoundingClientRect();
4
+ var marginTop = styles['marginTop'];
5
+ // margin-bottom overlaps margin-top
6
+ // const marginBottom = styles['marginBottom'];
7
+ var height = rect.height;
8
+ return height + parseInt(marginTop);
9
+ };
10
+ export var getSelectionRange = function getSelectionRange() {
11
+ if (window.getSelection) {
12
+ var sel = window.getSelection();
13
+ if (sel.getRangeAt && sel.rangeCount) {
14
+ return sel.getRangeAt(0);
15
+ }
16
+ } else if (document.selection && document.selection.createRange) {
17
+ return document.selection.createRange();
18
+ }
19
+ return null;
20
+ };
21
+ export var getCursorPosition = function getCursorPosition() {
22
+ var isScrollUp = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
23
+ var x = 0,
24
+ y = 0;
25
+ var range = getSelectionRange();
26
+ if (range) {
27
+ var rect = range.getBoundingClientRect();
28
+ var headerHeight = 100;
29
+ x = rect.x || 0;
30
+ if (isScrollUp) {
31
+ y = rect.y - headerHeight;
32
+ } else {
33
+ y = rect.y - headerHeight + rect.height;
34
+ }
35
+ }
36
+ return {
37
+ x: x,
38
+ y: y
39
+ };
40
+ };
@@ -47,8 +47,8 @@ export var getMouseMoveInfo = function getMouseMoveInfo(event, mouseDownInfo, sc
47
47
  var scrollLeft = 0;
48
48
  var scrollTop = 0;
49
49
  if (scrollContainer) {
50
- scrollLeft = scrollContainer.scrollLeft;
51
- scrollTop = scrollContainer.scrollTop;
50
+ scrollLeft = scrollContainer.scrollLeft || 0;
51
+ scrollTop = scrollContainer.scrollTop || 0;
52
52
  }
53
53
  displacementX = currPositionX - mouseDownInfo.positionX + scrollLeft - (mouseDownInfo.scrollLeft || 0);
54
54
  displacementY = currPositionY - mouseDownInfo.positionY + scrollTop - (mouseDownInfo.scrollTop || 0);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seafile/sdoc-editor",
3
- "version": "0.1.71",
3
+ "version": "0.1.72",
4
4
  "private": false,
5
5
  "description": "This is a sdoc editor",
6
6
  "main": "dist/index.js",