@seafile/sdoc-editor 0.5.52 → 0.5.55

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.
@@ -70,6 +70,7 @@ const CommentArticle = _ref => {
70
70
  value: slateValue,
71
71
  onChange: updateSlateValue
72
72
  }, /*#__PURE__*/React.createElement(Editable, {
73
+ id: "sdoc-editor",
73
74
  scrollSelectionIntoView: handleScrollIntoView,
74
75
  cursors: cursors,
75
76
  renderElement: props => RenderCommentEditorCustomRenderElement(_objectSpread(_objectSpread({}, props), {}, {
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ const InlineBugFixer = () => {
3
+ return /*#__PURE__*/React.createElement("span", {
4
+ contentEditable: false,
5
+ style: {
6
+ fontSize: 0
7
+ }
8
+ }, String.fromCodePoint(160) /* Non-breaking space */);
9
+ };
10
+
11
+ export default InlineBugFixer;
@@ -56,5 +56,5 @@ export const MOUSE_ENTER_EVENT_DISABLED_MAP = {
56
56
  [HEADER6]: [CALL_OUT],
57
57
  [CALL_OUT]: [CALL_OUT]
58
58
  };
59
- export const ROOT_ELEMENT_TYPES = [PARAGRAPH, TITLE, SUBTITLE, CHECK_LIST_ITEM, ORDERED_LIST, UNORDERED_LIST, BLOCKQUOTE, HEADER1, HEADER2, HEADER3, HEADER4, HEADER5, HEADER6, CALL_OUT, TABLE];
59
+ export const ROOT_ELEMENT_TYPES = [PARAGRAPH, TITLE, SUBTITLE, CHECK_LIST_ITEM, ORDERED_LIST, UNORDERED_LIST, BLOCKQUOTE, HEADER1, HEADER2, HEADER3, HEADER4, HEADER5, HEADER6, CALL_OUT, TABLE, CODE_BLOCK];
60
60
  export { ELEMENT_TYPE, BLOCKQUOTE, TITLE, SUBTITLE, HEADER, HEADER1, HEADER2, HEADER3, HEADER4, HEADER5, HEADER6, PARAGRAPH, ORDERED_LIST, UNORDERED_LIST, LIST_ITEM, CHECK_LIST_ITEM, CODE_BLOCK, CODE_LINE, TABLE, TABLE_CELL, TABLE_ROW, LINK, SDOC_LINK, FILE_LINK, IMAGE, IMAGE_BLOCK, TOP_LEVEL_TYPES, INLINE_LEVEL_TYPES, CALL_OUT, MENTION, MENTION_TEMP, FILE_LINK_INSET_INPUT_TEMP };
@@ -20,7 +20,8 @@ const ImageHoverMenu = _ref => {
20
20
  parentNodeEntry,
21
21
  imageCaptionInputRef,
22
22
  onHideImageHoverMenu,
23
- t
23
+ t,
24
+ readonly
24
25
  } = _ref;
25
26
  const {
26
27
  data,
@@ -152,7 +153,7 @@ const ImageHoverMenu = _ref => {
152
153
  style: menuPosition
153
154
  }, /*#__PURE__*/React.createElement("div", {
154
155
  className: "hover-menu-container"
155
- }, type !== TABLE && /*#__PURE__*/React.createElement("span", {
156
+ }, type !== TABLE && !readonly && /*#__PURE__*/React.createElement("span", {
156
157
  className: "op-group-item"
157
158
  }, /*#__PURE__*/React.createElement("span", {
158
159
  role: "button",
@@ -166,7 +167,7 @@ const ImageHoverMenu = _ref => {
166
167
  className: "mr-1"
167
168
  }, t(type === IMAGE_BLOCK ? 'Block' : 'Inline')), /*#__PURE__*/React.createElement("i", {
168
169
  className: "sdocfont sdoc-drop-down icon-font"
169
- }))), /*#__PURE__*/React.createElement("span", {
170
+ }))), !readonly && /*#__PURE__*/React.createElement("span", {
170
171
  className: "op-group-item"
171
172
  }, type === IMAGE_BLOCK && /*#__PURE__*/React.createElement("span", {
172
173
  role: "button",
@@ -254,12 +254,13 @@ const Image = _ref => {
254
254
  onCompositionStart: e => {
255
255
  e.stopPropagation();
256
256
  }
257
- }))), children), isSelected && isShowImageHoverMenu && !readOnly && /*#__PURE__*/React.createElement(ImageHoverMenu, {
257
+ }))), children), isShowImageHoverMenu && /*#__PURE__*/React.createElement(ImageHoverMenu, {
258
258
  editor: editor,
259
259
  menuPosition: menuPosition,
260
260
  element: element,
261
261
  parentNodeEntry: nodeEntry,
262
262
  imageCaptionInputRef: imageCaptionInputRef,
263
+ readonly: readOnly,
263
264
  onHideImageHoverMenu: () => {
264
265
  setIsShowImageHoverMenu(false);
265
266
  }
@@ -66,10 +66,6 @@ export const insertLink = function (editor, title, url) {
66
66
  }
67
67
  const p = generateEmptyElement(ELEMENT_TYPE.PARAGRAPH);
68
68
  p.children[1] = linkNode;
69
- p.children[2] = {
70
- id: slugid.nice(),
71
- text: ' '
72
- };
73
69
  Transforms.insertNodes(editor, p, {
74
70
  at: [path[0] + 1]
75
71
  });
@@ -85,12 +81,6 @@ export const insertLink = function (editor, title, url) {
85
81
  if (isCollapsed) {
86
82
  const linkNode = genLinkNode(url, title);
87
83
  Transforms.insertNodes(editor, linkNode);
88
-
89
- // Not being able to use insertText directly causes the added Spaces to be added to the linked text, as in the issue above, replaced by insertFragment
90
- editor.insertFragment([{
91
- id: slugid.nice(),
92
- text: ' '
93
- }]);
94
84
  } else {
95
85
  const selectedText = Editor.string(editor, selection); // Selected text
96
86
  if (selectedText !== title) {
@@ -1,5 +1,4 @@
1
- import { Transforms, Node, Editor, Range } from '@seafile/slate';
2
- import slugid from 'slugid';
1
+ import { Transforms, Node, Editor, Range, Element } from '@seafile/slate';
3
2
  import isUrl from 'is-url';
4
3
  import context from '../../../../context';
5
4
  import { insertSdocFileLink } from '../sdoc-link/helpers';
@@ -12,7 +11,6 @@ const withLink = editor => {
12
11
  normalizeNode,
13
12
  isInline,
14
13
  insertData,
15
- insertText,
16
14
  insertFragment
17
15
  } = editor;
18
16
  const newEditor = editor;
@@ -27,17 +25,6 @@ const withLink = editor => {
27
25
  }
28
26
  return isInline(elem);
29
27
  };
30
- newEditor.insertText = text => {
31
- const path = Editor.path(editor, editor.selection);
32
- if (Range.isCollapsed(editor.selection) && getSelectedNodeByType(editor, LINK) && Editor.isEnd(editor, editor.selection.focus, path)) {
33
- editor.insertFragment([{
34
- id: slugid.nice(),
35
- text: text
36
- }]);
37
- return;
38
- }
39
- return insertText(text);
40
- };
41
28
  newEditor.insertData = data => {
42
29
  // Paste link content
43
30
  const text = data.getData('text/plain');
@@ -95,6 +82,20 @@ const withLink = editor => {
95
82
  }
96
83
  return normalizeNode([node, path]);
97
84
  };
85
+ editor.onCompositionStart = e => {
86
+ const {
87
+ selection
88
+ } = editor;
89
+ if (Range.isCollapsed(selection)) {
90
+ const [LinkNodeEntry] = Editor.nodes(editor, {
91
+ match: n => Element.isElement && n.type === LINK
92
+ });
93
+ if (LinkNodeEntry) {
94
+ e.preventDefault();
95
+ return true;
96
+ }
97
+ }
98
+ };
98
99
  return newEditor;
99
100
  };
100
101
  export default withLink;
@@ -6,6 +6,7 @@ import LinkHover from './hover';
6
6
  import EventBus from '../../../utils/event-bus';
7
7
  import { INTERNAL_EVENT } from '../../../constants';
8
8
  import { ELEMENT_TYPE } from '../../constants';
9
+ import InlineBugFixer from '../../commons/Inline-bug-fix-wrapper';
9
10
  class LinkHoverMenuComponent extends React.Component {
10
11
  constructor(props) {
11
12
  super(props);
@@ -95,7 +96,7 @@ class LinkHoverMenuComponent extends React.Component {
95
96
  }), /*#__PURE__*/React.createElement("span", {
96
97
  className: "virtual-link",
97
98
  title: element.title
98
- }, children)), isShowLinkMenu && (this.props.readonly || Range.isCollapsed(editor.selection)) && /*#__PURE__*/React.createElement(LinkHover, {
99
+ }, /*#__PURE__*/React.createElement(InlineBugFixer, null), children, /*#__PURE__*/React.createElement(InlineBugFixer, null))), isShowLinkMenu && (this.props.readonly || Range.isCollapsed(editor.selection)) && /*#__PURE__*/React.createElement(LinkHover, {
99
100
  editor: editor,
100
101
  menuPosition: menuPosition,
101
102
  element: element,
@@ -1878,4 +1878,34 @@ export const getTableColumnSelectedRange = (table, columnIndex) => {
1878
1878
  minColIndex,
1879
1879
  maxColIndex
1880
1880
  };
1881
+ };
1882
+ export const isTableWidthFitScreen = editor => {
1883
+ const {
1884
+ table
1885
+ } = getSelectedInfo(editor);
1886
+ const tableNode = ReactEditor.toDOMNode(editor, table);
1887
+ if (!tableNode) return;
1888
+ const tableDom = tableNode.querySelector('.sdoc-table-scroll-wrapper');
1889
+ const {
1890
+ width: tableWidth
1891
+ } = tableDom.getBoundingClientRect();
1892
+ const sdocWidth = editor.width;
1893
+ if (tableWidth >= sdocWidth) return true;
1894
+ return false;
1895
+ };
1896
+ export const fitTableColumnToScreen = editor => {
1897
+ const {
1898
+ table,
1899
+ tablePath
1900
+ } = getSelectedInfo(editor);
1901
+ const colCount = table.columns.length;
1902
+ const columnWidth = Math.max(TABLE_CELL_MIN_WIDTH, parseInt(editor.width / colCount));
1903
+ const columns = table.columns.map(column => _objectSpread(_objectSpread({}, column), {}, {
1904
+ width: columnWidth
1905
+ }));
1906
+ Transforms.setNodes(editor, {
1907
+ columns
1908
+ }, {
1909
+ at: tablePath
1910
+ });
1881
1911
  };
@@ -6,7 +6,7 @@ import { ElementPopover } from '../../../../commons';
6
6
  import { ELEMENT_TYPE } from '../../../../constants';
7
7
  import { getSelectedNodeByType } from '../../../../core';
8
8
  import { TABLE_MAX_COLUMNS, TABLE_MAX_ROWS, TABLE_ELEMENT, TABLE_ELEMENT_POSITION, EMPTY_SELECTED_RANGE } from '../../constants';
9
- import { insertTableElement, removeTableElement, combineCells } from '../../helpers';
9
+ import { insertTableElement, removeTableElement, combineCells, isTableWidthFitScreen, fitTableColumnToScreen } from '../../helpers';
10
10
  import InsertTableElement from './insert-table-element';
11
11
  import EventBus from '../../../../../utils/event-bus';
12
12
  import { INTERNAL_EVENT } from '../../../../../constants';
@@ -66,7 +66,8 @@ class TableContextMenu extends React.Component {
66
66
  });
67
67
  });
68
68
  this.state = {
69
- contextStyle: {}
69
+ contextStyle: {},
70
+ isDisableFitTableWidthToScreen: false
70
71
  };
71
72
  this.position = null;
72
73
  this.eventBus = EventBus.getInstance();
@@ -97,7 +98,8 @@ class TableContextMenu extends React.Component {
97
98
  }
98
99
  render() {
99
100
  const {
100
- contextStyle
101
+ contextStyle,
102
+ isDisableFitTableWidthToScreen
101
103
  } = this.state;
102
104
  const {
103
105
  editor,
@@ -118,6 +120,17 @@ class TableContextMenu extends React.Component {
118
120
  const enableCombineCell = !ObjectUtils.isSameObject(tableSelectedRange, EMPTY_SELECTED_RANGE);
119
121
  const enableSplitCell = !enableCombineCell;
120
122
  const isMergedCell = this.isMergedCell();
123
+
124
+ // Check if the table width is fit to screen
125
+ // Use queueMicrotask to resolve the issue that the table cell combined or split, the table width is not updated immediately
126
+ queueMicrotask(() => {
127
+ const isDisable = isTableWidthFitScreen(editor);
128
+ if (isDisableFitTableWidthToScreen !== isDisable) {
129
+ this.setState({
130
+ isDisableFitTableWidthToScreen: isTableWidthFitScreen(editor)
131
+ });
132
+ }
133
+ });
121
134
  return /*#__PURE__*/React.createElement(ElementPopover, {
122
135
  className: "sdoc-context-menu"
123
136
  }, /*#__PURE__*/React.createElement("div", {
@@ -160,7 +173,13 @@ class TableContextMenu extends React.Component {
160
173
  className: "dropdown-item",
161
174
  disabled: !isMergedCell || !enableSplitCell,
162
175
  onMouseDown: this.toggleSplitCellSettingDialog
163
- }, t('Split_cell'))));
176
+ }, t('Split_cell')), /*#__PURE__*/React.createElement("div", {
177
+ className: 'seafile-divider dropdown-divider'
178
+ }), /*#__PURE__*/React.createElement("button", {
179
+ className: "dropdown-item",
180
+ disabled: isDisableFitTableWidthToScreen,
181
+ onMouseDown: () => fitTableColumnToScreen(editor)
182
+ }, t('Fit_table_to_page_width'))));
164
183
  }
165
184
  }
166
185
  export default withTranslation('sdoc-editor')(TableContextMenu);
@@ -16,6 +16,14 @@ const renderText = (props, editor) => {
16
16
  rest = _objectWithoutProperties(leaf, _excluded);
17
17
  let markedChildren = React.cloneElement(children);
18
18
  let style = {};
19
+ // The following is a workaround for a Chromium bug where,
20
+ // if you have an inline at the end of a block,
21
+ // clicking the end of a block puts the cursor inside the inline
22
+ // instead of inside the final {text: ''} node
23
+ // https://github.com/ianstormtaylor/slate/issues/4704#issuecomment-1006696364
24
+ if (!text.length) {
25
+ style['paddingLeft'] = '0.1px';
26
+ }
19
27
  if (leaf.isCaret) {
20
28
  style['position'] = 'relative';
21
29
  style['display'] = 'inline-block';
@@ -19,12 +19,13 @@ const generatorDiffTextElement = function (textElement, diffType) {
19
19
  };
20
20
  export const getTopLevelChanges = changes => {
21
21
  const topLevelChanges = [];
22
+ const articleEl = document.getElementById('sdoc-editor');
22
23
  changes.forEach(item => {
23
24
  let dom = document.querySelectorAll("[data-id=\"".concat(item, "\"]"))[0];
24
25
  if (!dom) return [];
25
- while (((_dom = dom) === null || _dom === void 0 ? void 0 : (_dom$dataset = _dom.dataset) === null || _dom$dataset === void 0 ? void 0 : _dom$dataset.root) !== 'true') {
26
- var _dom, _dom$dataset, _dom2;
27
- if (!((_dom2 = dom) === null || _dom2 === void 0 ? void 0 : _dom2.parentNode) || dom instanceof Document) break;
26
+ while (((_dom = dom) === null || _dom === void 0 ? void 0 : (_dom$dataset = _dom.dataset) === null || _dom$dataset === void 0 ? void 0 : _dom$dataset.root) !== 'true' || ((_dom2 = dom) === null || _dom2 === void 0 ? void 0 : _dom2.parentNode) !== articleEl) {
27
+ var _dom, _dom$dataset, _dom2, _dom3;
28
+ if (!((_dom3 = dom) === null || _dom3 === void 0 ? void 0 : _dom3.parentNode) || dom instanceof Document) break;
28
29
  const parentNode = dom.parentNode;
29
30
  if (parentNode instanceof Document) {
30
31
  break;
@@ -18,6 +18,7 @@ const ReadOnlyArticle = _ref => {
18
18
  }, /*#__PURE__*/React.createElement(ArticleContainer, {
19
19
  editor: editor
20
20
  }, /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement(SetNodeToDecorations, null), /*#__PURE__*/React.createElement(Editable, {
21
+ id: "sdoc-editor",
21
22
  readOnly: true,
22
23
  placeholder: "",
23
24
  renderElement: renderElement,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seafile/sdoc-editor",
3
- "version": "0.5.52",
3
+ "version": "0.5.55",
4
4
  "private": false,
5
5
  "description": "This is a sdoc editor",
6
6
  "main": "dist/index.js",
@@ -47,7 +47,7 @@
47
47
  "scripts": {
48
48
  "clean": "rm -rf dist && mkdir dist",
49
49
  "start.bak": "node scripts/start.js",
50
- "start": "export NODE_ENV=development LOG_ENV=rc && node dev-server.js",
50
+ "start": "cross-env NODE_ENV=development node dev-server.js",
51
51
  "build": "node scripts/build.js",
52
52
  "pub:dist": "export BABEL_ENV=production && ./node_modules/.bin/babel src --out-dir dist --copy-files",
53
53
  "push-translate": "tx push -s",
@@ -92,6 +92,7 @@
92
92
  "case-sensitive-paths-webpack-plugin": "2.2.0",
93
93
  "clean-webpack-plugin": "4.0.0",
94
94
  "core-js": "2.6.12",
95
+ "cross-env": "^7.0.3",
95
96
  "css-loader": "^6.5.1",
96
97
  "css-minimizer-webpack-plugin": "5.0.1",
97
98
  "dotenv": "6.2.0",
@@ -456,5 +456,6 @@
456
456
  "Print": "Print",
457
457
  "Enter_more_character_start_search": "Enter more characters to start search",
458
458
  "Create_file_name_sdoc": "Create {{file_name_sdoc}}",
459
- "Source_document_changed_tip": "Original document has concurrent modifications. Do you like to merge these modifications to the revision?"
459
+ "Source_document_changed_tip": "Original document has concurrent modifications. Do you like to merge these modifications to the revision?",
460
+ "Fit_table_to_page_width": "Fit table to page width"
460
461
  }
@@ -456,5 +456,6 @@
456
456
  "Print": "打印",
457
457
  "Enter_more_character_start_search": "输入更多字符开始搜索",
458
458
  "Create_file_name_sdoc": "新建 {{file_name_sdoc}}",
459
- "Source_document_changed_tip": "源文档有并发的改动。你需要合并这些改动到修订稿吗?"
459
+ "Source_document_changed_tip": "源文档有并发的改动。你需要合并这些改动到修订稿吗?",
460
+ "Fit_table_to_page_width": "自动适应页面宽度"
460
461
  }