@seafile/sdoc-editor 0.1.45 → 0.1.47

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.
@@ -19,6 +19,6 @@
19
19
  color: #333;
20
20
  }
21
21
 
22
- .sdoc-editor-page-header .doc-info .sdocfont {
23
- font-size: 18px;
22
+ .sdoc-editor-page-header .doc-info .sdoc-link {
23
+ font-size: 14px;
24
24
  }
@@ -32,3 +32,7 @@
32
32
  border: 1px solid #e5e6e8;
33
33
  box-shadow: 0 0 15px rgba(0, 0, 0, 0.06);
34
34
  }
35
+
36
+ .sdoc-editor-container .sdoc-editor-content .article > div {
37
+ caret-color: blue;
38
+ }
@@ -5,25 +5,28 @@ import randomColor from 'randomcolor';
5
5
  // selection: { anchor, focus }
6
6
  // cursor: { anchor, focus }
7
7
 
8
- export var setCursor = function setCursor(id, editor, operations, cursorData) {
8
+ export var setCursor = function setCursor(editor, operations, user, selection, cursorData) {
9
+ var clientId = user.username;
9
10
  var cursorOps = operations.filter(function (operation) {
10
11
  return operation.type === 'set_selection';
11
12
  });
12
13
  if (!editor.cursors) editor.cursors = {};
13
- var oldCursor = editor.cursors[id] ? editor.cursors[id] : {};
14
+ var oldCursor = editor.cursors[clientId] ? editor.cursors[clientId] : {};
14
15
  var lastCursorOp = cursorOps[cursorOps.length - 1];
15
- var selection = editor.selection;
16
16
  if (selection) {
17
17
  var newCursor = lastCursorOp && lastCursorOp.newProperties || {};
18
18
  var newCursorData = _objectSpread(_objectSpread(_objectSpread(_objectSpread({}, oldCursor), newCursor), selection), _objectSpread(_objectSpread({}, cursorData), {}, {
19
19
  isForward: Range.isForward(selection)
20
20
  }));
21
- editor.cursors[id] = newCursorData;
21
+ editor.cursors[clientId] = newCursorData;
22
22
  } else {
23
- delete editor.cursors[id];
23
+ delete editor.cursors[clientId];
24
24
  }
25
25
  return editor;
26
26
  };
27
+ export var deleteCursor = function deleteCursor(editor, username) {
28
+ delete editor.cursors[username];
29
+ };
27
30
  export var generateCursorData = function generateCursorData(config) {
28
31
  var user = config.user;
29
32
  var options = {
@@ -46,7 +46,9 @@ var SDocEditor = /*#__PURE__*/function (_React$Component) {
46
46
  });
47
47
  }
48
48
  };
49
- var children = props.document.children;
49
+ var _props$document = props.document,
50
+ children = _props$document.children,
51
+ cursors = _props$document.cursors;
50
52
  _this.state = {
51
53
  slateValue: children,
52
54
  isLoading: true
@@ -61,6 +63,7 @@ var SDocEditor = /*#__PURE__*/function (_React$Component) {
61
63
  config: config
62
64
  });
63
65
  }
66
+ _this.editor.cursors = cursors;
64
67
  _this.eventProxy = new EventProxy(_this.editor);
65
68
  return _this;
66
69
  }
@@ -85,7 +88,7 @@ var SDocEditor = /*#__PURE__*/function (_React$Component) {
85
88
  var slateValue = this.state.slateValue;
86
89
  var config = this.props.config;
87
90
  var docUuid = config.docUuid;
88
- var decorate = getDecorate(editor);
91
+ var decorate = getDecorate(this.editor);
89
92
  return /*#__PURE__*/React.createElement("div", {
90
93
  className: "sdoc-editor-container"
91
94
  }, /*#__PURE__*/React.createElement(Toolbar, {
@@ -1,6 +1,8 @@
1
1
  export var BLOCKQUOTE = 'blockquote';
2
2
  export var BOLD = 'bold';
3
3
  export var ITALIC = 'italic';
4
+ export var UNDERLINE = 'underline';
5
+ export var STRIKETHROUGH = 'strikethrough';
4
6
  export var HEADER = 'header';
5
7
  export var HEADER1 = 'header1';
6
8
  export var HEADER2 = 'header2';
@@ -2,7 +2,7 @@ import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
2
2
  var _MENUS_CONFIG_MAP, _HEADER_TITLE_MAP;
3
3
  // extension plugin
4
4
  import * as ELEMENT_TYPE from './element-type';
5
- import { BLOCKQUOTE, BOLD, ITALIC, HEADER, HEADER1, HEADER2, HEADER3, HEADER4, HEADER5, HEADER6, ORDERED_LIST, UNORDERED_LIST, LIST_ITEM, LIST_LIC, CHECK_LIST, CHECK_LIST_ITEM, PARAGRAPH, LINK, HTML, CODE_BLOCK, CODE_LINE, IMAGE, TABLE, TABLE_CELL, TABLE_ROW, FORMULA, COLUMN, TEXT_STYLE, BOLD_ITALIC } from './element-type';
5
+ import { BLOCKQUOTE, HEADER, HEADER1, HEADER2, HEADER3, HEADER4, HEADER5, HEADER6, PARAGRAPH, BOLD, ITALIC, UNDERLINE, STRIKETHROUGH, 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, BOLD_ITALIC } from './element-type';
6
6
  import KEYBOARD from './keyboard';
7
7
 
8
8
  // history
@@ -59,6 +59,16 @@ export var MENUS_CONFIG_MAP = (_MENUS_CONFIG_MAP = {}, _defineProperty(_MENUS_CO
59
59
  iconClass: 'sdocfont sdoc-bold',
60
60
  text: 'bold',
61
61
  type: 'BOLD'
62
+ }, {
63
+ id: UNDERLINE,
64
+ iconClass: 'sdocfont sdoc-underline',
65
+ text: 'underline',
66
+ type: 'UNDERLINE'
67
+ }, {
68
+ id: STRIKETHROUGH,
69
+ iconClass: 'sdocfont sdoc-strikethrough',
70
+ text: 'strikethrough',
71
+ type: 'STRIKETHROUGH'
62
72
  }]), _defineProperty(_MENUS_CONFIG_MAP, UNDO, {
63
73
  id: UNDO,
64
74
  iconClass: 'sdocfont sdoc-revoke',
@@ -90,4 +100,4 @@ export var TABLE_ELEMENT_POSITION = {
90
100
  AFTER: 'after',
91
101
  BEFORE: 'before'
92
102
  };
93
- export { BLOCKQUOTE, BOLD, ITALIC, HEADER, HEADER1, HEADER2, HEADER3, HEADER4, HEADER5, HEADER6, ORDERED_LIST, UNORDERED_LIST, LIST_ITEM, LIST_LIC, CHECK_LIST, CHECK_LIST_ITEM, PARAGRAPH, LINK, HTML, CODE_BLOCK, CODE_LINE, IMAGE, TABLE, TABLE_CELL, TABLE_ROW, FORMULA, COLUMN, TEXT_STYLE, BOLD_ITALIC, ELEMENT_TYPE, KEYBOARD };
103
+ export { BLOCKQUOTE, HEADER, HEADER1, HEADER2, HEADER3, HEADER4, HEADER5, HEADER6, PARAGRAPH, BOLD, ITALIC, UNDERLINE, STRIKETHROUGH, 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, BOLD_ITALIC, ELEMENT_TYPE, KEYBOARD };
@@ -2,6 +2,7 @@
2
2
  padding: 8px 0;
3
3
  }
4
4
 
5
- .sdoc-table-menu-group .sdocfont {
5
+ .sdoc-table-menu-group .sdoc-drop-down,
6
+ .sdoc-table-menu-group .sdoc-caret-up {
6
7
  transform: scale(.8);
7
8
  }
@@ -11,10 +11,13 @@ import { getValue, isMenuDisabled, addMark, removeMark } from '../helpers';
11
11
  var TextStyleMenuList = /*#__PURE__*/function (_React$Component) {
12
12
  _inherits(TextStyleMenuList, _React$Component);
13
13
  var _super = _createSuper(TextStyleMenuList);
14
- function TextStyleMenuList(props) {
14
+ function TextStyleMenuList() {
15
15
  var _this;
16
16
  _classCallCheck(this, TextStyleMenuList);
17
- _this = _super.call(this, props);
17
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
18
+ args[_key] = arguments[_key];
19
+ }
20
+ _this = _super.call.apply(_super, [this].concat(args));
18
21
  _this.isActive = function (editor, type) {
19
22
  var isMark = getValue(editor, type);
20
23
  return !!isMark;
@@ -36,43 +39,36 @@ var TextStyleMenuList = /*#__PURE__*/function (_React$Component) {
36
39
  }
37
40
  focusEditor(editor);
38
41
  };
39
- _this.state = {
40
- isShowLinkDialog: false
41
- };
42
42
  return _this;
43
43
  }
44
44
  _createClass(TextStyleMenuList, [{
45
45
  key: "getTextStyleMenuList",
46
46
  value: function getTextStyleMenuList() {
47
+ var _this2 = this;
47
48
  var _this$props = this.props,
48
49
  isRichEditor = _this$props.isRichEditor,
49
50
  className = _this$props.className,
50
51
  editor = _this$props.editor;
51
- var textStyleMenuList = [{
52
- isRichEditor: isRichEditor,
53
- className: className,
54
- disabled: this.isDisabled(),
55
- isActive: this.isActive(editor, 'ITALIC'),
56
- onMouseDown: this.onMouseDown
57
- }, {
58
- isRichEditor: isRichEditor,
59
- className: className,
60
- disabled: this.isDisabled(),
61
- isActive: this.isActive(editor, 'BOLD'),
62
- onMouseDown: this.onMouseDown
63
- }];
64
- return textStyleMenuList;
52
+ var list = MENUS_CONFIG_MAP[TEXT_STYLE].map(function (item) {
53
+ var itemProps = {
54
+ isRichEditor: isRichEditor,
55
+ className: className,
56
+ disabled: _this2.isDisabled(),
57
+ isActive: _this2.isActive(editor, item.type),
58
+ onMouseDown: _this2.onMouseDown
59
+ };
60
+ return _objectSpread(_objectSpread({}, itemProps), item);
61
+ });
62
+ return list;
65
63
  }
66
64
  }, {
67
65
  key: "render",
68
66
  value: function render() {
69
67
  var textStyleMenuList = this.getTextStyleMenuList();
70
- return /*#__PURE__*/React.createElement(React.Fragment, null, textStyleMenuList.map(function (menuItem, index) {
71
- var menuItemConfig = MENUS_CONFIG_MAP[TEXT_STYLE][index];
72
- var menuItemProps = _objectSpread(_objectSpread({}, menuItem), menuItemConfig);
68
+ return /*#__PURE__*/React.createElement(React.Fragment, null, textStyleMenuList.map(function (itemProps, index) {
73
69
  return /*#__PURE__*/React.createElement(MenuItem, Object.assign({
74
70
  key: index
75
- }, menuItemProps));
71
+ }, itemProps));
76
72
  }));
77
73
  }
78
74
  }]);
@@ -8,12 +8,26 @@ var renderText = function renderText(props, editor) {
8
8
  if (leaf.BOLD) {
9
9
  markedChildren = /*#__PURE__*/React.createElement("strong", null, markedChildren);
10
10
  }
11
- if (leaf.CODE) {
12
- markedChildren = /*#__PURE__*/React.createElement("code", null, markedChildren);
13
- }
14
11
  if (leaf.ITALIC) {
15
12
  markedChildren = /*#__PURE__*/React.createElement("i", null, markedChildren);
16
13
  }
14
+ if (leaf.UNDERLINE) {
15
+ markedChildren = /*#__PURE__*/React.createElement("span", {
16
+ style: {
17
+ textDecoration: 'underline'
18
+ }
19
+ }, markedChildren);
20
+ }
21
+ if (leaf.STRIKETHROUGH) {
22
+ markedChildren = /*#__PURE__*/React.createElement("span", {
23
+ style: {
24
+ textDecoration: 'line-through'
25
+ }
26
+ }, markedChildren);
27
+ }
28
+ if (leaf.CODE) {
29
+ markedChildren = /*#__PURE__*/React.createElement("code", null, markedChildren);
30
+ }
17
31
  if (leaf.DELETE) {
18
32
  markedChildren = /*#__PURE__*/React.createElement("del", null, markedChildren);
19
33
  }
@@ -4,6 +4,7 @@ import { Editor, Operation } from '@seafile/slate';
4
4
  import { getNode } from '../extension/core';
5
5
  import * as OPERATION from '../node-id/constants';
6
6
  import { setCursor } from '../cursor/helper';
7
+ import context from '../../context';
7
8
  export var getNodePathById = function getNodePathById(rootNode, nodeId) {
8
9
  var path = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
9
10
  if (rootNode.id === nodeId) return path;
@@ -251,7 +252,7 @@ export var reExecRevertOperationList = function reExecRevertOperationList(editor
251
252
  _loop2();
252
253
  }
253
254
  };
254
- export var syncRemoteOperations = function syncRemoteOperations(editor, remoteOperations, user) {
255
+ export var syncRemoteOperations = function syncRemoteOperations(editor, remoteOperations, user, selection, cursorData) {
255
256
  if (remoteOperations.length === 0) return;
256
257
  Editor.withoutNormalizing(editor, function () {
257
258
  for (var i = 0; i < remoteOperations.length; i++) {
@@ -261,6 +262,11 @@ export var syncRemoteOperations = function syncRemoteOperations(editor, remoteOp
261
262
  }
262
263
  editor.apply(op);
263
264
  }
264
- setCursor(user.username, editor, remoteOperations);
265
+ var username = context.getSetting('username');
266
+ if (user && user.username !== username) {
267
+ setCursor(editor, remoteOperations, user, selection, cursorData);
268
+ // sync cursor position
269
+ editor.onChange();
270
+ }
265
271
  });
266
272
  };
@@ -78,13 +78,14 @@ var SocketClient = /*#__PURE__*/_createClass(function SocketClient(config) {
78
78
  var socketManager = SocketManager.getInstance();
79
79
  socketManager.dispatchConnectState('leave-room', username);
80
80
  };
81
- this.sendOperations = function (operations, version, callback) {
81
+ this.sendOperations = function (operations, version, selection, callback) {
82
82
  debug('=========== send operations ==========');
83
83
  debug('%O', operations);
84
84
  debug('======================================');
85
85
  _this.socket.emit('update-document', _this.getParams({
86
86
  operations: operations,
87
- version: version
87
+ version: version,
88
+ selection: selection
88
89
  }), function (result) {
89
90
  callback && callback(result);
90
91
  });
@@ -4,6 +4,7 @@ import EventBus from '../utils/event-bus';
4
4
  import { syncRemoteOperations, reExecRevertOperationList, revertOperationList } from './helpers';
5
5
  import SocketClient from './socket-client';
6
6
  import debug from '../utils/debug';
7
+ import { deleteCursor } from '../cursor/helper';
7
8
  var SocketManager = /*#__PURE__*/_createClass(function SocketManager(editor, document, config) {
8
9
  var _this = this;
9
10
  _classCallCheck(this, SocketManager);
@@ -28,7 +29,8 @@ var SocketManager = /*#__PURE__*/_createClass(function SocketManager(editor, doc
28
29
  _this.dispatchConnectState('is-saving');
29
30
  var version = _this.document.version;
30
31
  var operations = _this.pendingOperationList.shift();
31
- _this.socketClient.sendOperations(operations, version, _this.sendOperationsCallback);
32
+ var selection = _this.editor.selection;
33
+ _this.socketClient.sendOperations(operations, version, selection, _this.sendOperationsCallback);
32
34
  };
33
35
  this.sendOperationsCallback = function (result) {
34
36
  if (result && result.success) {
@@ -84,10 +86,12 @@ var SocketManager = /*#__PURE__*/_createClass(function SocketManager(editor, doc
84
86
 
85
87
  // 2. execute operations
86
88
  var operations = params.operations,
87
- user = params.user;
89
+ user = params.user,
90
+ selection = params.selection,
91
+ cursorData = params.cursor_data;
88
92
  // 2.1 Update content & version
89
93
  debug('execute remote operations: %O', operations);
90
- syncRemoteOperations(_this.editor, operations, user);
94
+ syncRemoteOperations(_this.editor, operations, user, selection, cursorData);
91
95
 
92
96
  // 2.2 Update document
93
97
  _this.document.version = serverVersion;
@@ -158,6 +162,10 @@ var SocketManager = /*#__PURE__*/_createClass(function SocketManager(editor, doc
158
162
  });
159
163
  };
160
164
  this.dispatchConnectState = function (type, message) {
165
+ if (type === 'leave-room') {
166
+ deleteCursor(_this.editor, message);
167
+ _this.editor.onChange();
168
+ }
161
169
  _this.eventBus.dispatch(type, message);
162
170
  };
163
171
  this.closeSocketConnect = function () {
@@ -1,5 +1,5 @@
1
1
  var _this = this;
2
- import { generateCursorData, setCursor } from '../cursor/helper';
2
+ import { generateCursorData } from '../cursor/helper';
3
3
  import SocketManager from './socket-manager';
4
4
  var withSocketIO = function withSocketIO(editor, options) {
5
5
  var onChange = editor.onChange;
@@ -21,9 +21,6 @@ var withSocketIO = function withSocketIO(editor, options) {
21
21
  if (!newEditor.isRemote && operations.length > 0) {
22
22
  var _socketManager = SocketManager.getInstance();
23
23
  _socketManager.addOperations && _socketManager.addOperations(operations);
24
- var config = options.config;
25
- var clientId = config.user.username;
26
- setCursor(clientId, editor, operations, cursorData);
27
24
  }
28
25
  onChange();
29
26
  };
@@ -68,7 +68,8 @@ var SimpleEditor = /*#__PURE__*/function (_React$Component) {
68
68
  if (result && !result.children) {
69
69
  result = {
70
70
  version: 0,
71
- children: result.content
71
+ children: result.content,
72
+ cursors: result.cursors || {}
72
73
  };
73
74
  }
74
75
  this.setState({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seafile/sdoc-editor",
3
- "version": "0.1.45",
3
+ "version": "0.1.47",
4
4
  "private": false,
5
5
  "description": "This is a sdoc editor",
6
6
  "main": "dist/index.js",
@@ -1,6 +1,8 @@
1
1
  {
2
2
  "bold": "Bold",
3
3
  "italic": "Italic",
4
+ "underline": "Underline",
5
+ "strikethrough": "Strikethrough",
4
6
  "inline_code": "Code",
5
7
  "header_one": "Heading 1",
6
8
  "header_two": "Heading 2",