@seafile/sdoc-editor 0.2.31 → 0.3.1

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.
@@ -6,6 +6,7 @@ import { getNodeById, focusEditor, findPath } from '../../../extension/core';
6
6
  import { useScrollContext } from '../../../hooks/use-scroll-context';
7
7
  import { getElementCommentCountTop } from '../../helper';
8
8
  import { eventStopPropagation } from '../../../utils/mouse-event';
9
+ import { ELEMENT_TYPE } from '../../../extension/constants';
9
10
  var ElementCommentCount = function ElementCommentCount(_ref) {
10
11
  var elementId = _ref.elementId,
11
12
  commentsCount = _ref.commentsCount;
@@ -20,8 +21,9 @@ var ElementCommentCount = function ElementCommentCount(_ref) {
20
21
  eventStopPropagation(event);
21
22
  var path = findPath(editor, element);
22
23
  var endOfFirstNode = Editor.end(editor, path);
24
+ var startOfFirstNode = Editor.start(editor, path);
23
25
  var range = {
24
- anchor: endOfFirstNode,
26
+ anchor: [ELEMENT_TYPE.LIST_ITEM, ELEMENT_TYPE.ORDERED_LIST, ELEMENT_TYPE.UNORDERED_LIST].includes(element.type) ? startOfFirstNode : endOfFirstNode,
25
27
  focus: endOfFirstNode
26
28
  };
27
29
  focusEditor(editor, range);
@@ -11,6 +11,8 @@ export var INTERNAL_EVENT = {
11
11
  COMMENT_LIST_CLICK: 'comment_list_click',
12
12
  UNSEEN_NOTIFICATIONS_COUNT: 'unseen_notifications_count'
13
13
  };
14
+ export var REVISION_DIFF_KEY = 'diff';
15
+ export var REVISION_DIFF_VALUE = '1';
14
16
  export var PAGE_EDIT_AREA_WIDTH = 672; // 672 = 794 - 2[borderLeft + borderRight] - 120[paddingLeft + paddingRight]
15
17
 
16
18
  export var MODIFY_TYPE = {
@@ -47,7 +47,6 @@ var InsertElementDialog = function InsertElementDialog(_ref) {
47
47
  return function () {
48
48
  toggleDialogSubscribe();
49
49
  };
50
-
51
50
  // eslint-disable-next-line react-hooks/exhaustive-deps
52
51
  }, []);
53
52
  var toggleDialog = useCallback(function (_ref2) {
@@ -50,7 +50,6 @@ export var getType = function getType(editor) {
50
50
  };
51
51
  export var insertFileLink = function insertFileLink(editor, text, uuid) {
52
52
  if (isMenuDisabled(editor)) return;
53
-
54
53
  // Selection folded or not
55
54
  var selection = editor.selection;
56
55
  if (selection == null) return;
@@ -80,4 +80,26 @@ export var getListType = function getListType(editor, type) {
80
80
  };
81
81
  export var setListType = function setListType(editor, type) {
82
82
  toggleList(editor, type);
83
+ };
84
+ export var getBeforeText = function getBeforeText(editor) {
85
+ var selection = editor.selection;
86
+ if (selection == null) return {
87
+ beforeText: '',
88
+ range: null
89
+ };
90
+ var anchor = selection.anchor;
91
+ // Find the near text node above the current text
92
+ var _Editor$above = Editor.above(editor),
93
+ _Editor$above2 = _slicedToArray(_Editor$above, 2),
94
+ aboveNodePath = _Editor$above2[1];
95
+ var aboveNodeStartPoint = Editor.start(editor, aboveNodePath); // The starting position of the text node
96
+ var range = {
97
+ anchor: anchor,
98
+ focus: aboveNodeStartPoint
99
+ };
100
+ var beforeText = Editor.string(editor, range) || '';
101
+ return {
102
+ beforeText: beforeText,
103
+ range: range
104
+ };
83
105
  };
@@ -2,10 +2,12 @@ import { insertBreakList } from './insert-break-list';
2
2
  import { onTabHandle } from './on-tab-handle';
3
3
  import { normalizeList } from './normalize-list';
4
4
  import { insertFragmentList } from './insert-fragment-list';
5
+ import { handleShortcut } from './shortcut';
5
6
  var withList = function withList(editor) {
6
7
  var insertBreak = editor.insertBreak,
7
8
  deleteBackWord = editor.deleteBackWord,
8
- handleTab = editor.handleTab;
9
+ handleTab = editor.handleTab,
10
+ insertText = editor.insertText;
9
11
  var newEditor = editor;
10
12
  newEditor.insertBreak = function () {
11
13
  if (insertBreakList(editor)) return;
@@ -31,6 +33,11 @@ var withList = function withList(editor) {
31
33
  };
32
34
  newEditor.insertFragment = insertFragmentList(newEditor);
33
35
  newEditor.normalizeNode = normalizeList(editor);
36
+ newEditor.insertText = function (text) {
37
+ var isPreventInsert = handleShortcut(newEditor, text);
38
+ if (isPreventInsert) return;
39
+ return insertText(text);
40
+ };
34
41
  return newEditor;
35
42
  };
36
43
  export default withList;
@@ -0,0 +1,79 @@
1
+ import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
2
+ import { Editor, Path, Range, Transforms } from '@seafile/slate';
3
+ import { ORDERED_LIST, PARAGRAPH } from '../../../constants';
4
+ import { getBeforeText, setListType } from '../helpers';
5
+ import { focusEditor, getLastChild, getPreviousPath } from '../../../core';
6
+ import { generateEmptyListItem } from '../model';
7
+
8
+ /**
9
+ * @param {Editor} editor
10
+ * @param {String} text
11
+ * @returns {Boolean} isPreventInsert
12
+ */
13
+ export var handleShortcut = function handleShortcut(editor, text) {
14
+ if (text !== ' ') return false;
15
+ var selection = editor.selection;
16
+ if (!Range.isCollapsed(selection)) return false;
17
+ var _Editor$above = Editor.above(editor),
18
+ _Editor$above2 = _slicedToArray(_Editor$above, 2),
19
+ aboveNode = _Editor$above2[0],
20
+ aboveNodePath = _Editor$above2[1];
21
+ var aboveNodeRef = Editor.pathRef(editor, aboveNodePath);
22
+ if (aboveNode.type !== PARAGRAPH) return false;
23
+ // Match ordered list shortcut
24
+ var regShortcut = /^\s*[1-9]+\.\s*$/;
25
+ var _getBeforeText = getBeforeText(editor),
26
+ beforeText = _getBeforeText.beforeText,
27
+ range = _getBeforeText.range;
28
+ var matchResult = beforeText.match(regShortcut);
29
+ var matchedText = matchResult && matchResult[0];
30
+ // If the match fails or the match is not at the beginning of the line, it is not a shortcut
31
+ if (!matchResult || matchResult.index !== 0) return false;
32
+ var previousNodePath = getPreviousPath(aboveNodePath);
33
+ var _Editor$node = Editor.node(editor, previousNodePath),
34
+ _Editor$node2 = _slicedToArray(_Editor$node, 2),
35
+ previousNode = _Editor$node2[0],
36
+ previousPath = _Editor$node2[1];
37
+ // If the previous node is not an ordered list and is not start with `1.`,it is not a shortcut
38
+ if (previousNode.type !== ORDERED_LIST && matchedText !== '1.') return false;
39
+ // If the previous node is not an ordered list and is start with `1.`,transforms to ordered list
40
+ if (previousNode.type !== ORDERED_LIST && matchedText === '1.') {
41
+ // Delete shortcut key text
42
+ Transforms.delete(editor, {
43
+ at: range
44
+ });
45
+ setListType(editor, ORDERED_LIST);
46
+ focusEditor(editor);
47
+ return;
48
+ }
49
+ // Record the order number of the shortcut that will be inserted as a list item
50
+ var shortcutOrderNum = parseInt(matchResult[0].slice(0, -1));
51
+
52
+ // Check If order number is continuous
53
+ if (previousNode.children.length + 1 !== shortcutOrderNum) return false;
54
+
55
+ // Delete shortcut key text
56
+ Transforms.delete(editor, {
57
+ at: range
58
+ });
59
+ // Update aboveNode after delete shortcut text
60
+ var _Editor$above3 = Editor.above(editor);
61
+ var _Editor$above4 = _slicedToArray(_Editor$above3, 1);
62
+ aboveNode = _Editor$above4[0];
63
+ var _getLastChild = getLastChild([previousNode, previousPath]),
64
+ _getLastChild2 = _slicedToArray(_getLastChild, 2),
65
+ lastListItemPath = _getLastChild2[1];
66
+ var targetInsertPath = Path.next(lastListItemPath);
67
+ // Wrap the paragraph in a list item
68
+ var insertedListItem = generateEmptyListItem();
69
+ insertedListItem.children.push(aboveNode);
70
+ Transforms.insertNodes(editor, insertedListItem, {
71
+ at: targetInsertPath
72
+ });
73
+ Transforms.removeNodes(editor, {
74
+ at: aboveNodeRef.unref()
75
+ });
76
+ // Set the selection to the end of the inserted list item
77
+ Transforms.select(editor, Editor.end(editor, targetInsertPath));
78
+ return true;
79
+ };
@@ -1,11 +1,12 @@
1
+ import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
1
2
  import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
2
3
  import { ReactEditor } from '@seafile/slate-react';
3
- import { Editor, Transforms, Range } from '@seafile/slate';
4
+ import { Editor, Transforms, Range, Text } from '@seafile/slate';
4
5
  import slugid from 'slugid';
5
6
  import copy from 'copy-to-clipboard';
6
7
  import context from '../../../../context';
7
8
  import { SDOC_LINK, LINK, INSERT_FILE_DISPLAY_TYPE, CODE_BLOCK, CODE_LINE, PARAGRAPH } from '../../constants';
8
- import { getNodeType, getSelectedElems } from '../../core';
9
+ import { focusEditor, getNodeType, getSelectedElems } from '../../core';
9
10
  export var isMenuDisabled = function isMenuDisabled(editor, readonly) {
10
11
  if (readonly) return true;
11
12
  if (editor.selection == null) return true;
@@ -26,7 +27,7 @@ export var generateSdocFileNode = function generateSdocFileNode(uuid, text) {
26
27
  type: SDOC_LINK,
27
28
  doc_uuid: uuid,
28
29
  title: text,
29
- display_type: INSERT_FILE_DISPLAY_TYPE[0],
30
+ display_type: INSERT_FILE_DISPLAY_TYPE[1],
30
31
  children: [{
31
32
  id: slugid.nice(),
32
33
  text: text || ''
@@ -50,11 +51,13 @@ export var getType = function getType(editor) {
50
51
  };
51
52
  export var insertSdocFileLink = function insertSdocFileLink(editor, text, uuid) {
52
53
  if (isMenuDisabled(editor)) return;
53
-
54
54
  // Selection folded or not
55
55
  var selection = editor.selection;
56
56
  if (selection == null) return;
57
57
  var isCollapsed = Range.isCollapsed(selection);
58
+
59
+ // Remove shortcut symbol,if trigger by shortcut
60
+ removeShortCutSymbol(editor);
58
61
  if (isCollapsed) {
59
62
  // Insert Spaces before and after sdoclinks for easy operation
60
63
  editor.insertText(' ');
@@ -121,4 +124,58 @@ export var onCopySdocLinkNode = function onCopySdocLinkNode(editor, element) {
121
124
  });
122
125
  }
123
126
  });
127
+ };
128
+ export var getBeforeText = function getBeforeText(editor) {
129
+ var selection = editor.selection;
130
+ if (selection == null) return {
131
+ beforeText: '',
132
+ range: null
133
+ };
134
+ var anchor = selection.anchor;
135
+ // Find the near text node above the current text
136
+ var _Editor$nodes3 = Editor.nodes(editor, {
137
+ match: function match(node) {
138
+ return Text.isText(node);
139
+ },
140
+ mode: 'lowest'
141
+ }),
142
+ _Editor$nodes4 = _slicedToArray(_Editor$nodes3, 1),
143
+ _Editor$nodes4$ = _slicedToArray(_Editor$nodes4[0], 2),
144
+ beforeNodePath = _Editor$nodes4$[1];
145
+ var beforeNodeStartPoint = Editor.start(editor, beforeNodePath); // The starting position of the text node
146
+ var range = {
147
+ anchor: anchor,
148
+ focus: beforeNodeStartPoint
149
+ };
150
+ var beforeText = Editor.string(editor, range) || '';
151
+ return {
152
+ beforeText: beforeText,
153
+ range: range
154
+ };
155
+ };
156
+ export var isTriggeredByShortCut = function isTriggeredByShortCut(editor) {
157
+ var _getBeforeText = getBeforeText(editor),
158
+ beforeText = _getBeforeText.beforeText;
159
+ return beforeText.slice(-2) === '[[';
160
+ };
161
+
162
+ // If insert operation is triggered by shortcut, remove the '[[' symbol
163
+ export var removeShortCutSymbol = function removeShortCutSymbol(editor) {
164
+ // Check is trigger by short cut
165
+ var selection = editor.selection;
166
+ var _getBeforeText2 = getBeforeText(editor),
167
+ beforeText = _getBeforeText2.beforeText,
168
+ beforeRange = _getBeforeText2.range;
169
+ var isTrrigeredByShortCut = beforeText.slice(-3) === '[[ ';
170
+ isTrrigeredByShortCut && Transforms.delete(editor, {
171
+ at: {
172
+ anchor: {
173
+ path: beforeRange.focus.path,
174
+ offset: beforeText.length - 3
175
+ },
176
+ focus: _objectSpread({}, selection.focus)
177
+ },
178
+ voids: true
179
+ });
180
+ focusEditor(editor);
124
181
  };
@@ -1,8 +1,12 @@
1
1
  import { Transforms, Node, Editor } from '@seafile/slate';
2
- import { SDOC_LINK } from '../../constants';
2
+ import { ELEMENT_TYPE, SDOC_LINK } from '../../constants';
3
+ import EventBus from '../../../utils/event-bus';
4
+ import { INTERNAL_EVENT } from '../../../constants';
5
+ import { insertSdocFileLink, isTriggeredByShortCut } from './helpers';
3
6
  var withSdocLink = function withSdocLink(editor) {
4
7
  var isInline = editor.isInline,
5
- deleteBackward = editor.deleteBackward;
8
+ deleteBackward = editor.deleteBackward,
9
+ onHotKeyDown = editor.onHotKeyDown;
6
10
  var newEditor = editor;
7
11
 
8
12
  // Rewrite isInline
@@ -35,6 +39,19 @@ var withSdocLink = function withSdocLink(editor) {
35
39
  }
36
40
  return deleteBackward(unit);
37
41
  };
42
+ newEditor.onHotKeyDown = function (event) {
43
+ var key = event.key;
44
+ if (key !== ' ') return onHotKeyDown && onHotKeyDown(event);
45
+ // If user press whitespace after '[[', open file modal
46
+ var eventBus = EventBus.getInstance();
47
+ if (isTriggeredByShortCut(newEditor)) {
48
+ eventBus.dispatch(INTERNAL_EVENT.INSERT_ELEMENT, {
49
+ type: ELEMENT_TYPE.SDOC_LINK,
50
+ insertSdocFileLinkCallback: insertSdocFileLink
51
+ });
52
+ }
53
+ return onHotKeyDown && onHotKeyDown(event);
54
+ };
38
55
  return newEditor;
39
56
  };
40
57
  export default withSdocLink;
@@ -1,15 +1,59 @@
1
- import React, { useCallback } from 'react';
1
+ import _createForOfIteratorHelper from "@babel/runtime/helpers/esm/createForOfIteratorHelper";
2
+ import React, { useCallback, useEffect } from 'react';
2
3
  import { useTranslation } from 'react-i18next';
3
4
  import Switch from '../../../switch';
4
5
  import Tooltip from '../../../tooltip';
6
+ import { REVISION_DIFF_KEY, REVISION_DIFF_VALUE } from '../../../../basic-sdk/constants';
5
7
  import './index.css';
6
8
  var ViewChanges = function ViewChanges(_ref) {
7
9
  var isShowChanges = _ref.isShowChanges,
8
10
  propsOnViewChangesToggle = _ref.onViewChangesToggle;
9
11
  var _useTranslation = useTranslation(),
10
12
  t = _useTranslation.t;
13
+ useEffect(function () {
14
+ var url = new URL(window.location.href);
15
+ var searchParams = new URLSearchParams(url.search);
16
+ if (!searchParams.has(REVISION_DIFF_KEY)) return;
17
+ var firstLoadValue = searchParams.get(REVISION_DIFF_KEY);
18
+ if (firstLoadValue === REVISION_DIFF_VALUE) {
19
+ propsOnViewChangesToggle(true);
20
+ }
21
+ // eslint-disable-next-line react-hooks/exhaustive-deps
22
+ }, []);
11
23
  var onViewChangesToggle = useCallback(function () {
12
- propsOnViewChangesToggle(!isShowChanges);
24
+ var nextIsShowChanges = !isShowChanges;
25
+ var url = new URL(window.location.href);
26
+ var searchParams = new URLSearchParams(url.search);
27
+ var newParamsString = '';
28
+ var _iterator = _createForOfIteratorHelper(searchParams.entries()),
29
+ _step;
30
+ try {
31
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
32
+ var item = _step.value;
33
+ if (item[0] !== REVISION_DIFF_KEY) {
34
+ if (newParamsString) {
35
+ newParamsString = newParamsString + "&".concat(item[0], "=").concat(item[1]);
36
+ } else {
37
+ newParamsString = "".concat(item[0], "=").concat(item[1]);
38
+ }
39
+ }
40
+ }
41
+ } catch (err) {
42
+ _iterator.e(err);
43
+ } finally {
44
+ _iterator.f();
45
+ }
46
+ if (!searchParams.has(REVISION_DIFF_KEY) && nextIsShowChanges) {
47
+ if (newParamsString) {
48
+ newParamsString = newParamsString + "&".concat(REVISION_DIFF_KEY, "=").concat(REVISION_DIFF_VALUE);
49
+ } else {
50
+ newParamsString = "".concat(REVISION_DIFF_KEY, "=").concat(REVISION_DIFF_VALUE);
51
+ }
52
+ }
53
+ var validPathName = url.pathname.endsWith('/') ? url.pathname : url.pathname + '/';
54
+ var newURL = "".concat(url.origin).concat(validPathName).concat(newParamsString ? '?' + newParamsString : '');
55
+ window.history.replaceState(null, null, newURL);
56
+ propsOnViewChangesToggle(nextIsShowChanges);
13
57
  // eslint-disable-next-line react-hooks/exhaustive-deps
14
58
  }, [isShowChanges, propsOnViewChangesToggle]);
15
59
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seafile/sdoc-editor",
3
- "version": "0.2.31",
3
+ "version": "0.3.1",
4
4
  "private": false,
5
5
  "description": "This is a sdoc editor",
6
6
  "main": "dist/index.js",