@seafile/sdoc-editor 0.1.47 → 0.1.49

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.
@@ -69,3 +69,12 @@
69
69
  font-size: 12px;
70
70
  }
71
71
 
72
+ /* caret */
73
+ .sdoc-editor-container .article .caret-item .caret-name {
74
+ display: none;
75
+ }
76
+
77
+ .sdoc-editor-container .article .caret-item:hover .caret-name {
78
+ display: block;
79
+ }
80
+
@@ -0,0 +1,32 @@
1
+ import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
2
+ import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
3
+ import { Text, Path, Range } from '@seafile/slate';
4
+ export var decorateCursors = function decorateCursors(nodeEntry, storageCursors) {
5
+ var ranges = [];
6
+ var _nodeEntry = _slicedToArray(nodeEntry, 2),
7
+ node = _nodeEntry[0],
8
+ path = _nodeEntry[1];
9
+ var cursors = Object.values(storageCursors || {});
10
+ if (Text.isText(node) && (cursors === null || cursors === void 0 ? void 0 : cursors.length)) {
11
+ cursors.forEach(function (cursor) {
12
+ if (Range.includes(cursor, path)) {
13
+ var focus = cursor.focus,
14
+ anchor = cursor.anchor;
15
+ var isFocusNode = Path.equals(focus.path, path);
16
+ var isAnchorNode = Path.equals(anchor.path, path);
17
+ ranges.push(_objectSpread(_objectSpread({}, cursor), {}, {
18
+ isCaret: isFocusNode,
19
+ anchor: {
20
+ path: path,
21
+ offset: isAnchorNode ? anchor.offset : node.text.length
22
+ },
23
+ focus: {
24
+ path: path,
25
+ offset: isFocusNode ? focus.offset : 0
26
+ }
27
+ }));
28
+ }
29
+ });
30
+ }
31
+ return ranges;
32
+ };
@@ -1,5 +1,4 @@
1
1
  import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
2
- import { Range } from '@seafile/slate';
3
2
  import randomColor from 'randomcolor';
4
3
 
5
4
  // selection: { anchor, focus }
@@ -15,9 +14,7 @@ export var setCursor = function setCursor(editor, operations, user, selection, c
15
14
  var lastCursorOp = cursorOps[cursorOps.length - 1];
16
15
  if (selection) {
17
16
  var newCursor = lastCursorOp && lastCursorOp.newProperties || {};
18
- var newCursorData = _objectSpread(_objectSpread(_objectSpread(_objectSpread({}, oldCursor), newCursor), selection), _objectSpread(_objectSpread({}, cursorData), {}, {
19
- isForward: Range.isForward(selection)
20
- }));
17
+ var newCursorData = _objectSpread(_objectSpread(_objectSpread(_objectSpread({}, oldCursor), newCursor), selection), cursorData);
21
18
  editor.cursors[clientId] = newCursorData;
22
19
  } else {
23
20
  delete editor.cursors[clientId];
@@ -37,7 +34,6 @@ export var generateCursorData = function generateCursorData(config) {
37
34
  var color = randomColor(options);
38
35
  return {
39
36
  name: user.name,
40
- color: color,
41
- alphaColor: color.slice(0, -2) + '0.2)'
37
+ color: color
42
38
  };
43
39
  };
@@ -0,0 +1,25 @@
1
+ import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
2
+ import { useCallback } from 'react';
3
+ import { decorateCursors } from '../cursor/decorate-cursors';
4
+ export var useDecorate = function useDecorate(editor) {
5
+ var cursors = editor.cursors;
6
+ var decorate = useCallback(function (nodeEntry) {
7
+ var ranges = [];
8
+ var addRanges = function addRanges(newRanges) {
9
+ if (newRanges.length) {
10
+ ranges = [].concat(_toConsumableArray(ranges), _toConsumableArray(newRanges));
11
+ }
12
+ };
13
+ console.log('eeee');
14
+ // useCursor
15
+ addRanges(decorateCursors(nodeEntry, cursors));
16
+
17
+ // others decorate
18
+ // ...
19
+
20
+ return ranges;
21
+ }, [cursors]);
22
+ return {
23
+ decorate: decorate
24
+ };
25
+ };
@@ -7,13 +7,13 @@ import React from 'react';
7
7
  import { Node } from '@seafile/slate';
8
8
  import { Editable, Slate, ReactEditor } from '@seafile/slate-react';
9
9
  import { Editor } from '@seafile/slate';
10
- import editor, { renderLeaf as _renderLeaf, renderElement as _renderElement, Toolbar } from './extension';
10
+ import editor, { renderLeaf, renderElement, Toolbar } from './extension';
11
11
  import { withSocketIO } from './socket';
12
12
  import withNodeId from './node-id';
13
13
  import SDocOutline from './outline';
14
14
  import EventProxy from './utils/event-handler';
15
15
  import { focusEditor } from './extension/core';
16
- import { getDecorate } from './cursor/decorate';
16
+ import { uiDecorate } from './decorates';
17
17
  import './assets/css/layout.css';
18
18
  import './assets/css/sdoc-editor-plugins.css';
19
19
  var SDocEditor = /*#__PURE__*/function (_React$Component) {
@@ -65,6 +65,13 @@ var SDocEditor = /*#__PURE__*/function (_React$Component) {
65
65
  }
66
66
  _this.editor.cursors = cursors;
67
67
  _this.eventProxy = new EventProxy(_this.editor);
68
+ _this.renderElement = function (props) {
69
+ return renderElement(props, _this.editor);
70
+ };
71
+ _this.renderLeaf = function (props) {
72
+ return renderLeaf(props, _this.editor);
73
+ };
74
+ _this.decorate = uiDecorate(_this.editor);
68
75
  return _this;
69
76
  }
70
77
  _createClass(SDocEditor, [{
@@ -84,11 +91,9 @@ var SDocEditor = /*#__PURE__*/function (_React$Component) {
84
91
  }, {
85
92
  key: "render",
86
93
  value: function render() {
87
- var _this2 = this;
88
94
  var slateValue = this.state.slateValue;
89
95
  var config = this.props.config;
90
96
  var docUuid = config.docUuid;
91
- var decorate = getDecorate(this.editor);
92
97
  return /*#__PURE__*/React.createElement("div", {
93
98
  className: "sdoc-editor-container"
94
99
  }, /*#__PURE__*/React.createElement(Toolbar, {
@@ -107,15 +112,11 @@ var SDocEditor = /*#__PURE__*/function (_React$Component) {
107
112
  }, /*#__PURE__*/React.createElement("div", {
108
113
  className: "article"
109
114
  }, /*#__PURE__*/React.createElement(Editable, {
110
- renderElement: function renderElement(props) {
111
- return _renderElement(props, _this2.editor);
112
- },
113
- renderLeaf: function renderLeaf(props) {
114
- return _renderLeaf(props, _this2.editor);
115
- },
115
+ renderElement: this.renderElement,
116
+ renderLeaf: this.renderLeaf,
116
117
  onKeyDown: this.eventProxy.onKeyDown,
117
118
  onDOMBeforeInput: this.onDOMBeforeInput,
118
- decorate: decorate
119
+ decorate: this.decorate
119
120
  }))))));
120
121
  }
121
122
  }]);
@@ -0,0 +1,107 @@
1
+ import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
2
+ import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
3
+ var _this = this;
4
+ import React, { useCallback, useEffect, useMemo, useState } from 'react';
5
+ import { Node } from '@seafile/slate';
6
+ import { Editable, Slate, ReactEditor } from '@seafile/slate-react';
7
+ import { Editor } from '@seafile/slate';
8
+ import { useUpdate } from 'ahooks';
9
+ import editor2, { renderLeaf, renderElement, Toolbar } from './extension';
10
+ import { withSocketIO } from './socket';
11
+ import withNodeId from './node-id';
12
+ import SDocOutline from './outline';
13
+ import EventProxy from './utils/event-handler';
14
+ import { focusEditor } from './extension/core';
15
+ import './assets/css/layout.css';
16
+ import './assets/css/sdoc-editor-plugins.css';
17
+ import { useDecorate } from './decorates';
18
+ var SDocEditor = function SDocEditor(_ref) {
19
+ var document = _ref.document,
20
+ config = _ref.config;
21
+ var _useState = useState(document.children),
22
+ _useState2 = _slicedToArray(_useState, 2),
23
+ slateValue = _useState2[0],
24
+ setSlateValue = _useState2[1];
25
+
26
+ // init editor
27
+ var editor = useMemo(function () {
28
+ var newEditor = withNodeId(withSocketIO(editor2, {
29
+ document: document,
30
+ config: config
31
+ }));
32
+ var cursors = document.cursors;
33
+ newEditor.cursors = cursors || {};
34
+ return newEditor;
35
+ // eslint-disable-next-line react-hooks/exhaustive-deps
36
+ }, []);
37
+ var eventProxy = useMemo(function () {
38
+ return new EventProxy(editor);
39
+ // eslint-disable-next-line react-hooks/exhaustive-deps
40
+ }, []);
41
+
42
+ // useMount: init socket connection
43
+ useEffect(function () {
44
+ editor.openConnection();
45
+ return function () {
46
+ editor.closeConnection();
47
+ };
48
+ // eslint-disable-next-line react-hooks/exhaustive-deps
49
+ }, []);
50
+
51
+ // useMount: focus editor
52
+ useEffect(function () {
53
+ if (Node.string(editor) === '') {
54
+ var firstNodePath = ReactEditor.findPath(editor, editor.children[0]);
55
+ focusEditor(_this.editor, firstNodePath);
56
+ }
57
+ }, []);
58
+ var _renderElement = useCallback(function (props) {
59
+ return renderElement(props, editor);
60
+ }, []);
61
+ var _renderLeaf = useCallback(function (props) {
62
+ return renderLeaf(props, editor);
63
+ }, []);
64
+ var onChange = useCallback(function (slateValue) {
65
+ setSlateValue(_toConsumableArray(slateValue));
66
+ }, []);
67
+ var update = useUpdate();
68
+ var onDOMBeforeInput = useCallback(function (e) {
69
+ if (e.data && e.data !== '') {
70
+ var _node$;
71
+ var node = Editor.parent(editor, editor.selection);
72
+ editor.onDOMBeforeInputId = (_node$ = node[0]) === null || _node$ === void 0 ? void 0 : _node$.id;
73
+ update();
74
+ } else {
75
+ editor.onDOMBeforeInputId = null;
76
+ update();
77
+ }
78
+ }, []);
79
+ var _useDecorate = useDecorate(editor),
80
+ decorate = _useDecorate.decorate;
81
+ console.log('dadadihuaile');
82
+ return /*#__PURE__*/React.createElement("div", {
83
+ className: "sdoc-editor-container"
84
+ }, /*#__PURE__*/React.createElement(Toolbar, {
85
+ editor: editor
86
+ }), /*#__PURE__*/React.createElement("div", {
87
+ className: "sdoc-editor-content"
88
+ }, /*#__PURE__*/React.createElement(SDocOutline, {
89
+ doc: slateValue,
90
+ docUuid: config.docUuid
91
+ }), /*#__PURE__*/React.createElement("div", {
92
+ className: "flex-fill o-auto"
93
+ }, /*#__PURE__*/React.createElement(Slate, {
94
+ editor: editor,
95
+ value: slateValue,
96
+ onChange: onChange
97
+ }, /*#__PURE__*/React.createElement("div", {
98
+ className: "article"
99
+ }, /*#__PURE__*/React.createElement(Editable, {
100
+ renderElement: _renderElement,
101
+ renderLeaf: _renderLeaf,
102
+ onKeyDown: eventProxy.onKeyDown,
103
+ onDOMBeforeInput: onDOMBeforeInput,
104
+ decorate: decorate
105
+ }))))));
106
+ };
107
+ export default SDocEditor;
@@ -6,12 +6,12 @@ import renderElement from './render/render-element';
6
6
  import renderLeaf from './render/render-leaf';
7
7
  import Toolbar from './toolbar';
8
8
  var baseEditor = withHistory(withReact(createEditor()));
9
- var editor = Plugins.reduce(function (editor, pluginItem) {
9
+ var editor2 = Plugins.reduce(function (editor, pluginItem) {
10
10
  var withPlugin = pluginItem.editorPlugin;
11
11
  if (withPlugin) {
12
12
  return withPlugin(editor);
13
13
  }
14
14
  return editor;
15
15
  }, baseEditor);
16
- export default editor;
16
+ export default editor2;
17
17
  export { renderLeaf, renderElement, Toolbar };
@@ -13,7 +13,7 @@ var cursorStyleBase = {
13
13
  };
14
14
  var caretStyleBase = {
15
15
  position: 'absolute',
16
- pointerEvents: 'none',
16
+ // pointerEvents: 'none',
17
17
  userSelect: 'none',
18
18
  height: '1.2em',
19
19
  width: 2,
@@ -21,18 +21,19 @@ var caretStyleBase = {
21
21
  };
22
22
  var Caret = function Caret(_ref) {
23
23
  var color = _ref.color,
24
- isForward = _ref.isForward,
25
24
  name = _ref.name;
26
25
  var cursorStyles = _objectSpread(_objectSpread({}, cursorStyleBase), {}, {
27
26
  background: color,
28
- left: isForward ? '100%' : '0%'
27
+ left: '0%',
28
+ cursor: 'default'
29
29
  });
30
30
  var caretStyles = _objectSpread(_objectSpread({}, caretStyleBase), {}, {
31
31
  background: color,
32
- left: isForward ? '100%' : '0%'
32
+ left: '0%'
33
33
  });
34
- caretStyles[isForward ? 'bottom' : 'top'] = 0;
34
+ caretStyles['top'] = 1;
35
35
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("span", {
36
+ className: "caret-item",
36
37
  contentEditable: false,
37
38
  style: caretStyles
38
39
  }, /*#__PURE__*/React.createElement("span", {
@@ -40,6 +41,7 @@ var Caret = function Caret(_ref) {
40
41
  position: 'relative'
41
42
  }
42
43
  }, /*#__PURE__*/React.createElement("span", {
44
+ className: "caret-name",
43
45
  contentEditable: false,
44
46
  style: cursorStyles
45
47
  }, name))));
@@ -39,12 +39,17 @@ var renderText = function renderText(props, editor) {
39
39
  className: "token ".concat(leaf.type)
40
40
  }, markedChildren);
41
41
  }
42
+ var style = {
43
+ position: 'relative'
44
+ };
45
+ if (leaf.isCaret) {
46
+ style['display'] = 'inline-block';
47
+ style['minWidth'] = '2px';
48
+ }
42
49
  return /*#__PURE__*/React.createElement("span", Object.assign({
43
50
  "data-id": leaf.id
44
51
  }, attributes, {
45
- style: {
46
- position: 'relative'
47
- }
52
+ style: style
48
53
  }), leaf.isCaret ? /*#__PURE__*/React.createElement(Caret, leaf) : null, markedChildren);
49
54
  };
50
55
  export default renderText;
@@ -1,4 +1,4 @@
1
- import SDocEditor from './editor';
1
+ import SDocEditor from './editor2';
2
2
  import SDocViewer from './viewer';
3
3
  import SDocOutline from './outline';
4
4
  import EventBus from './utils/event-bus';
@@ -115,7 +115,9 @@ var OutlineItem = /*#__PURE__*/function (_React$PureComponent2) {
115
115
  onClick: this.onItemClick,
116
116
  onMouseOver: this.onMouseOver,
117
117
  onMouseOut: this.onMouseOut
118
- }, children[0].text);
118
+ }, children.map(function (child) {
119
+ return child.text;
120
+ }).join(''));
119
121
  }
120
122
  }]);
121
123
  return OutlineItem;
@@ -262,8 +262,8 @@ export var syncRemoteOperations = function syncRemoteOperations(editor, remoteOp
262
262
  }
263
263
  editor.apply(op);
264
264
  }
265
- var username = context.getSetting('username');
266
- if (user && user.username !== username) {
265
+ var currentUser = editor.user;
266
+ if (user && user.username !== currentUser.username) {
267
267
  setCursor(editor, remoteOperations, user, selection, cursorData);
268
268
  // sync cursor position
269
269
  editor.onChange();
@@ -4,11 +4,13 @@ import SocketManager from './socket-manager';
4
4
  var withSocketIO = function withSocketIO(editor, options) {
5
5
  var onChange = editor.onChange;
6
6
  var newEditor = editor;
7
- var cursorData = generateCursorData(options.config);
8
7
  var socketManager = null;
8
+ var user = options.config.user;
9
+ newEditor.user = user;
9
10
  newEditor.openConnection = function () {
10
11
  var document = options.document,
11
12
  config = options.config;
13
+ var cursorData = generateCursorData(options.config);
12
14
  config['cursorData'] = cursorData;
13
15
  socketManager = SocketManager.getInstance(newEditor, document, config);
14
16
  };
@@ -6,6 +6,7 @@
6
6
  .doc-ops .op-item {
7
7
  margin-left: 1rem;
8
8
  display: flex;
9
+ align-items: center;
9
10
  position: relative;
10
11
  }
11
12
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seafile/sdoc-editor",
3
- "version": "0.1.47",
3
+ "version": "0.1.49",
4
4
  "private": false,
5
5
  "description": "This is a sdoc editor",
6
6
  "main": "dist/index.js",
@@ -10,6 +10,7 @@
10
10
  "@seafile/slate-history": "0.86.2",
11
11
  "@seafile/slate-hyperscript": "0.81.7",
12
12
  "@seafile/slate-react": "0.92.2",
13
+ "ahooks": "3.7.7",
13
14
  "classnames": "2.3.2",
14
15
  "deep-copy": "1.4.2",
15
16
  "is-hotkey": "0.2.0",
@@ -1,35 +0,0 @@
1
- import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
2
- import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
3
- import { Text, Path, Range } from '@seafile/slate';
4
- export var getDecorate = function getDecorate(editor) {
5
- return function (nodeEntry) {
6
- var ranges = [];
7
- var _nodeEntry = _slicedToArray(nodeEntry, 2),
8
- node = _nodeEntry[0],
9
- path = _nodeEntry[1];
10
- var cursors = Object.values(editor.cursors || {});
11
- if (Text.isText(node) && (cursors === null || cursors === void 0 ? void 0 : cursors.length)) {
12
- cursors.forEach(function (cursor) {
13
- if (Range.includes(cursor, path)) {
14
- var focus = cursor.focus,
15
- anchor = cursor.anchor,
16
- isForward = cursor.isForward;
17
- var isFocusNode = Path.equals(focus.path, path);
18
- var isAnchorNode = Path.equals(anchor.path, path);
19
- ranges.push(_objectSpread(_objectSpread({}, cursor), {}, {
20
- isCaret: isFocusNode,
21
- anchor: {
22
- path: path,
23
- offset: isAnchorNode ? anchor.offset : isForward ? 0 : node.text.length
24
- },
25
- focus: {
26
- path: path,
27
- offset: isFocusNode ? focus.offset : isForward ? node.text.length : 0
28
- }
29
- }));
30
- }
31
- });
32
- }
33
- return ranges;
34
- };
35
- };