@seafile/sdoc-editor 0.1.81 → 0.1.82

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.
@@ -57,10 +57,12 @@
57
57
  .sdoc-editor-container .article .image-size {
58
58
  display: inline-block;
59
59
  padding: 5px;
60
+ white-space: nowrap;
60
61
  height: 22px;
61
62
  position: absolute;
62
63
  bottom: -25px;
63
64
  left: 100%;
65
+ z-index: 1;
64
66
  transform: translateX(5px);
65
67
  border-radius: 3px;
66
68
  line-height: 12px;
@@ -120,4 +120,6 @@ export var ADDED_STYLE = {
120
120
  computed_bg_color: '#e6ffed',
121
121
  color: 'rgb(137, 181, 66)'
122
122
  };
123
+ export var HEADER_TYPE_ARRAY = ['header1', 'header2', 'header3', 'header4', 'header5', 'header6'];
124
+ export var LIST_TYPE_ARRAY = ['unordered_list', 'ordered_list'];
123
125
  export { BLOCKQUOTE, HEADER, HEADER1, HEADER2, HEADER3, HEADER4, HEADER5, HEADER6, PARAGRAPH, BOLD, ITALIC, UNDERLINE, STRIKETHROUGH, SUPERSCRIPT, SUBSCRIPT, ORDERED_LIST, UNORDERED_LIST, LIST_ITEM, LIST_LIC, CHECK_LIST, CHECK_LIST_ITEM, LINK, HTML, CODE_BLOCK, CODE_LINE, IMAGE, TABLE, TABLE_CELL, TABLE_ROW, FORMULA, COLUMN, TEXT_STYLE, TEXT_STYLE_MORE, BOLD_ITALIC, TEXT_ALIGN, ALIGN_LEFT, ALIGN_RIGHT, ALIGN_CENTER, ELEMENT_TYPE, KEYBOARD };
@@ -84,16 +84,28 @@ export var getSelectedNodeByType = function getSelectedNodeByType(editor, type)
84
84
  nodeEntry = _Editor$nodes2[0];
85
85
  return nodeEntry ? nodeEntry[0] : null;
86
86
  };
87
- export var getSelectedNodeEntryByType = function getSelectedNodeEntryByType(editor, type) {
87
+ export var getSelectedNodeByTypes = function getSelectedNodeByTypes(editor, types) {
88
88
  var match = function match(n) {
89
- return getNodeType(n) === type;
89
+ return types.includes(getNodeType(n));
90
90
  };
91
91
  var _Editor$nodes3 = Editor.nodes(editor, {
92
92
  match: match,
93
- universal: false
93
+ universal: true
94
94
  }),
95
95
  _Editor$nodes4 = _slicedToArray(_Editor$nodes3, 1),
96
96
  nodeEntry = _Editor$nodes4[0];
97
+ return nodeEntry ? nodeEntry[0] : null;
98
+ };
99
+ export var getSelectedNodeEntryByType = function getSelectedNodeEntryByType(editor, type) {
100
+ var match = function match(n) {
101
+ return getNodeType(n) === type;
102
+ };
103
+ var _Editor$nodes5 = Editor.nodes(editor, {
104
+ match: match,
105
+ universal: false
106
+ }),
107
+ _Editor$nodes6 = _slicedToArray(_Editor$nodes5, 1),
108
+ nodeEntry = _Editor$nodes6[0];
97
109
  return nodeEntry ? nodeEntry : null;
98
110
  };
99
111
  export var getNodeEntries = function getNodeEntries(editor, options) {
@@ -1,9 +1,9 @@
1
1
  import { Node, Range, Transforms } from '@seafile/slate';
2
2
  import { CHECK_LIST_ITEM, PARAGRAPH } from '../../constants';
3
- import { getSelectedNodeByType } from '../../core';
3
+ import { generateDefaultText, getSelectedNodeByType } from '../../core';
4
4
  var withCheckList = function withCheckList(editor) {
5
5
  var insertBreak = editor.insertBreak,
6
- deleteBackWord = editor.deleteBackWord;
6
+ deleteBackward = editor.deleteBackward;
7
7
  var newEditor = editor;
8
8
  newEditor.insertBreak = function () {
9
9
  var selection = newEditor.selection;
@@ -18,16 +18,25 @@ var withCheckList = function withCheckList(editor) {
18
18
  }
19
19
  if (Node.string(node).length === 0) {
20
20
  Transforms.setNodes(editor, {
21
- type: PARAGRAPH
21
+ type: PARAGRAPH,
22
+ children: [generateDefaultText()]
22
23
  }, {
23
- mode: 'highest'
24
+ at: node[1]
25
+ });
26
+ return;
27
+ }
28
+
29
+ // If it is check-list-item, handle your own business logic
30
+ if (Node.string(node).length > 0) {
31
+ Transforms.splitNodes(editor, {
32
+ always: true
24
33
  });
25
34
  return;
26
35
  }
27
36
  insertBreak();
28
37
  return;
29
38
  };
30
- newEditor.deleteBackWord = function (unit) {
39
+ newEditor.deleteBackward = function (unit) {
31
40
  var selection = newEditor.selection;
32
41
  if (selection && Range.isCollapsed(selection)) {
33
42
  var selectedTodo = getSelectedNodeByType(editor, CHECK_LIST_ITEM);
@@ -35,15 +44,16 @@ var withCheckList = function withCheckList(editor) {
35
44
  // If the current todo has no text, it will be converted to a paragraph
36
45
  if (Node.string(selectedTodo).length === 0) {
37
46
  Transforms.setNodes(editor, {
38
- type: PARAGRAPH
47
+ type: PARAGRAPH,
48
+ children: [generateDefaultText()]
39
49
  }, {
40
- mode: 'highest'
50
+ at: selectedTodo[1]
41
51
  });
42
52
  return;
43
53
  }
44
54
  }
45
55
  }
46
- deleteBackWord(unit);
56
+ deleteBackward(unit);
47
57
  };
48
58
  return newEditor;
49
59
  };
@@ -16,12 +16,15 @@ var HeaderMenu = /*#__PURE__*/function (_React$Component) {
16
16
  _classCallCheck(this, HeaderMenu);
17
17
  _this = _super.call(this, props);
18
18
  _this.registerEventHandler = function () {
19
- document.addEventListener('click', _this.onHideHeaderMenu);
19
+ document.addEventListener('click', _this.onHideHeaderMenu, true);
20
20
  };
21
21
  _this.unregisterEventHandler = function () {
22
- document.removeEventListener('click', _this.onHideHeaderMenu);
22
+ document.removeEventListener('click', _this.onHideHeaderMenu, true);
23
23
  };
24
- _this.onHideHeaderMenu = function () {
24
+ _this.onHideHeaderMenu = function (e) {
25
+ var menu = _this.menu;
26
+ var clickIsInMenu = menu && menu.contains(e.target) && menu !== e.target;
27
+ if (clickIsInMenu) return;
25
28
  _this.setState({
26
29
  isShowHeaderPopover: false
27
30
  }, function () {
@@ -65,8 +68,16 @@ var HeaderMenu = /*#__PURE__*/function (_React$Component) {
65
68
 
66
69
  // 执行命令
67
70
  setHeaderType(editor, newType);
71
+ _this.setState({
72
+ isShowHeaderPopover: false
73
+ }, function () {
74
+ _this.unregisterEventHandler();
75
+ });
68
76
  };
69
77
  };
78
+ _this.setMenuRef = function (ref) {
79
+ _this.menu = ref;
80
+ };
70
81
  _this.state = {
71
82
  isShowHeaderPopover: false
72
83
  };
@@ -92,6 +103,7 @@ var HeaderMenu = /*#__PURE__*/function (_React$Component) {
92
103
  }, t(HEADER_TITLE_MAP[headerType])), !disabled && /*#__PURE__*/React.createElement("span", {
93
104
  className: headerIconClass
94
105
  })), isShowHeaderPopover && /*#__PURE__*/React.createElement("div", {
106
+ ref: this.setMenuRef,
95
107
  className: "header-popover sdoc-dropdown-menu"
96
108
  }, /*#__PURE__*/React.createElement("div", {
97
109
  className: "sdoc-dropdown-menu-item",
@@ -1,7 +1,7 @@
1
1
  import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
2
- import { Editor, Element, Transforms } from '@seafile/slate';
3
- import { PARAGRAPH } from '../../constants';
4
- import { generateEmptyElement } from '../../core';
2
+ import { Editor, Element, Transforms, Node } from '@seafile/slate';
3
+ import { PARAGRAPH, HEADER_TYPE_ARRAY, LIST_TYPE_ARRAY } from '../../constants';
4
+ import { generateEmptyElement, getSelectedNodeByTypes } from '../../core';
5
5
  var isSelectionAtLineEnd = function isSelectionAtLineEnd(editor, path) {
6
6
  var selection = editor.selection;
7
7
  if (!selection) return false;
@@ -9,7 +9,9 @@ var isSelectionAtLineEnd = function isSelectionAtLineEnd(editor, path) {
9
9
  return isAtLineEnd;
10
10
  };
11
11
  var withHeader = function withHeader(editor) {
12
- var insertBreak = editor.insertBreak;
12
+ var insertBreak = editor.insertBreak,
13
+ insertFragment = editor.insertFragment,
14
+ insertText = editor.insertText;
13
15
  var newEditor = editor;
14
16
 
15
17
  // Rewrite insertBreak - insert paragraph when carriage return at the end of header
@@ -51,6 +53,20 @@ var withHeader = function withHeader(editor) {
51
53
  insertBreak();
52
54
  }
53
55
  };
56
+ newEditor.insertFragment = function (data) {
57
+ var headerNode = getSelectedNodeByTypes(editor, HEADER_TYPE_ARRAY);
58
+ var headerText = Node.string(headerNode || {
59
+ children: []
60
+ });
61
+ var isSingleListItem = data.length === 1 && data[0].children.length === 1 && LIST_TYPE_ARRAY.includes(data[0].type);
62
+ // Insert a list item when the header is empty, insert only the text
63
+ if (headerNode && headerText.length === 0 && isSingleListItem) {
64
+ var text = Node.string(data[0]);
65
+ insertText(text);
66
+ return;
67
+ }
68
+ return insertFragment(data);
69
+ };
54
70
  return newEditor;
55
71
  };
56
72
  export default withHeader;
@@ -26,7 +26,7 @@ var Image = /*#__PURE__*/function (_React$Component) {
26
26
  };
27
27
  _this.onResizeStart = function (event) {
28
28
  event.preventDefault();
29
- // event.stopPropagation();
29
+ event.stopPropagation();
30
30
  _this.setState({
31
31
  isResizing: true
32
32
  }, function () {
@@ -464,4 +464,15 @@ export var getFirstTableCell = function getFirstTableCell(element) {
464
464
  tableCellElement = tableCellElement.parentNode;
465
465
  }
466
466
  return tableCellElement;
467
+ };
468
+ export var rowElementHasImage = function rowElementHasImage(element) {
469
+ if (!element) return false;
470
+ if (!Array.isArray(element.children) || element.children.length === 0) return false;
471
+ return element.children.some(function (child) {
472
+ if (child.type === ELEMENT_TYPE.IMAGE) return true;
473
+ if (ObjectUtils.hasProperty(child, 'children')) {
474
+ return rowElementHasImage(child);
475
+ }
476
+ return false;
477
+ });
467
478
  };
@@ -8,6 +8,7 @@ import { useResizeHandlersContext, useTableSelectedRangeContext } from '../../ho
8
8
  import { useScrollContext } from '../../../../../../hooks/use-scroll-context';
9
9
  import { ELEMENT_TYPE } from '../../../../../constants';
10
10
  import { findPath, getSelectedNodeByType } from '../../../../../core';
11
+ import { rowElementHasImage } from '../../../helpers';
11
12
  var RowHeader = function RowHeader(_ref) {
12
13
  var _row$style;
13
14
  var row = _ref.row,
@@ -30,6 +31,18 @@ var RowHeader = function RowHeader(_ref) {
30
31
  var currentCellPath = currentCell ? findPath(editor, currentCell, [-1, -1]) : [-1, -1];
31
32
  var pathLength = currentCellPath.length;
32
33
  useEffect(function () {
34
+ if (rowElementHasImage(row)) {
35
+ var time = setTimeout(function () {
36
+ // There is a delay in image loading
37
+ var rowDom = ReactEditor.toDOMNode(editor, row);
38
+ if (!rowDom) return;
39
+ if (rowHeight === rowDom.clientHeight) return;
40
+ setRowHeight(rowDom.clientHeight);
41
+ }, 300);
42
+ return function () {
43
+ clearTimeout(time);
44
+ };
45
+ }
33
46
  var rowDom = ReactEditor.toDOMNode(editor, row);
34
47
  if (!rowDom) return;
35
48
  if (rowHeight === rowDom.clientHeight) return;
@@ -16,12 +16,15 @@ var TextAlignMenu = /*#__PURE__*/function (_React$Component) {
16
16
  _classCallCheck(this, TextAlignMenu);
17
17
  _this = _super.call(this, props);
18
18
  _this.registerEventHandler = function () {
19
- document.addEventListener('click', _this.onHideTextAlignMenu);
19
+ document.addEventListener('click', _this.onHideTextAlignMenu, true);
20
20
  };
21
21
  _this.unregisterEventHandler = function () {
22
- document.removeEventListener('click', _this.onHideTextAlignMenu);
22
+ document.removeEventListener('click', _this.onHideTextAlignMenu, true);
23
23
  };
24
- _this.onHideTextAlignMenu = function () {
24
+ _this.onHideTextAlignMenu = function (e) {
25
+ var menu = _this.menu;
26
+ var clickIsInMenu = menu && menu.contains(e.target) && menu !== e.target;
27
+ if (clickIsInMenu) return;
25
28
  _this.setState({
26
29
  isDropdownMenuOpen: false
27
30
  }, function () {
@@ -60,6 +63,14 @@ var TextAlignMenu = /*#__PURE__*/function (_React$Component) {
60
63
  _this.setType = function (type) {
61
64
  var editor = _this.props.editor;
62
65
  setAlignType(editor, type);
66
+ _this.setState({
67
+ isDropdownMenuOpen: false
68
+ }, function () {
69
+ _this.unregisterEventHandler();
70
+ });
71
+ };
72
+ _this.setMenuRef = function (ref) {
73
+ _this.menu = ref;
63
74
  };
64
75
  _this.state = {
65
76
  isDropdownMenuOpen: false
@@ -89,6 +100,7 @@ var TextAlignMenu = /*#__PURE__*/function (_React$Component) {
89
100
  }), !disabled && /*#__PURE__*/React.createElement("span", {
90
101
  className: caretIconClass
91
102
  })), isDropdownMenuOpen && /*#__PURE__*/React.createElement("div", {
103
+ ref: this.setMenuRef,
92
104
  className: "align-popover sdoc-dropdown-menu"
93
105
  }, MENUS_CONFIG_MAP[TEXT_ALIGN].map(function (item, index) {
94
106
  return /*#__PURE__*/React.createElement("span", {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seafile/sdoc-editor",
3
- "version": "0.1.81",
3
+ "version": "0.1.82",
4
4
  "private": false,
5
5
  "description": "This is a sdoc editor",
6
6
  "main": "dist/index.js",