@seafile/sdoc-editor 0.1.5 → 0.1.6

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.
@@ -0,0 +1,22 @@
1
+ .code-block-container {
2
+ position: relative;
3
+ }
4
+
5
+ .language-type {
6
+ font-size: 12px;
7
+ position: absolute;
8
+ right: 0;
9
+ top: 0;
10
+ }
11
+
12
+ .language-type select {
13
+ background-color: #eeeeee;
14
+ cursor: pointer;
15
+ appearance: none;
16
+ outline: none;
17
+ -moz-appearance: none;
18
+ -webkit-appearance: none;
19
+ border: none;
20
+ border-radius: 4px;
21
+ padding: 0 5px;
22
+ }
@@ -3,7 +3,7 @@
3
3
  padding-inline-start: 24px;
4
4
  }
5
5
 
6
- .sf-editor-container {
6
+ .sdoc-editor-container {
7
7
  flex: 1;
8
8
  display: flex;
9
9
  flex-direction: column;
@@ -11,7 +11,7 @@
11
11
  min-height: 0;
12
12
  }
13
13
 
14
- .sf-editor-container .sf-editor-toolbar {
14
+ .sdoc-editor-container .sdoc-editor-toolbar {
15
15
  display: flex;
16
16
  justify-content: center;
17
17
  height: 39px;
@@ -23,13 +23,13 @@
23
23
  box-shadow: 0 3px 2px -2px rgb(200 200 200 / 15%)
24
24
  }
25
25
 
26
- .sf-editor-container .sf-editor-content {
26
+ .sdoc-editor-container .sdoc-editor-content {
27
27
  flex: 1;
28
28
  height: 100%;
29
29
  overflow: auto;
30
30
  }
31
31
 
32
- .sf-editor-container .sf-editor-content .editor-article {
32
+ .sdoc-editor-container .sdoc-editor-content .article {
33
33
  max-width: 950px;
34
34
  min-height: calc(100% - 40px);
35
35
  margin: 20px auto;
@@ -0,0 +1,10 @@
1
+ /* header */
2
+ .sdoc-editor-container .article h2 {
3
+ border-bottom: none;
4
+ }
5
+
6
+ /* list */
7
+ .sdoc-editor-container .article .list-container {
8
+ margin: 0;
9
+ padding-inline-start: 24px;
10
+ }
@@ -49,4 +49,4 @@
49
49
 
50
50
  .header-menu .header-popover .header-menu-item:hover {
51
51
  background-color: rgb(245, 245, 245);
52
- }
52
+ }
package/dist/config.js ADDED
@@ -0,0 +1,16 @@
1
+ var serverConfig = {
2
+ //serviceUrl: "http://127.0.0.1:8000",
3
+ serviceUrl: "http://192.168.1.100:8000",
4
+ username: "lj@11.com",
5
+ password: "11",
6
+ repoID: "79d1fa93-4b5f-4d6c-8fb5-ad3958e1fa47",
7
+ userInfo: {
8
+ username: 'lj@11.com',
9
+ name: 'lj-',
10
+ contact_email: 'lj@11.com'
11
+ },
12
+ filePath: '/xxx.md',
13
+ fileName: 'xxx.md',
14
+ dirPath: '/'
15
+ };
16
+ export { serverConfig };
package/dist/editor.js CHANGED
@@ -8,7 +8,8 @@ import isHotkey from 'is-hotkey';
8
8
  import editor, { renderLeaf as _renderLeaf, renderElement as _renderElement, Toolbar } from './extension';
9
9
  import { SocketManager, withSocketIO } from './socket';
10
10
  import withNodeId from './node-id';
11
- import './assets/css/sdoc-editor.css';
11
+ import './assets/css/layout.css';
12
+ import './assets/css/sdoc-editor-content.css';
12
13
  var SDocEditor = /*#__PURE__*/function (_React$Component) {
13
14
  _inherits(SDocEditor, _React$Component);
14
15
  var _super = _createSuper(SDocEditor);
@@ -51,21 +52,19 @@ var SDocEditor = /*#__PURE__*/function (_React$Component) {
51
52
  key: "render",
52
53
  value: function render() {
53
54
  var _this2 = this;
54
- var _this$state = this.state,
55
- slateValue = _this$state.slateValue,
56
- isEditorBlur = _this$state.isEditorBlur;
55
+ var slateValue = this.state.slateValue;
57
56
  return /*#__PURE__*/React.createElement("div", {
58
- className: "sf-editor-container"
57
+ className: "sdoc-editor-container"
59
58
  }, /*#__PURE__*/React.createElement(Toolbar, {
60
59
  editor: this.editor
61
60
  }), /*#__PURE__*/React.createElement("div", {
62
- className: "sf-editor-content"
61
+ className: "sdoc-editor-content"
63
62
  }, /*#__PURE__*/React.createElement(Slate, {
64
63
  editor: this.editor,
65
64
  value: slateValue,
66
65
  onChange: this.onChange
67
66
  }, /*#__PURE__*/React.createElement("div", {
68
- className: "editor-article"
67
+ className: "article"
69
68
  }, /*#__PURE__*/React.createElement(Editable, {
70
69
  placeholder: "Enter some text...",
71
70
  renderElement: function renderElement(props) {
@@ -2,7 +2,8 @@ import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
2
2
  var _MENUS_CONFIG_MAP, _HEADER_TITLE_MAP;
3
3
  // extension plugin
4
4
  export var BLOCKQUOTE = 'blockquote';
5
- export var BLOB = 'blob';
5
+ export var BOLD = 'blod';
6
+ export var ITALIC = 'italic';
6
7
  export var HEADER = 'header';
7
8
  export var HEADER1 = 'header1';
8
9
  export var HEADER2 = 'header2';
@@ -27,6 +28,7 @@ export var TABLE_CELL = 'table-cell';
27
28
  export var TABLE_ROW = 'table-row';
28
29
  export var FORMULA = 'formula';
29
30
  export var COLUMN = 'column';
31
+ export var TEXTSTYLE = 'text-style';
30
32
 
31
33
  // menus config
32
34
  export var MENUS_CONFIG_MAP = (_MENUS_CONFIG_MAP = {}, _defineProperty(_MENUS_CONFIG_MAP, BLOCKQUOTE, {
@@ -45,9 +47,23 @@ export var MENUS_CONFIG_MAP = (_MENUS_CONFIG_MAP = {}, _defineProperty(_MENUS_CO
45
47
  id: CHECK_LIST,
46
48
  iconClass: 'iconfont icon-check-square',
47
49
  text: 'check_list_item'
50
+ }), _defineProperty(_MENUS_CONFIG_MAP, CODE_BLOCK, {
51
+ id: CODE_BLOCK,
52
+ iconClass: 'iconfont icon-code-block',
53
+ text: 'code-block'
48
54
  }), _defineProperty(_MENUS_CONFIG_MAP, LINK, {
49
55
  id: LINK,
50
56
  iconClass: 'iconfont icon-link',
51
57
  text: 'link'
52
- }), _MENUS_CONFIG_MAP);
58
+ }), _defineProperty(_MENUS_CONFIG_MAP, TEXTSTYLE, [{
59
+ id: ITALIC,
60
+ iconClass: 'iconfont icon-italic',
61
+ text: 'italic',
62
+ type: 'ITALIC'
63
+ }, {
64
+ id: BOLD,
65
+ iconClass: 'iconfont icon-bold',
66
+ text: 'bold',
67
+ type: 'BOLD'
68
+ }]), _MENUS_CONFIG_MAP);
53
69
  export var HEADER_TITLE_MAP = (_HEADER_TITLE_MAP = {}, _defineProperty(_HEADER_TITLE_MAP, HEADER1, 'header_1'), _defineProperty(_HEADER_TITLE_MAP, HEADER2, 'header_2'), _defineProperty(_HEADER_TITLE_MAP, HEADER3, 'header_3'), _defineProperty(_HEADER_TITLE_MAP, HEADER4, 'header_4'), _defineProperty(_HEADER_TITLE_MAP, HEADER5, 'header_5'), _defineProperty(_HEADER_TITLE_MAP, HEADER6, 'header_6'), _defineProperty(_HEADER_TITLE_MAP, PARAGRAPH, 'paragraph'), _HEADER_TITLE_MAP);
@@ -153,6 +153,14 @@ export var getSelectedElems = function getSelectedElems(editor) {
153
153
  }
154
154
  return elems;
155
155
  };
156
+ export var genEmptyParagraph = function genEmptyParagraph() {
157
+ return {
158
+ type: 'paragraph',
159
+ children: [{
160
+ text: ''
161
+ }]
162
+ };
163
+ };
156
164
 
157
165
  // siblings
158
166
  export var getNextSiblingNodes = function getNextSiblingNodes(ancestorEntry, path) {
@@ -324,4 +332,9 @@ export var isSelectionAtBlockStart = function isSelectionAtBlockStart(editor, op
324
332
  var path = (_getAboveBlockNode2 = getAboveBlockNode(editor, options)) === null || _getAboveBlockNode2 === void 0 ? void 0 : _getAboveBlockNode2[1];
325
333
  if (!path) return false;
326
334
  return isStartPoint(editor, selection.focus, path) || Range.isExpanded(editor.selection) && isStartPoint(editor, selection.anchor, path);
335
+ };
336
+ export var isLastNode = function isLastNode(editor, node) {
337
+ var editorChildren = editor.children || [];
338
+ var editorChildrenLength = editorChildren.length;
339
+ return editorChildren[editorChildrenLength - 1] === node;
327
340
  };
@@ -13,7 +13,7 @@ var MenuItem = /*#__PURE__*/function (_React$Component) {
13
13
  _this = _super.call(this, props);
14
14
  _this.onMouseDown = function (event) {
15
15
  if (_this.props.disabled) return;
16
- _this.props.onMouseDown(event);
16
+ _this.props.onMouseDown(event, _this.props.type);
17
17
  };
18
18
  _this.onClick = function (event) {
19
19
  event.stopPropagation();
@@ -26,7 +26,7 @@ export var isMenuDisabled = function isMenuDisabled(editor) {
26
26
  var notMatch = selectedElements.some(function (element) {
27
27
  if (Editor.isVoid(editor, element) && Editor.isBlock(editor, element)) return true;
28
28
  var type = element.type;
29
- if (['pre', 'code', 'list-item'].includes(type)) return true;
29
+ if (['code-line', 'code-block', 'list-item'].includes(type)) return true;
30
30
  return false;
31
31
  });
32
32
  if (notMatch) return true;
@@ -0,0 +1,106 @@
1
+ import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
2
+ import _createForOfIteratorHelper from "@babel/runtime/helpers/esm/createForOfIteratorHelper";
3
+ import { Transforms, Editor, Node } from '@seafile/slate';
4
+ import { CODE_BLOCK, PARAGRAPH } from '../../constants';
5
+ import { getNodeType, getSelectedNodeByType, getSelectedElems } from '../../core';
6
+ export var isMenuDisabled = function isMenuDisabled(editor) {
7
+ var selection = editor.selection;
8
+ if (selection == null) return true;
9
+ var selectedElems = getSelectedElems(editor);
10
+ var hasVoid = selectedElems.some(function (elem) {
11
+ return editor.isVoid(elem);
12
+ });
13
+ if (hasVoid) return true;
14
+ var isMatch = selectedElems.some(function (elem) {
15
+ var type = getNodeType(elem);
16
+ if (type === CODE_BLOCK || type === PARAGRAPH) return true;
17
+ return false;
18
+ });
19
+ if (isMatch) return false; // enable
20
+ return true; // disable
21
+ };
22
+
23
+ export var getSelectCodeElem = function getSelectCodeElem(editor) {
24
+ var codeNode = getSelectedNodeByType(editor, CODE_BLOCK);
25
+ if (codeNode == null) return null;
26
+ return codeNode;
27
+ };
28
+ export var updateLanguageSetting = function updateLanguageSetting(editor, language) {
29
+ Transforms.setNodes(editor, {
30
+ language: language
31
+ }, {
32
+ mode: 'highest'
33
+ });
34
+ };
35
+ export var changeToCodeBlock = function changeToCodeBlock(editor, language) {
36
+ // Summarizes the strings for the selected highest-level node
37
+ var strArr = [];
38
+ var nodeEntries = Editor.nodes(editor, {
39
+ match: function match(n) {
40
+ return editor.children.includes(n);
41
+ },
42
+ // Matches the selected node at the highest level
43
+ universal: true
44
+ });
45
+ var _iterator = _createForOfIteratorHelper(nodeEntries),
46
+ _step;
47
+ try {
48
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
49
+ var nodeEntry = _step.value;
50
+ var _nodeEntry = _slicedToArray(nodeEntry, 1),
51
+ n = _nodeEntry[0];
52
+ if (n) strArr.push(Node.string(n));
53
+ }
54
+
55
+ // Deletes the selected node at the highest level
56
+ } catch (err) {
57
+ _iterator.e(err);
58
+ } finally {
59
+ _iterator.f();
60
+ }
61
+ Transforms.removeNodes(editor, {
62
+ mode: 'highest'
63
+ });
64
+
65
+ // Insert the codeBlockNode node
66
+ var newCodeBlockNode = {
67
+ type: CODE_BLOCK,
68
+ children: [{
69
+ type: 'code-line',
70
+ children: [{
71
+ text: strArr.join('\n')
72
+ } // Select the plain text of the node
73
+ ]
74
+ }],
75
+
76
+ language: language
77
+ };
78
+ Transforms.insertNodes(editor, newCodeBlockNode, {
79
+ mode: 'highest'
80
+ });
81
+ };
82
+ export var changeToPlainText = function changeToPlainText(editor) {
83
+ var elem = getSelectCodeElem(editor);
84
+ if (elem == null) return;
85
+
86
+ // Get code text
87
+ var str = Node.string(elem);
88
+
89
+ // Delete the highest level node, -> "the code-block node"
90
+ Transforms.removeNodes(editor, {
91
+ mode: 'highest'
92
+ });
93
+
94
+ // Insert p node
95
+ var pList = str.split('\n').map(function (s) {
96
+ return {
97
+ type: 'paragraph',
98
+ children: [{
99
+ text: s
100
+ }]
101
+ };
102
+ });
103
+ Transforms.insertNodes(editor, pList, {
104
+ mode: 'highest'
105
+ });
106
+ };
@@ -0,0 +1,12 @@
1
+ import { CODE_BLOCK } from '../../constants';
2
+ import CodeBlockMenu from './menu';
3
+ import withCodeBlock from './plugin';
4
+ import { renderCodeBlock } from './render-elem';
5
+ var CodeBlockPlugin = {
6
+ type: CODE_BLOCK,
7
+ nodeType: 'element',
8
+ editorMenus: [CodeBlockMenu],
9
+ editorPlugin: withCodeBlock,
10
+ renderElements: [renderCodeBlock]
11
+ };
12
+ export default CodeBlockPlugin;
@@ -0,0 +1,65 @@
1
+ import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
2
+ import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
3
+ import _createClass from "@babel/runtime/helpers/esm/createClass";
4
+ import _inherits from "@babel/runtime/helpers/esm/inherits";
5
+ import _createSuper from "@babel/runtime/helpers/esm/createSuper";
6
+ import React from 'react';
7
+ import { focusEditor } from '../../../core';
8
+ import { CODE_BLOCK, MENUS_CONFIG_MAP } from '../../../constants';
9
+ import { MenuItem } from '../../../menu';
10
+ import { getSelectCodeElem, isMenuDisabled, changeToCodeBlock, changeToPlainText } from '../helpers';
11
+ var CodeBlockMenu = /*#__PURE__*/function (_React$Component) {
12
+ _inherits(CodeBlockMenu, _React$Component);
13
+ var _super = _createSuper(CodeBlockMenu);
14
+ function CodeBlockMenu() {
15
+ var _this;
16
+ _classCallCheck(this, CodeBlockMenu);
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));
21
+ _this.isActive = function () {
22
+ var editor = _this.props.editor;
23
+ var elem = getSelectCodeElem(editor);
24
+ return !!elem;
25
+ };
26
+ _this.isDisabled = function () {
27
+ return isMenuDisabled(_this.props.editor);
28
+ };
29
+ _this.onMouseDown = function (e) {
30
+ e.preventDefault();
31
+ e.stopPropagation();
32
+ var editor = _this.props.editor;
33
+ var active = _this.isActive(editor);
34
+ if (active) {
35
+ // It is currently in a code-block and needs to be converted to plain text
36
+ changeToPlainText(editor);
37
+ } else {
38
+ // It is not currently in code-block, so it needs to be converted to code-block
39
+ changeToCodeBlock(editor, 'text');
40
+ }
41
+ focusEditor(editor);
42
+ };
43
+ return _this;
44
+ }
45
+ _createClass(CodeBlockMenu, [{
46
+ key: "render",
47
+ value: function render() {
48
+ var _this$props = this.props,
49
+ isRichEditor = _this$props.isRichEditor,
50
+ className = _this$props.className;
51
+ var menuConfig = MENUS_CONFIG_MAP[CODE_BLOCK];
52
+ var props = _objectSpread(_objectSpread({
53
+ isRichEditor: isRichEditor,
54
+ className: className
55
+ }, menuConfig), {}, {
56
+ disabled: this.isDisabled(),
57
+ isActive: this.isActive(),
58
+ onMouseDown: this.onMouseDown
59
+ });
60
+ return /*#__PURE__*/React.createElement(MenuItem, props);
61
+ }
62
+ }]);
63
+ return CodeBlockMenu;
64
+ }(React.Component);
65
+ export default CodeBlockMenu;
@@ -0,0 +1,11 @@
1
+ import _createClass from "@babel/runtime/helpers/esm/createClass";
2
+ import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
3
+ import { BLOCKQUOTE } from '../../constants';
4
+ var Blockquote = /*#__PURE__*/_createClass(function Blockquote(options) {
5
+ _classCallCheck(this, Blockquote);
6
+ this.type = options.type || BLOCKQUOTE;
7
+ this.children = options.children || [{
8
+ text: ''
9
+ }];
10
+ });
11
+ export default Blockquote;
@@ -0,0 +1,89 @@
1
+ import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
2
+ import { Editor, Transforms, Node } from '@seafile/slate';
3
+ import { getSelectedNodeByType, getNodeType, isLastNode, genEmptyParagraph } from '../../core';
4
+ import { CODE_BLOCK } from '../../constants';
5
+ var getLastTextLineBeforeSelection = function getLastTextLineBeforeSelection(codeNode, editor) {
6
+ var selection = editor.selection;
7
+ if (selection == null) return '';
8
+ var codeText = Node.string(codeNode);
9
+ var anchorOffset = selection.anchor.offset;
10
+ var textBeforeAnchor = codeText.slice(0, anchorOffset); // The text before the selection
11
+ var arr = textBeforeAnchor.split('\n'); // text before selection, split by line break
12
+ var length = arr.length;
13
+ if (length === 0) return '';
14
+ return arr[length - 1];
15
+ };
16
+ var withCodeBlock = function withCodeBlock(editor) {
17
+ var insertBreak = editor.insertBreak,
18
+ normalizeNode = editor.normalizeNode,
19
+ insertData = editor.insertData;
20
+ var newEditor = editor;
21
+
22
+ // Rewrite insertBreak
23
+ newEditor.insertBreak = function () {
24
+ var codeNode = getSelectedNodeByType(newEditor, CODE_BLOCK);
25
+ if (codeNode == null) {
26
+ insertBreak(); // Perform the default line feed
27
+ return;
28
+ }
29
+
30
+ // When press Enter, the space is automatically inserted according to the space in the current line
31
+ var lastLineBeforeSelection = getLastTextLineBeforeSelection(codeNode, newEditor);
32
+ if (lastLineBeforeSelection) {
33
+ var arr = lastLineBeforeSelection.match(/^\s+/); // The space at the beginning of a line
34
+ if (arr != null && arr[0] != null) {
35
+ var spaces = arr[0];
36
+ newEditor.insertText("\n".concat(spaces)); // Insert a space after a newline
37
+ return;
38
+ }
39
+ }
40
+
41
+ // Normal line feed
42
+ newEditor.insertText('\n');
43
+ };
44
+
45
+ // Rewrite normalizeNode
46
+ newEditor.normalizeNode = function (_ref) {
47
+ var _ref2 = _slicedToArray(_ref, 2),
48
+ node = _ref2[0],
49
+ path = _ref2[1];
50
+ var type = getNodeType(node);
51
+ if (type === CODE_BLOCK) {
52
+ // code-block is the last node in the editor and needs to be followed by a p node
53
+ var isLast = isLastNode(newEditor, node);
54
+ if (isLast) {
55
+ Transforms.insertNodes(newEditor, genEmptyParagraph(), {
56
+ at: [path[0] + 1]
57
+ });
58
+ }
59
+
60
+ // There must be a code node below code-block
61
+ if (getNodeType(node.children[0]) !== 'code-line') {
62
+ Transforms.unwrapNodes(newEditor);
63
+ Transforms.setNodes(newEditor, {
64
+ type: 'paragraph'
65
+ }, {
66
+ mode: 'highest'
67
+ });
68
+ }
69
+ }
70
+
71
+ // Perform default behavior
72
+ return normalizeNode([node, path]);
73
+ };
74
+
75
+ // Rewrite insertData - Paste text
76
+ newEditor.insertData = function (data) {
77
+ var codeNode = getSelectedNodeByType(newEditor, CODE_BLOCK);
78
+ if (codeNode == null) {
79
+ insertData(data); // Perform default insertData
80
+ return;
81
+ }
82
+
83
+ // Gets the text and inserts it into the code block
84
+ var text = data.getData('text/plain');
85
+ Editor.insertText(newEditor, text);
86
+ };
87
+ return newEditor;
88
+ };
89
+ export default withCodeBlock;
@@ -0,0 +1,107 @@
1
+ import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
2
+ import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
3
+ import _createClass from "@babel/runtime/helpers/esm/createClass";
4
+ import _inherits from "@babel/runtime/helpers/esm/inherits";
5
+ import _createSuper from "@babel/runtime/helpers/esm/createSuper";
6
+ import React from 'react';
7
+ import { updateLanguageSetting } from './helpers';
8
+ import { getSelectedNodeByType } from '../../core';
9
+ import { CODE_BLOCK } from '../../constants';
10
+ import '../../../assets/css/code-block.css';
11
+ var LanguageSet = /*#__PURE__*/function (_React$PureComponent) {
12
+ _inherits(LanguageSet, _React$PureComponent);
13
+ var _super = _createSuper(LanguageSet);
14
+ function LanguageSet() {
15
+ var _this;
16
+ _classCallCheck(this, LanguageSet);
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));
21
+ _this.stopPropagation = function (event) {
22
+ event.stopPropagation();
23
+ };
24
+ return _this;
25
+ }
26
+ _createClass(LanguageSet, [{
27
+ key: "componentDidMount",
28
+ value: function componentDidMount() {
29
+ // Compat chrome browser in windows, stop propagation to prevent emit the click event added to document
30
+ this.selector.addEventListener('click', this.stopPropagation);
31
+ }
32
+ }, {
33
+ key: "componentWillUnmount",
34
+ value: function componentWillUnmount() {
35
+ this.selector.removeEventListener('click', this.stopPropagation);
36
+ }
37
+ }, {
38
+ key: "render",
39
+ value: function render() {
40
+ var _this2 = this;
41
+ var _this$props = this.props,
42
+ language = _this$props.language,
43
+ onChange = _this$props.onChange;
44
+ return /*#__PURE__*/React.createElement("div", {
45
+ contentEditable: false,
46
+ className: "language-type"
47
+ }, /*#__PURE__*/React.createElement("select", {
48
+ ref: function ref(_ref) {
49
+ return _this2.selector = _ref;
50
+ },
51
+ value: language,
52
+ name: "language",
53
+ onInput: function onInput(event) {
54
+ return event.stopPropagation();
55
+ },
56
+ onChange: onChange
57
+ }, /*#__PURE__*/React.createElement("option", {
58
+ value: "none"
59
+ }, "Text")));
60
+ }
61
+ }]);
62
+ return LanguageSet;
63
+ }(React.PureComponent);
64
+ var CodeBlock = /*#__PURE__*/function (_React$PureComponent2) {
65
+ _inherits(CodeBlock, _React$PureComponent2);
66
+ var _super2 = _createSuper(CodeBlock);
67
+ function CodeBlock() {
68
+ var _this3;
69
+ _classCallCheck(this, CodeBlock);
70
+ for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
71
+ args[_key2] = arguments[_key2];
72
+ }
73
+ _this3 = _super2.call.apply(_super2, [this].concat(args));
74
+ _this3.onChange = function (event) {
75
+ var editor = _this3.props.editor;
76
+ var language = event.target.value;
77
+ updateLanguageSetting(editor, language);
78
+ };
79
+ return _this3;
80
+ }
81
+ _createClass(CodeBlock, [{
82
+ key: "render",
83
+ value: function render() {
84
+ var _this$props2 = this.props,
85
+ codeBlockProps = _this$props2.codeBlockProps,
86
+ editor = _this$props2.editor;
87
+ var attributes = codeBlockProps.attributes,
88
+ children = codeBlockProps.children,
89
+ element = codeBlockProps.element;
90
+ var language = element.language;
91
+ var codeNode = getSelectedNodeByType(editor, CODE_BLOCK);
92
+ return /*#__PURE__*/React.createElement("div", {
93
+ className: 'code-block-container'
94
+ }, /*#__PURE__*/React.createElement("pre", attributes, children), (codeNode === null || codeNode === void 0 ? void 0 : codeNode.id) === (element === null || element === void 0 ? void 0 : element.id) && /*#__PURE__*/React.createElement(LanguageSet, {
95
+ language: language,
96
+ onChange: this.onChange
97
+ }));
98
+ }
99
+ }]);
100
+ return CodeBlock;
101
+ }(React.PureComponent);
102
+ export var renderCodeBlock = function renderCodeBlock(props, editor) {
103
+ return /*#__PURE__*/React.createElement(CodeBlock, {
104
+ codeBlockProps: _objectSpread({}, props),
105
+ editor: editor
106
+ });
107
+ };
@@ -1,12 +1,12 @@
1
1
  import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
2
- import { Editor, Transforms } from "@seafile/slate";
3
- import { getNodeType } from "../../core";
2
+ import { Editor, Transforms } from '@seafile/slate';
3
+ import { getNodeType } from '../../core';
4
4
  export var isMenuDisabled = function isMenuDisabled(editor) {
5
5
  if (!editor.selection) return true;
6
6
  var _Editor$nodes = Editor.nodes(editor, {
7
7
  match: function match(n) {
8
8
  var type = getNodeType(n);
9
- if (type === 'paragraph') return true;
9
+ if (['code-line', 'code-block', 'paragraph'].includes(type)) return true;
10
10
  if (type.startsWith('header')) return true;
11
11
  return false;
12
12
  },
@@ -4,6 +4,7 @@ import BlockquotePlugin from './blockquote';
4
4
  import ListPlugin from './list';
5
5
  import CheckListPlugin from './check-list';
6
6
  import TextPlugin from './text-style';
7
- var Plugins = [HeaderPlugin, LinkPlugin, BlockquotePlugin, ListPlugin, CheckListPlugin, TextPlugin];
7
+ import CodeBlockPlugin from './code-block';
8
+ var Plugins = [HeaderPlugin, LinkPlugin, BlockquotePlugin, ListPlugin, CheckListPlugin, TextPlugin, CodeBlockPlugin];
8
9
  export default Plugins;
9
- export { HeaderPlugin, LinkPlugin, BlockquotePlugin, ListPlugin, CheckListPlugin, TextPlugin };
10
+ export { HeaderPlugin, LinkPlugin, BlockquotePlugin, ListPlugin, CheckListPlugin, TextPlugin, CodeBlockPlugin };
@@ -10,7 +10,7 @@ export var isMenuDisabled = function isMenuDisabled(editor) {
10
10
  var notMatch = selectedElems.some(function (elem) {
11
11
  var type = elem.type;
12
12
  if (editor.isVoid(elem)) return true;
13
- if (['pre', 'code', 'link'].includes(type)) return true;
13
+ if (['code-block', 'code-line', 'link'].includes(type)) return true;
14
14
  return false;
15
15
  });
16
16
  if (notMatch) return true; // disabled
@@ -27,7 +27,7 @@ export var isMenuDisabled = function isMenuDisabled(editor) {
27
27
  var notMatch = selectedElements.some(function (element) {
28
28
  if (Editor.isVoid(editor, element) && Editor.isBlock(editor, element)) return true;
29
29
  var type = element.type;
30
- if (['pre', 'code', 'table', 'check-list-item'].includes(type)) return true;
30
+ if (['code-line', 'code-block', 'table', 'check-list-item'].includes(type)) return true;
31
31
  return false;
32
32
  });
33
33
  if (notMatch) return true;
@@ -7,7 +7,7 @@ var renderList = function renderList(props, editor) {
7
7
  var Tag = node.type === ORDERED_LIST ? 'ol' : 'ul';
8
8
  return /*#__PURE__*/React.createElement(Tag, Object.assign({
9
9
  "data-id": node.id,
10
- className: "dlThau"
10
+ className: "list-container"
11
11
  }, attributes), children);
12
12
  };
13
13
  var renderListItem = function renderListItem(props, editor) {
@@ -0,0 +1,52 @@
1
+ import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
2
+ import { Editor, Transforms } from '@seafile/slate';
3
+ import { getNodeType } from '../../core';
4
+ export var isMenuDisabled = function isMenuDisabled(editor) {
5
+ if (editor.selection == null) return true;
6
+ var _Editor$nodes = Editor.nodes(editor, {
7
+ match: function match(n) {
8
+ var type = getNodeType(n);
9
+ if (type === 'code-block') return true; // Code block
10
+ if (Editor.isVoid(editor, n)) return true; // void node
11
+
12
+ return false;
13
+ },
14
+ universal: true
15
+ }),
16
+ _Editor$nodes2 = _slicedToArray(_Editor$nodes, 1),
17
+ match = _Editor$nodes2[0];
18
+
19
+ // If yes, it is disabled
20
+ if (match) return true;
21
+ return false;
22
+ };
23
+ export var addMark = function addMark(editor, type) {
24
+ Editor.addMark(editor, type, true);
25
+ };
26
+ export var removeMark = function removeMark(editor, type) {
27
+ Editor.removeMark(editor, type);
28
+ Transforms.setNodes(editor, {
29
+ type: 'paragraph'
30
+ }, {
31
+ mode: 'highest'
32
+ });
33
+ };
34
+
35
+ // Whether mark is included
36
+ export var getValue = function getValue(editor, mark) {
37
+ var curMarks = Editor.marks(editor);
38
+
39
+ // If curMarks exists, you need to set this parameter manually. curMarks prevails
40
+ if (curMarks) {
41
+ return curMarks[mark];
42
+ } else {
43
+ var _Editor$nodes3 = Editor.nodes(editor, {
44
+ match: function match(n) {
45
+ return n[mark] === true;
46
+ }
47
+ }),
48
+ _Editor$nodes4 = _slicedToArray(_Editor$nodes3, 1),
49
+ match = _Editor$nodes4[0];
50
+ return !!match;
51
+ }
52
+ };
@@ -0,0 +1,81 @@
1
+ import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
2
+ import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
3
+ import _createClass from "@babel/runtime/helpers/esm/createClass";
4
+ import _inherits from "@babel/runtime/helpers/esm/inherits";
5
+ import _createSuper from "@babel/runtime/helpers/esm/createSuper";
6
+ import React from 'react';
7
+ import { TEXTSTYLE, MENUS_CONFIG_MAP } from '../../../constants';
8
+ import { focusEditor } from '../../../core';
9
+ import { MenuItem } from '../../../menu';
10
+ import { getValue, isMenuDisabled, addMark, removeMark } from '../helpers';
11
+ var TextStyleMenuList = /*#__PURE__*/function (_React$Component) {
12
+ _inherits(TextStyleMenuList, _React$Component);
13
+ var _super = _createSuper(TextStyleMenuList);
14
+ function TextStyleMenuList(props) {
15
+ var _this;
16
+ _classCallCheck(this, TextStyleMenuList);
17
+ _this = _super.call(this, props);
18
+ _this.isActive = function (editor, type) {
19
+ var isMark = getValue(editor, type);
20
+ return !!isMark;
21
+ };
22
+ _this.isDisabled = function () {
23
+ var editor = _this.props.editor;
24
+ return isMenuDisabled(editor);
25
+ };
26
+ _this.onMouseDown = function (e, type) {
27
+ e.preventDefault();
28
+ e.stopPropagation();
29
+ if (_this.isDisabled()) return;
30
+ var editor = _this.props.editor;
31
+ var active = _this.isActive(editor, type);
32
+ if (active) {
33
+ removeMark(editor, type);
34
+ } else {
35
+ addMark(editor, type);
36
+ }
37
+ focusEditor(editor);
38
+ };
39
+ _this.state = {
40
+ isShowLinkDialog: false
41
+ };
42
+ return _this;
43
+ }
44
+ _createClass(TextStyleMenuList, [{
45
+ key: "getTextStyleMenuList",
46
+ value: function getTextStyleMenuList() {
47
+ var _this$props = this.props,
48
+ isRichEditor = _this$props.isRichEditor,
49
+ className = _this$props.className,
50
+ 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;
65
+ }
66
+ }, {
67
+ key: "render",
68
+ value: function render() {
69
+ var textStyleMenuList = this.getTextStyleMenuList();
70
+ return /*#__PURE__*/React.createElement(React.Fragment, null, textStyleMenuList.map(function (menuItem, index) {
71
+ var menuItemConfig = MENUS_CONFIG_MAP[TEXTSTYLE][index];
72
+ var menuItemProps = _objectSpread(_objectSpread({}, menuItem), menuItemConfig);
73
+ return /*#__PURE__*/React.createElement(MenuItem, Object.assign({
74
+ key: index
75
+ }, menuItemProps));
76
+ }));
77
+ }
78
+ }]);
79
+ return TextStyleMenuList;
80
+ }(React.Component);
81
+ export default TextStyleMenuList;
@@ -1,7 +1,7 @@
1
1
  import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
2
2
  import React from 'react';
3
- import { BLOCKQUOTE, LINK, CHECK_LIST_ITEM, HEADER1, HEADER2, HEADER3, HEADER4, HEADER5, HEADER6, LIST_ITEM, LIST_LIC, ORDERED_LIST, PARAGRAPH, UNORDERED_LIST } from '../constants';
4
- import { BlockquotePlugin, LinkPlugin, CheckListPlugin, HeaderPlugin, ListPlugin } from '../plugins';
3
+ import { BLOCKQUOTE, LINK, CHECK_LIST_ITEM, HEADER1, HEADER2, HEADER3, HEADER4, HEADER5, HEADER6, LIST_ITEM, LIST_LIC, ORDERED_LIST, PARAGRAPH, UNORDERED_LIST, CODE_BLOCK } from '../constants';
4
+ import { BlockquotePlugin, LinkPlugin, CheckListPlugin, HeaderPlugin, ListPlugin, CodeBlockPlugin } from '../plugins';
5
5
  var renderElement = function renderElement(props, editor) {
6
6
  var attributes = props.attributes,
7
7
  children = props.children,
@@ -61,6 +61,12 @@ var renderElement = function renderElement(props, editor) {
61
61
  editor: editor
62
62
  }));
63
63
  }
64
+ case CODE_BLOCK:
65
+ {
66
+ var _CodeBlockPlugin$rend = _slicedToArray(CodeBlockPlugin.renderElements, 1),
67
+ renderCodeBlock = _CodeBlockPlugin$rend[0];
68
+ return renderCodeBlock(props, editor);
69
+ }
64
70
  default:
65
71
  {
66
72
  return /*#__PURE__*/React.createElement("p", Object.assign({
@@ -10,6 +10,8 @@ import { ORDERED_LIST, UNORDERED_LIST } from '../constants';
10
10
  import HeaderMenu from '../plugins/header/menu';
11
11
  import CheckListMenu from '../plugins/check-list/menu';
12
12
  import { MenuGroup } from '../menu';
13
+ import TextStyleMenuList from '../plugins/text-style/menu';
14
+ import CodeBlockMenu from '../plugins/code-block/menu';
13
15
  import '../../assets/css/sdoc-editor-toolbar.css';
14
16
  var Toolbar = /*#__PURE__*/function (_React$Component) {
15
17
  _inherits(Toolbar, _React$Component);
@@ -22,10 +24,12 @@ var Toolbar = /*#__PURE__*/function (_React$Component) {
22
24
  key: "render",
23
25
  value: function render() {
24
26
  return /*#__PURE__*/React.createElement("div", {
25
- className: "sf-editor-toolbar"
27
+ className: "sdoc-editor-toolbar"
26
28
  }, /*#__PURE__*/React.createElement(HeaderMenu, {
27
29
  editor: this.props.editor
28
- }), /*#__PURE__*/React.createElement(MenuGroup, null, /*#__PURE__*/React.createElement(LinkMenu, {
30
+ }), /*#__PURE__*/React.createElement(MenuGroup, null, /*#__PURE__*/React.createElement(TextStyleMenuList, {
31
+ editor: this.props.editor
32
+ }), /*#__PURE__*/React.createElement(LinkMenu, {
29
33
  editor: this.props.editor
30
34
  }), /*#__PURE__*/React.createElement(QuoteMenu, {
31
35
  editor: this.props.editor
@@ -37,6 +41,8 @@ var Toolbar = /*#__PURE__*/function (_React$Component) {
37
41
  type: ORDERED_LIST
38
42
  }), /*#__PURE__*/React.createElement(CheckListMenu, {
39
43
  editor: this.props.editor
44
+ }), /*#__PURE__*/React.createElement(CodeBlockMenu, {
45
+ editor: this.props.editor
40
46
  })));
41
47
  }
42
48
  }]);
package/dist/viewer.js CHANGED
@@ -8,7 +8,8 @@ import isHotkey from 'is-hotkey';
8
8
  import editor, { renderLeaf as _renderLeaf, renderElement as _renderElement } from './extension';
9
9
  import { SocketManager, withSocketIO } from './socket';
10
10
  import withNodeId from './node-id';
11
- import './assets/css/sdoc-editor.css';
11
+ import './assets/css/layout.css';
12
+ import './assets/css/sdoc-editor-content.css';
12
13
  var SDocViewer = /*#__PURE__*/function (_React$Component) {
13
14
  _inherits(SDocViewer, _React$Component);
14
15
  var _super = _createSuper(SDocViewer);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seafile/sdoc-editor",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "private": false,
5
5
  "description": "This is a sdoc editor",
6
6
  "main": "dist/index.js",