@seafile/sdoc-editor 0.1.57 → 0.1.59

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.
Files changed (28) hide show
  1. package/dist/assets/css/simple-editor.css +2 -0
  2. package/dist/basic-sdk/assets/css/code-block.css +111 -17
  3. package/dist/basic-sdk/editor.js +9 -3
  4. package/dist/basic-sdk/extension/menu/menu.css +0 -1
  5. package/dist/basic-sdk/extension/plugins/code-block/helpers.js +11 -12
  6. package/dist/basic-sdk/extension/plugins/code-block/menu/index.js +1 -1
  7. package/dist/basic-sdk/extension/plugins/code-block/plugin.js +3 -38
  8. package/dist/basic-sdk/extension/plugins/code-block/render-elem.js +119 -95
  9. package/dist/basic-sdk/extension/plugins/text-align/menu/style.css +0 -1
  10. package/dist/basic-sdk/extension/plugins/text-style/render-elem.js +6 -1
  11. package/dist/basic-sdk/extension/render/render-element.js +12 -2
  12. package/dist/basic-sdk/highlight-decorate/index.js +22 -0
  13. package/dist/basic-sdk/highlight-decorate/setNodeToDecorations.js +104 -0
  14. package/dist/basic-sdk/utils/prismjs.js +172 -0
  15. package/dist/components/code-block-hover-menu/index.css +84 -0
  16. package/dist/components/code-block-hover-menu/index.js +110 -0
  17. package/dist/components/doc-info/index.js +17 -4
  18. package/dist/constants/index.js +1 -0
  19. package/dist/pages/simple-editor.js +3 -1
  20. package/package.json +2 -1
  21. package/public/locales/en/sdoc-editor.json +6 -1
  22. package/public/locales/zh-CN/sdoc-editor.json +2 -1
  23. package/public/media/sdoc-editor-font/iconfont.eot +0 -0
  24. package/public/media/sdoc-editor-font/iconfont.svg +15 -7
  25. package/public/media/sdoc-editor-font/iconfont.ttf +0 -0
  26. package/public/media/sdoc-editor-font/iconfont.woff +0 -0
  27. package/public/media/sdoc-editor-font/iconfont.woff2 +0 -0
  28. package/public/media/sdoc-editor-font.css +37 -13
@@ -12,6 +12,8 @@
12
12
  margin-left: 0.5rem;
13
13
  color: #999;
14
14
  cursor: pointer;
15
+ font-size: 14px;
16
+ line-height: 1;
15
17
  }
16
18
 
17
19
  .sdoc-editor-page-header .doc-info .doc-icon:hover {
@@ -1,22 +1,116 @@
1
- .code-block-container {
1
+ .sdoc-code-block-container {
2
2
  position: relative;
3
3
  }
4
4
 
5
- .language-type {
6
- font-size: 12px;
5
+ .sdoc-code-block-pre {
6
+ border: 1px solid #ccc;
7
+ }
8
+
9
+ .sdoc-code-block-pre .sdoc-code-no-wrap {
10
+ white-space: nowrap;
11
+ }
12
+
13
+ .sdoc-code-block-pre .sdoc-code-no-wrap .sdoc-code-line > span {
14
+ white-space: pre;
15
+ }
16
+
17
+ .sdoc-code-block-code .sdoc-code-line {
18
+ position: relative;
19
+ padding-left: 5px;
20
+ }
21
+
22
+ .sdoc-code-block-code .sdoc-code-line .sdoc-code-line-index {
7
23
  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;
24
+ left: -10px;
25
+ color: #ccc;
26
+ width: 10px;
27
+ height: 10px;
28
+ caret-color: transparent;
29
+ pointer-events: none;
30
+ }
31
+
32
+ .sdoc-code-line
33
+ .token.comment,
34
+ .token.prolog,
35
+ .token.doctype,
36
+ .token.cdata {
37
+ color: slategray;
38
+ }
39
+
40
+ .sdoc-code-line
41
+ .token.punctuation {
42
+ color: #999;
43
+ }
44
+
45
+ .sdoc-code-line
46
+ .token.namespace {
47
+ opacity: .7;
48
+ }
49
+
50
+ .sdoc-code-line
51
+ .token.property,
52
+ .token.tag,
53
+ .token.boolean,
54
+ .token.number,
55
+ .token.constant,
56
+ .token.symbol,
57
+ .token.deleted {
58
+ color: #905;
59
+ padding: 0rem;
60
+ }
61
+
62
+ .sdoc-code-line
63
+ .token.selector,
64
+ .token.attr-name,
65
+ .token.string,
66
+ .token.char,
67
+ .token.builtin,
68
+ .token.inserted {
69
+ color: #690;
70
+ }
71
+
72
+ .sdoc-code-line
73
+ .token.operator,
74
+ .token.entity,
75
+ .token.url,
76
+ .language-css .token.string,
77
+ .style .token.string {
78
+ color: #9a6e3a;
79
+ }
80
+
81
+ .sdoc-code-line
82
+ .token.atrule,
83
+ .token.attr-value,
84
+ .token.keyword {
85
+ color: #07a;
86
+ }
87
+
88
+ .sdoc-code-line
89
+ .token.function,
90
+ .token.class-name {
91
+ color: #DD4A68;
92
+ }
93
+
94
+ .sdoc-code-line
95
+ .token.regex,
96
+ .token.important,
97
+ .token.variable {
98
+ color: #e90;
99
+ }
100
+
101
+ .sdoc-code-line
102
+ .sdoc-code-line
103
+ .token.important,
104
+ .token.bold {
105
+ font-weight: bold;
106
+ }
107
+
108
+ .sdoc-code-line
109
+ .token.italic {
110
+ font-style: italic;
111
+ }
112
+
113
+ .sdoc-code-line
114
+ .token.entity {
115
+ cursor: help;
22
116
  }
@@ -9,9 +9,11 @@ import withNodeId from './node-id';
9
9
  import SDocOutline from './outline';
10
10
  import EventProxy from './utils/event-handler';
11
11
  import { useCursors } from './cursor/use-cursors';
12
+ import { useHighlightDecorate } from './highlight-decorate';
12
13
  import EventBus from './utils/event-bus';
13
14
  import { EXTERNAL_EVENT } from '../constants';
14
15
  import { isAllInTable } from './extension/plugins/table/helpers';
16
+ import { SetNodeToDecorations } from './highlight-decorate/setNodeToDecorations';
15
17
  import './assets/css/layout.css';
16
18
  import './assets/css/sdoc-editor-plugins.css';
17
19
  var SDocEditor = function SDocEditor(_ref) {
@@ -42,6 +44,8 @@ var SDocEditor = function SDocEditor(_ref) {
42
44
  setMenuPosition = _useState6[1];
43
45
  var _useCursors = useCursors(editor),
44
46
  cursors = _useCursors.cursors;
47
+ var _useHighlightDecorate = useHighlightDecorate(editor),
48
+ highlightDecorate = _useHighlightDecorate.highlightDecorate;
45
49
 
46
50
  // init eventHandler
47
51
  // eslint-disable-next-line react-hooks/exhaustive-deps
@@ -100,20 +104,22 @@ var SDocEditor = function SDocEditor(_ref) {
100
104
  doc: slateValue,
101
105
  docUuid: config.docUuid
102
106
  }), /*#__PURE__*/React.createElement("div", {
103
- className: "flex-fill o-auto sdoc-editor-article-container"
107
+ className: "flex-fill o-auto sdoc-editor-article-container",
108
+ id: "sdoc-editor-article-container"
104
109
  }, /*#__PURE__*/React.createElement(Slate, {
105
110
  editor: editor,
106
111
  value: slateValue,
107
112
  onChange: onChange
108
113
  }, /*#__PURE__*/React.createElement("div", {
109
114
  className: "article"
110
- }, /*#__PURE__*/React.createElement(Editable, {
115
+ }, /*#__PURE__*/React.createElement(SetNodeToDecorations, null), /*#__PURE__*/React.createElement(Editable, {
111
116
  renderElement: renderElement,
112
117
  renderLeaf: renderLeaf,
113
118
  onKeyDown: eventProxy.onKeyDown,
114
119
  cursors: cursors,
115
120
  onContextMenu: onContextMenu,
116
- onMouseDown: onMouseDown
121
+ onMouseDown: onMouseDown,
122
+ decorate: highlightDecorate
117
123
  })))))), isShowContextMenu && /*#__PURE__*/React.createElement(ContextMenu, {
118
124
  editor: editor,
119
125
  contextMenuPosition: menuPosition
@@ -11,7 +11,6 @@
11
11
  height: 100%;
12
12
  margin-right: 10px;
13
13
  border: 1px solid transparent;
14
- line-height: 30px;
15
14
  color: #555555;
16
15
  background-color: #fff;
17
16
  }
@@ -1,7 +1,8 @@
1
1
  import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
2
2
  import _createForOfIteratorHelper from "@babel/runtime/helpers/esm/createForOfIteratorHelper";
3
3
  import { Transforms, Editor, Node } from '@seafile/slate';
4
- import { CODE_BLOCK, PARAGRAPH } from '../../constants';
4
+ import slugid from 'slugid';
5
+ import { CODE_BLOCK, CODE_LINE, PARAGRAPH } from '../../constants';
5
6
  import { getNodeType, getSelectedNodeByType, getSelectedElems } from '../../core';
6
7
  export var isMenuDisabled = function isMenuDisabled(editor) {
7
8
  var selection = editor.selection;
@@ -25,13 +26,6 @@ export var getSelectCodeElem = function getSelectCodeElem(editor) {
25
26
  if (codeNode == null) return null;
26
27
  return codeNode;
27
28
  };
28
- export var updateLanguageSetting = function updateLanguageSetting(editor, language) {
29
- Transforms.setNodes(editor, {
30
- language: language
31
- }, {
32
- mode: 'highest'
33
- });
34
- };
35
29
  export var changeToCodeBlock = function changeToCodeBlock(editor, language) {
36
30
  // Summarizes the strings for the selected highest-level node
37
31
  var strArr = [];
@@ -65,16 +59,21 @@ export var changeToCodeBlock = function changeToCodeBlock(editor, language) {
65
59
  // Insert the codeBlockNode node
66
60
  var newCodeBlockNode = {
67
61
  type: CODE_BLOCK,
62
+ language: language,
63
+ style: {
64
+ white_space: 'nowrap' // default nowrap
65
+ },
66
+
68
67
  children: [{
69
- type: 'code-line',
68
+ id: slugid.nice(),
69
+ type: CODE_LINE,
70
70
  children: [{
71
71
  text: strArr.join('\n')
72
72
  } // Select the plain text of the node
73
73
  ]
74
- }],
75
-
76
- language: language
74
+ }]
77
75
  };
76
+
78
77
  Transforms.insertNodes(editor, newCodeBlockNode, {
79
78
  mode: 'highest'
80
79
  });
@@ -36,7 +36,7 @@ var CodeBlockMenu = /*#__PURE__*/function (_React$Component) {
36
36
  changeToPlainText(editor);
37
37
  } else {
38
38
  // It is not currently in code-block, so it needs to be converted to code-block
39
- changeToCodeBlock(editor, 'text');
39
+ changeToCodeBlock(editor, 'plaintext');
40
40
  }
41
41
  focusEditor(editor);
42
42
  };
@@ -1,46 +1,11 @@
1
1
  import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
2
- import { Transforms, Node } from '@seafile/slate';
3
- import { getSelectedNodeByType, getNodeType, isLastNode, genEmptyParagraph } from '../../core';
2
+ import { Transforms } from '@seafile/slate';
3
+ import { getNodeType, isLastNode, genEmptyParagraph } from '../../core';
4
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
5
  var withCodeBlock = function withCodeBlock(editor) {
17
- var insertBreak = editor.insertBreak,
18
- normalizeNode = editor.normalizeNode;
6
+ var normalizeNode = editor.normalizeNode;
19
7
  var newEditor = editor;
20
8
 
21
- // Rewrite insertBreak
22
- newEditor.insertBreak = function () {
23
- var codeNode = getSelectedNodeByType(newEditor, CODE_BLOCK);
24
- if (codeNode == null) {
25
- insertBreak(); // Perform the default line feed
26
- return;
27
- }
28
-
29
- // When press Enter, the space is automatically inserted according to the space in the current line
30
- var lastLineBeforeSelection = getLastTextLineBeforeSelection(codeNode, newEditor);
31
- if (lastLineBeforeSelection) {
32
- var arr = lastLineBeforeSelection.match(/^\s+/); // The space at the beginning of a line
33
- if (arr != null && arr[0] != null) {
34
- var spaces = arr[0];
35
- newEditor.insertText("\n".concat(spaces)); // Insert a space after a newline
36
- return;
37
- }
38
- }
39
-
40
- // Normal line feed
41
- newEditor.insertText('\n');
42
- };
43
-
44
9
  // Rewrite normalizeNode
45
10
  newEditor.normalizeNode = function (_ref) {
46
11
  var _ref2 = _slicedToArray(_ref, 2),
@@ -1,104 +1,128 @@
1
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';
2
+ import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
3
+ import React, { useCallback, useEffect, useState, useRef } from 'react';
4
+ import { ReactEditor, useSlateStatic } from '@seafile/slate-react';
5
+ import { Transforms } from '@seafile/slate';
6
+ import CodeBlockHoverMenu from '../../../../components/code-block-hover-menu';
10
7
  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];
8
+ var CodeBlock = function CodeBlock(_ref) {
9
+ var codeBlockProps = _ref.codeBlockProps;
10
+ var codeBlockRef = useRef();
11
+ var attributes = codeBlockProps.attributes,
12
+ children = codeBlockProps.children,
13
+ element = codeBlockProps.element;
14
+ var _element$style = element.style,
15
+ style = _element$style === void 0 ? {
16
+ white_space: 'nowrap'
17
+ } : _element$style;
18
+ var white_space = style.white_space;
19
+ var editor = useSlateStatic();
20
+ var _useState = useState({
21
+ top: '',
22
+ left: ''
23
+ }),
24
+ _useState2 = _slicedToArray(_useState, 2),
25
+ menuPosition = _useState2[0],
26
+ setMenuPosition = _useState2[1];
27
+ var _useState3 = useState(false),
28
+ _useState4 = _slicedToArray(_useState3, 2),
29
+ showHoverMenu = _useState4[0],
30
+ setShowHoverMenu = _useState4[1];
31
+ var onChangeLanguage = useCallback(function (lang) {
32
+ var language = lang.value;
33
+ var path = ReactEditor.findPath(editor, element);
34
+ Transforms.setNodes(editor, {
35
+ language: language
36
+ }, {
37
+ at: path
38
+ });
39
+ // eslint-disable-next-line react-hooks/exhaustive-deps
40
+ }, []);
41
+ var onChangeAutoLineWrap = useCallback(function (autoWrap) {
42
+ var path = ReactEditor.findPath(editor, element);
43
+ var newStyle = _objectSpread(_objectSpread({}, style), {}, {
44
+ white_space: autoWrap
45
+ });
46
+ Transforms.setNodes(editor, {
47
+ style: newStyle
48
+ }, {
49
+ at: path
50
+ });
51
+ // eslint-disable-next-line react-hooks/exhaustive-deps
52
+ }, []);
53
+ var onDeleteCodeBlock = useCallback(function () {
54
+ var path = ReactEditor.findPath(editor, element);
55
+ Transforms.removeNodes(editor, {
56
+ at: path
57
+ });
58
+ // eslint-disable-next-line react-hooks/exhaustive-deps
59
+ }, []);
60
+ var onMouseEnter = useCallback(function (e) {
61
+ if (codeBlockRef.current) {
62
+ var _codeBlockRef$current = codeBlockRef.current.getBoundingClientRect(),
63
+ top = _codeBlockRef$current.top,
64
+ left = _codeBlockRef$current.left;
65
+ var menuTop = top - 42; // top = top distance - menu height
66
+ var newMenuPosition = {
67
+ top: menuTop,
68
+ left: left // left = code-block left distance
69
+ };
70
+
71
+ setMenuPosition(newMenuPosition);
19
72
  }
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);
73
+ setShowHoverMenu(true);
74
+ // eslint-disable-next-line react-hooks/exhaustive-deps
75
+ }, []);
76
+ var onMouseLeave = useCallback(function (e) {
77
+ setShowHoverMenu(false);
78
+ // eslint-disable-next-line react-hooks/exhaustive-deps
79
+ }, []);
80
+ var onScroll = useCallback(function (e) {
81
+ if (e.currentTarget.scrollTop) {
82
+ var _codeBlockRef$current2 = codeBlockRef.current.getBoundingClientRect(),
83
+ top = _codeBlockRef$current2.top,
84
+ left = _codeBlockRef$current2.left;
85
+ var menuTop = top - 42; // top = top distance - menu height
86
+ var newMenuPosition = {
87
+ top: menuTop,
88
+ left: left // left = code-block left distance
89
+ };
90
+
91
+ setMenuPosition(newMenuPosition);
36
92
  }
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")));
93
+ // eslint-disable-next-line react-hooks/exhaustive-deps
94
+ }, []);
95
+ useEffect(function () {
96
+ if (showHoverMenu) {
97
+ document.getElementById('sdoc-editor-article-container').addEventListener('scroll', onScroll);
98
+ } else {
99
+ document.getElementById('sdoc-editor-article-container').removeEventListener('scroll', onScroll);
60
100
  }
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);
101
+ return function () {
102
+ document.getElementById('sdoc-editor-article-container').removeEventListener('scroll', onScroll);
78
103
  };
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);
104
+ // eslint-disable-next-line react-hooks/exhaustive-deps
105
+ }, [showHoverMenu]);
106
+ return /*#__PURE__*/React.createElement("div", {
107
+ ref: codeBlockRef,
108
+ className: 'sdoc-code-block-container',
109
+ onMouseEnter: onMouseEnter,
110
+ onMouseLeave: onMouseLeave
111
+ }, /*#__PURE__*/React.createElement("pre", Object.assign({
112
+ className: 'sdoc-code-block-pre'
113
+ }, attributes), /*#__PURE__*/React.createElement("code", {
114
+ className: "sdoc-code-block-code ".concat(white_space === 'nowrap' ? 'sdoc-code-no-wrap' : '')
115
+ }, children)), showHoverMenu && /*#__PURE__*/React.createElement(CodeBlockHoverMenu, {
116
+ menuPosition: menuPosition,
117
+ onChangeLanguage: onChangeLanguage,
118
+ language: element.language,
119
+ style: element.style || {
120
+ white_space: 'nowrap'
121
+ },
122
+ onChangeAutoLineWrap: onChangeAutoLineWrap,
123
+ onDeleteCodeBlock: onDeleteCodeBlock
124
+ }));
125
+ };
102
126
  export var renderCodeBlock = function renderCodeBlock(props, editor) {
103
127
  return /*#__PURE__*/React.createElement(CodeBlock, {
104
128
  codeBlockProps: _objectSpread({}, props),
@@ -21,7 +21,6 @@
21
21
  }
22
22
 
23
23
  .align-menu .align-toggle .sdocfont {
24
- height: 30px;
25
24
  display: inline-flex;
26
25
  justify-content: center;
27
26
  align-items: center;
@@ -1,9 +1,13 @@
1
+ import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
2
+ var _excluded = ["text"];
1
3
  import React from 'react';
2
4
  import Caret from './caret';
3
5
  var renderText = function renderText(props, editor) {
4
6
  var attributes = props.attributes,
5
7
  children = props.children,
6
8
  leaf = props.leaf;
9
+ var text = leaf.text,
10
+ rest = _objectWithoutProperties(leaf, _excluded);
7
11
  var markedChildren = React.cloneElement(children);
8
12
  if (leaf.BOLD) {
9
13
  markedChildren = /*#__PURE__*/React.createElement("strong", null, markedChildren);
@@ -49,7 +53,8 @@ var renderText = function renderText(props, editor) {
49
53
  return /*#__PURE__*/React.createElement("span", Object.assign({
50
54
  "data-id": leaf.id
51
55
  }, attributes, {
52
- style: style
56
+ style: style,
57
+ className: Object.keys(rest).join(' ')
53
58
  }), leaf.isCaret ? /*#__PURE__*/React.createElement(Caret, leaf) : null, markedChildren);
54
59
  };
55
60
  export default renderText;
@@ -3,9 +3,9 @@ import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
3
3
  import React from 'react';
4
4
  import { Node } from '@seafile/slate';
5
5
  import { useSlateStatic } from '@seafile/slate-react';
6
- import { BLOCKQUOTE, LINK, CHECK_LIST_ITEM, HEADER1, HEADER2, HEADER3, HEADER4, HEADER5, HEADER6, LIST_ITEM, LIST_LIC, ORDERED_LIST, PARAGRAPH, UNORDERED_LIST, CODE_BLOCK, IMAGE, ELEMENT_TYPE } from '../constants';
6
+ import { BLOCKQUOTE, LINK, CHECK_LIST_ITEM, HEADER1, HEADER2, HEADER3, HEADER4, HEADER5, HEADER6, LIST_ITEM, LIST_LIC, ORDERED_LIST, PARAGRAPH, UNORDERED_LIST, CODE_BLOCK, CODE_LINE, IMAGE, ELEMENT_TYPE } from '../constants';
7
7
  import { BlockquotePlugin, LinkPlugin, CheckListPlugin, HeaderPlugin, ListPlugin, CodeBlockPlugin, ImagePlugin, TablePlugin } from '../plugins';
8
- import { Placeholder } from '../core';
8
+ import { Placeholder, findPath } from '../core';
9
9
  var CustomElement = function CustomElement(props) {
10
10
  var editor = useSlateStatic();
11
11
  var attributes = props.attributes,
@@ -92,6 +92,16 @@ var CustomElement = function CustomElement(props) {
92
92
  renderCodeBlock = _CodeBlockPlugin$rend[0];
93
93
  return renderCodeBlock(props, editor);
94
94
  }
95
+ case CODE_LINE:
96
+ {
97
+ var path = findPath(editor, element);
98
+ var lineNumber = path.at(-1) + 1;
99
+ return /*#__PURE__*/React.createElement("div", Object.assign({}, attributes, {
100
+ className: 'sdoc-code-line'
101
+ }), lineNumber && /*#__PURE__*/React.createElement("span", {
102
+ className: "sdoc-code-line-index"
103
+ }, lineNumber), children);
104
+ }
95
105
  case IMAGE:
96
106
  {
97
107
  var _ImagePlugin$renderEl = _slicedToArray(ImagePlugin.renderElements, 1),
@@ -0,0 +1,22 @@
1
+ import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
2
+ import { useCallback } from 'react';
3
+ import { Element } from '@seafile/slate';
4
+ import { CODE_LINE } from '../extension/constants';
5
+ import { SetNodeToDecorations } from './setNodeToDecorations';
6
+ export var useHighlightDecorate = function useHighlightDecorate(editor) {
7
+ var highlightDecorate = useCallback(function (_ref) {
8
+ var _ref2 = _slicedToArray(_ref, 2),
9
+ node = _ref2[0],
10
+ path = _ref2[1];
11
+ if (Element.isElement(node) && node.type === CODE_LINE) {
12
+ var ranges = editor.nodeToDecorations.get(node) || [];
13
+ return ranges;
14
+ }
15
+ return [];
16
+ },
17
+ // eslint-disable-next-line react-hooks/exhaustive-deps
18
+ [editor.nodeToDecorations]);
19
+ return {
20
+ highlightDecorate: highlightDecorate
21
+ };
22
+ };