@seafile/seafile-editor 1.0.6 → 1.0.8
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.
- package/dist/containers/article-info/index.js +0 -1
- package/dist/editors/simple-slate-editor /index.js +7 -3
- package/dist/editors/simple-slate-editor /style.css +21 -17
- package/dist/editors/slate-editor/index.js +8 -4
- package/dist/editors/slate-editor/style.css +14 -14
- package/dist/editors/slate-viewer/index.js +7 -3
- package/dist/editors/slate-viewer/style.css +14 -0
- package/dist/extension/highlight/index.js +3 -0
- package/dist/extension/highlight/normalize-tokens.js +87 -0
- package/dist/extension/highlight/prismjs.js +19 -0
- package/dist/extension/highlight/set-node-decorations.js +74 -0
- package/dist/extension/highlight/use-highlight.js +13 -0
- package/dist/extension/index.js +2 -1
- package/dist/extension/plugins/code-block/render-elem/constant.js +13 -13
- package/dist/extension/toolbar/header-toolbar/style.css +1 -1
- package/package.json +5 -6
|
@@ -20,7 +20,6 @@ export default function ArticleInfo(_ref) {
|
|
|
20
20
|
if (activeTab === TAB_TYPES.FILE_DETAIL) return;
|
|
21
21
|
setActiveTab(TAB_TYPES.FILE_DETAIL);
|
|
22
22
|
}, [activeTab]);
|
|
23
|
-
console.log(children);
|
|
24
23
|
return /*#__PURE__*/React.createElement("div", {
|
|
25
24
|
className: "sf-article-info-container"
|
|
26
25
|
}, /*#__PURE__*/React.createElement("ul", {
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import React, { useCallback, useState, useMemo, useEffect } from 'react';
|
|
2
2
|
import { Editable, Slate } from 'slate-react';
|
|
3
3
|
import { Editor } from 'slate';
|
|
4
|
-
import { baseEditor, Toolbar, renderElement, renderLeaf } from '../../extension';
|
|
4
|
+
import { baseEditor, Toolbar, renderElement, renderLeaf, useHighlight, SetNodeToDecorations } from '../../extension';
|
|
5
5
|
import EventBus from '../../utils/event-bus';
|
|
6
6
|
import EventProxy from '../../utils/event-handler';
|
|
7
7
|
import withPropsEditor from './with-props-editor';
|
|
8
8
|
import { focusEditor } from '../../extension/core';
|
|
9
|
+
import { isMac } from '../../utils/common';
|
|
9
10
|
import './style.css';
|
|
11
|
+
const isMacOS = isMac();
|
|
10
12
|
export default function SimpleSlateEditor(_ref) {
|
|
11
13
|
let {
|
|
12
14
|
value,
|
|
@@ -23,6 +25,7 @@ export default function SimpleSlateEditor(_ref) {
|
|
|
23
25
|
const eventProxy = useMemo(() => {
|
|
24
26
|
return new EventProxy(editor);
|
|
25
27
|
}, [editor]);
|
|
28
|
+
const decorate = useHighlight(editor);
|
|
26
29
|
const onChange = useCallback(value => {
|
|
27
30
|
setSlateValue(value);
|
|
28
31
|
const operations = editor.operations;
|
|
@@ -74,12 +77,13 @@ export default function SimpleSlateEditor(_ref) {
|
|
|
74
77
|
initialValue: slateValue,
|
|
75
78
|
onChange: onChange
|
|
76
79
|
}, /*#__PURE__*/React.createElement("div", {
|
|
77
|
-
className: "sf-slate-scroll-container"
|
|
80
|
+
className: "sf-slate-scroll-container ".concat(isMacOS ? '' : 'isWin')
|
|
78
81
|
}, /*#__PURE__*/React.createElement("div", {
|
|
79
82
|
className: "sf-slate-article-container"
|
|
80
83
|
}, /*#__PURE__*/React.createElement("div", {
|
|
81
84
|
className: "article"
|
|
82
|
-
}, /*#__PURE__*/React.createElement(Editable, {
|
|
85
|
+
}, /*#__PURE__*/React.createElement(SetNodeToDecorations, null), /*#__PURE__*/React.createElement(Editable, {
|
|
86
|
+
decorate: decorate,
|
|
83
87
|
renderElement: renderElement,
|
|
84
88
|
renderLeaf: renderLeaf,
|
|
85
89
|
onKeyDown: eventProxy.onKeyDown,
|
|
@@ -28,13 +28,26 @@
|
|
|
28
28
|
min-height: 0;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
.sf-simple-slate-editor-container .sf-slate-scroll-container
|
|
32
|
-
.sf-simple-slate-editor-container .sf-slate-article-container {
|
|
31
|
+
.sf-simple-slate-editor-container .sf-slate-scroll-container {
|
|
33
32
|
height: 100%;
|
|
34
33
|
width: 100%;
|
|
35
34
|
overflow: auto;
|
|
36
35
|
}
|
|
37
36
|
|
|
37
|
+
.sf-simple-slate-editor-container .sf-slate-scroll-container.isWin::-webkit-scrollbar{
|
|
38
|
+
width: 8px;
|
|
39
|
+
height: 8px;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.sf-simple-slate-editor-container .sf-slate-scroll-container.isWin::-webkit-scrollbar-button {
|
|
43
|
+
display: none;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.sf-simple-slate-editor-container .sf-slate-scroll-container.isWin::-webkit-scrollbar-thumb {
|
|
47
|
+
background-color: rgb(206, 206, 212);
|
|
48
|
+
border-radius: 10px;
|
|
49
|
+
}
|
|
50
|
+
|
|
38
51
|
/* .sf-simple-slate-editor-container .sf-slate-article-container {
|
|
39
52
|
flex: 1;
|
|
40
53
|
position: relative;
|
|
@@ -45,10 +58,15 @@
|
|
|
45
58
|
padding-bottom: 20px;
|
|
46
59
|
} */
|
|
47
60
|
|
|
61
|
+
.sf-simple-slate-editor-container .sf-slate-article-container {
|
|
62
|
+
height: 100%;
|
|
63
|
+
width: 100%;
|
|
64
|
+
overflow: auto;
|
|
65
|
+
}
|
|
66
|
+
|
|
48
67
|
.sf-simple-slate-editor-container .sf-slate-editor-content .article {
|
|
49
68
|
margin: 0;
|
|
50
69
|
padding: 10px;
|
|
51
|
-
height: 100%;
|
|
52
70
|
border: none;
|
|
53
71
|
background-color: #fff;
|
|
54
72
|
}
|
|
@@ -56,17 +74,3 @@
|
|
|
56
74
|
.sf-simple-slate-editor-container .sf-slate-editor-content .article div:first-child {
|
|
57
75
|
outline: none;
|
|
58
76
|
}
|
|
59
|
-
|
|
60
|
-
.sf-simple-slate-editor-container ::-webkit-scrollbar{
|
|
61
|
-
width: 8px;
|
|
62
|
-
height: 8px;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
.sf-simple-slate-editor-container ::-webkit-scrollbar-button {
|
|
66
|
-
display: none;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
.sf-simple-slate-editor-container ::-webkit-scrollbar-thumb {
|
|
70
|
-
background-color: rgb(206, 206, 212);
|
|
71
|
-
border-radius: 10px;
|
|
72
|
-
}
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import React, { useCallback, useState, useMemo, useEffect, useRef } from 'react';
|
|
2
2
|
import { Editable, Slate } from 'slate-react';
|
|
3
3
|
import { Editor } from 'slate';
|
|
4
|
-
import { baseEditor, Toolbar, renderElement, renderLeaf } from '../../extension';
|
|
4
|
+
import { baseEditor, Toolbar, renderElement, renderLeaf, useHighlight, SetNodeToDecorations } from '../../extension';
|
|
5
5
|
import EventBus from '../../utils/event-bus';
|
|
6
6
|
import EventProxy from '../../utils/event-handler';
|
|
7
7
|
import withPropsEditor from './with-props-editor';
|
|
8
8
|
import EditorHelp from './editor-help';
|
|
9
9
|
import { focusEditor } from '../../extension/core';
|
|
10
10
|
import { ScrollContext } from '../../hooks/use-scroll-context';
|
|
11
|
-
import './style.css';
|
|
12
11
|
import useSeafileUtils from '../../hooks/use-insert-image';
|
|
12
|
+
import { isMac } from '../../utils/common';
|
|
13
|
+
import './style.css';
|
|
14
|
+
const isMacOS = isMac();
|
|
13
15
|
export default function SlateEditor(_ref) {
|
|
14
16
|
let {
|
|
15
17
|
value,
|
|
@@ -30,6 +32,7 @@ export default function SlateEditor(_ref) {
|
|
|
30
32
|
return new EventProxy(editor);
|
|
31
33
|
}, [editor]);
|
|
32
34
|
useSeafileUtils(editor);
|
|
35
|
+
const decorate = useHighlight(editor);
|
|
33
36
|
const onChange = useCallback(value => {
|
|
34
37
|
setSlateValue(value);
|
|
35
38
|
const operations = editor.operations;
|
|
@@ -88,12 +91,13 @@ export default function SlateEditor(_ref) {
|
|
|
88
91
|
onChange: onChange
|
|
89
92
|
}, /*#__PURE__*/React.createElement("div", {
|
|
90
93
|
ref: scrollRef,
|
|
91
|
-
className: "sf-slate-scroll-container"
|
|
94
|
+
className: "sf-slate-scroll-container ".concat(isMacOS ? '' : 'isWin')
|
|
92
95
|
}, /*#__PURE__*/React.createElement("div", {
|
|
93
96
|
className: "sf-slate-article-container"
|
|
94
97
|
}, /*#__PURE__*/React.createElement("div", {
|
|
95
98
|
className: "article"
|
|
96
|
-
}, /*#__PURE__*/React.createElement(Editable, {
|
|
99
|
+
}, /*#__PURE__*/React.createElement(SetNodeToDecorations, null), /*#__PURE__*/React.createElement(Editable, {
|
|
100
|
+
decorate: decorate,
|
|
97
101
|
renderElement: renderElement,
|
|
98
102
|
renderLeaf: renderLeaf,
|
|
99
103
|
onKeyDown: eventProxy.onKeyDown,
|
|
@@ -34,6 +34,20 @@
|
|
|
34
34
|
overflow: auto;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
.sf-slate-editor-container .sf-slate-scroll-container.isWin::-webkit-scrollbar{
|
|
38
|
+
width: 8px;
|
|
39
|
+
height: 8px;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.sf-slate-editor-container .sf-slate-scroll-container.isWin::-webkit-scrollbar-button {
|
|
43
|
+
display: none;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.sf-slate-editor-container .sf-slate-scroll-container.isWin::-webkit-scrollbar-thumb {
|
|
47
|
+
background-color: rgb(206, 206, 212);
|
|
48
|
+
border-radius: 10px;
|
|
49
|
+
}
|
|
50
|
+
|
|
37
51
|
.sf-slate-editor-container .sf-slate-article-container {
|
|
38
52
|
flex: 1;
|
|
39
53
|
position: relative;
|
|
@@ -57,20 +71,6 @@
|
|
|
57
71
|
outline: none;
|
|
58
72
|
}
|
|
59
73
|
|
|
60
|
-
.sf-slate-editor-container ::-webkit-scrollbar{
|
|
61
|
-
width: 8px;
|
|
62
|
-
height: 8px;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
.sf-slate-editor-container ::-webkit-scrollbar-button {
|
|
66
|
-
display: none;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
.sf-slate-editor-container ::-webkit-scrollbar-thumb {
|
|
70
|
-
background-color: rgb(206, 206, 212);
|
|
71
|
-
border-radius: 10px;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
74
|
@media (max-width: 991.8px) {
|
|
75
75
|
.sf-slate-editor-toolbar {
|
|
76
76
|
overflow-x: auto;
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import React, { useEffect, useRef } from 'react';
|
|
2
|
-
import { baseEditor, renderElement, renderLeaf } from '../../extension';
|
|
2
|
+
import { SetNodeToDecorations, baseEditor, renderElement, renderLeaf, useHighlight } from '../../extension';
|
|
3
3
|
import { Editable, Slate } from 'slate-react';
|
|
4
4
|
import Outline from '../../containers/outline';
|
|
5
5
|
import { ScrollContext } from '../../hooks/use-scroll-context';
|
|
6
|
+
import { isMac } from '../../utils/common';
|
|
6
7
|
import './style.css';
|
|
8
|
+
const isMacOS = isMac();
|
|
7
9
|
export default function SlateViewer(_ref) {
|
|
8
10
|
let {
|
|
9
11
|
value,
|
|
@@ -12,6 +14,7 @@ export default function SlateViewer(_ref) {
|
|
|
12
14
|
} = _ref;
|
|
13
15
|
const scrollRef = useRef(null);
|
|
14
16
|
const containerScrollRef = externalScrollRef ? externalScrollRef : scrollRef;
|
|
17
|
+
const decorate = useHighlight(baseEditor);
|
|
15
18
|
|
|
16
19
|
// willUnmount
|
|
17
20
|
useEffect(() => {
|
|
@@ -28,13 +31,14 @@ export default function SlateViewer(_ref) {
|
|
|
28
31
|
}
|
|
29
32
|
}, /*#__PURE__*/React.createElement("div", {
|
|
30
33
|
ref: scrollRef,
|
|
31
|
-
className: "sf-slate-viewer-scroll-container ".concat(isShowOutline ? 'outline' : '')
|
|
34
|
+
className: "sf-slate-viewer-scroll-container ".concat(isMacOS ? '' : 'isWin', " ").concat(isShowOutline ? 'outline' : '')
|
|
32
35
|
}, /*#__PURE__*/React.createElement("div", {
|
|
33
36
|
className: "sf-slate-viewer-article-container"
|
|
34
37
|
}, /*#__PURE__*/React.createElement("div", {
|
|
35
38
|
className: "article"
|
|
36
|
-
}, /*#__PURE__*/React.createElement(Editable, {
|
|
39
|
+
}, /*#__PURE__*/React.createElement(SetNodeToDecorations, null), /*#__PURE__*/React.createElement(Editable, {
|
|
37
40
|
readOnly: true,
|
|
41
|
+
decorate: decorate,
|
|
38
42
|
renderElement: renderElement,
|
|
39
43
|
renderLeaf: renderLeaf
|
|
40
44
|
}))), isShowOutline && /*#__PURE__*/React.createElement("div", {
|
|
@@ -8,6 +8,20 @@
|
|
|
8
8
|
padding: 30px 0 15px;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
+
.sf-slate-viewer-scroll-container.isWin::-webkit-scrollbar{
|
|
12
|
+
width: 8px;
|
|
13
|
+
height: 8px;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.sf-slate-viewer-scroll-container.isWin::-webkit-scrollbar-button {
|
|
17
|
+
display: none;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.sf-slate-viewer-scroll-container.isWin::-webkit-scrollbar-thumb {
|
|
21
|
+
background-color: rgb(206, 206, 212);
|
|
22
|
+
border-radius: 10px;
|
|
23
|
+
}
|
|
24
|
+
|
|
11
25
|
.sf-slate-viewer-scroll-container .sf-slate-viewer-article-container {
|
|
12
26
|
flex: 1;
|
|
13
27
|
margin: 0 auto 15px;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
const newlineRe = /\r\n|\r|\n/;
|
|
2
|
+
const normalizeEmptyLines = line => {
|
|
3
|
+
if (line.length === 0) {
|
|
4
|
+
line.push({
|
|
5
|
+
types: ['plain'],
|
|
6
|
+
content: '\n',
|
|
7
|
+
empty: true
|
|
8
|
+
});
|
|
9
|
+
} else if (line.length === 1 && line[0].content === '') {
|
|
10
|
+
line[0].content = '\n';
|
|
11
|
+
line[0].empty = true;
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
const appendTypes = (types, add) => {
|
|
15
|
+
const typesSize = types.length;
|
|
16
|
+
if (typesSize > 0 && types[typesSize - 1] === add) {
|
|
17
|
+
return types;
|
|
18
|
+
}
|
|
19
|
+
return types.concat(add);
|
|
20
|
+
};
|
|
21
|
+
export const normalizeTokens = tokens => {
|
|
22
|
+
const typeArrStack = [[]];
|
|
23
|
+
const tokenArrStack = [tokens];
|
|
24
|
+
const tokenArrIndexStack = [0];
|
|
25
|
+
const tokenArrSizeStack = [tokens.length];
|
|
26
|
+
let i = 0;
|
|
27
|
+
let stackIndex = 0;
|
|
28
|
+
let currentLine = [];
|
|
29
|
+
const acc = [currentLine];
|
|
30
|
+
while (stackIndex > -1) {
|
|
31
|
+
while ((i = tokenArrIndexStack[stackIndex]++) < tokenArrSizeStack[stackIndex]) {
|
|
32
|
+
let content;
|
|
33
|
+
let types = typeArrStack[stackIndex];
|
|
34
|
+
const tokenArr = tokenArrStack[stackIndex];
|
|
35
|
+
const token = tokenArr[i];
|
|
36
|
+
|
|
37
|
+
// Determine content and append type to types if necessary
|
|
38
|
+
if (typeof token === 'string') {
|
|
39
|
+
types = stackIndex > 0 ? types : ['plain'];
|
|
40
|
+
content = token;
|
|
41
|
+
} else {
|
|
42
|
+
types = appendTypes(types, token.type);
|
|
43
|
+
if (token.alias) {
|
|
44
|
+
types = appendTypes(types, token.alias);
|
|
45
|
+
}
|
|
46
|
+
content = token.content;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// If token.content is an array, increase the stack depth and repeat this while-loop
|
|
50
|
+
if (typeof content !== 'string') {
|
|
51
|
+
stackIndex++;
|
|
52
|
+
typeArrStack.push(types);
|
|
53
|
+
tokenArrStack.push(content);
|
|
54
|
+
tokenArrIndexStack.push(0);
|
|
55
|
+
tokenArrSizeStack.push(content.length);
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Split by newlines
|
|
60
|
+
const splitByNewlines = content.split(newlineRe);
|
|
61
|
+
const newlineCount = splitByNewlines.length;
|
|
62
|
+
currentLine.push({
|
|
63
|
+
types,
|
|
64
|
+
content: splitByNewlines[0]
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// Create a new line for each string on a new line
|
|
68
|
+
for (let i = 1; i < newlineCount; i++) {
|
|
69
|
+
normalizeEmptyLines(currentLine);
|
|
70
|
+
acc.push(currentLine = []);
|
|
71
|
+
currentLine.push({
|
|
72
|
+
types,
|
|
73
|
+
content: splitByNewlines[i]
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Decreate the stack depth
|
|
79
|
+
stackIndex--;
|
|
80
|
+
typeArrStack.pop();
|
|
81
|
+
tokenArrStack.pop();
|
|
82
|
+
tokenArrIndexStack.pop();
|
|
83
|
+
tokenArrSizeStack.pop();
|
|
84
|
+
}
|
|
85
|
+
normalizeEmptyLines(currentLine);
|
|
86
|
+
return acc;
|
|
87
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import Prism from 'prismjs';
|
|
2
|
+
import 'prismjs/themes/prism.css';
|
|
3
|
+
import 'prismjs/components/prism-javascript';
|
|
4
|
+
import 'prismjs/components/prism-typescript';
|
|
5
|
+
import 'prismjs/components/prism-markup';
|
|
6
|
+
import 'prismjs/components/prism-go';
|
|
7
|
+
import 'prismjs/components/prism-php';
|
|
8
|
+
import 'prismjs/components/prism-c';
|
|
9
|
+
import 'prismjs/components/prism-python';
|
|
10
|
+
import 'prismjs/components/prism-java';
|
|
11
|
+
import 'prismjs/components/prism-cpp';
|
|
12
|
+
import 'prismjs/components/prism-csharp';
|
|
13
|
+
import 'prismjs/components/prism-sql';
|
|
14
|
+
import 'prismjs/components/prism-ruby';
|
|
15
|
+
import 'prismjs/components/prism-swift';
|
|
16
|
+
import 'prismjs/components/prism-bash';
|
|
17
|
+
import 'prismjs/components/prism-lua';
|
|
18
|
+
import 'prismjs/components/prism-json';
|
|
19
|
+
export default Prism;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { Editor, Node, Element } from 'slate';
|
|
2
|
+
import { useSlate } from 'slate-react';
|
|
3
|
+
import { CODE_BLOCK } from '../constants/element-types';
|
|
4
|
+
import Prism from './prismjs';
|
|
5
|
+
import { normalizeTokens } from './normalize-tokens';
|
|
6
|
+
import { LANGUAGE_MAP } from '../plugins/code-block/render-elem/constant';
|
|
7
|
+
const mergeMaps = function () {
|
|
8
|
+
const map = new Map();
|
|
9
|
+
for (var _len = arguments.length, maps = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
10
|
+
maps[_key] = arguments[_key];
|
|
11
|
+
}
|
|
12
|
+
for (const m of maps) {
|
|
13
|
+
for (const item of m) {
|
|
14
|
+
map.set(...item);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return map;
|
|
18
|
+
};
|
|
19
|
+
const getChildNodeToDecorations = _ref => {
|
|
20
|
+
let [block, blockPath] = _ref;
|
|
21
|
+
const nodeToDecorations = new Map();
|
|
22
|
+
const text = block.children.map(line => Node.string(line)).join('\n');
|
|
23
|
+
const language = LANGUAGE_MAP[block.lang] ? block.lang : 'text';
|
|
24
|
+
const tokens = Prism.tokenize(text, Prism.languages[language]);
|
|
25
|
+
const normalizedTokens = normalizeTokens(tokens); // make tokens flat and grouped by line
|
|
26
|
+
const blockChildren = block.children;
|
|
27
|
+
for (let index = 0; index < normalizedTokens.length; index++) {
|
|
28
|
+
const tokens = normalizedTokens[index];
|
|
29
|
+
const element = blockChildren[index];
|
|
30
|
+
if (element) {
|
|
31
|
+
if (!nodeToDecorations.has(element)) {
|
|
32
|
+
nodeToDecorations.set(element, []);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
let start = 0;
|
|
36
|
+
for (const token of tokens) {
|
|
37
|
+
const length = token.content.length;
|
|
38
|
+
if (!length) {
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
const end = start + length;
|
|
42
|
+
const path = [...blockPath, index, 0];
|
|
43
|
+
const range = {
|
|
44
|
+
anchor: {
|
|
45
|
+
path,
|
|
46
|
+
offset: start
|
|
47
|
+
},
|
|
48
|
+
focus: {
|
|
49
|
+
path,
|
|
50
|
+
offset: end
|
|
51
|
+
},
|
|
52
|
+
token: true,
|
|
53
|
+
...Object.fromEntries(token.types.map(type => [type, true]))
|
|
54
|
+
};
|
|
55
|
+
if (nodeToDecorations.get(element)) {
|
|
56
|
+
nodeToDecorations.get(element).push(range);
|
|
57
|
+
}
|
|
58
|
+
start = end;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return nodeToDecorations;
|
|
62
|
+
};
|
|
63
|
+
const SetNodeToDecorations = () => {
|
|
64
|
+
const editor = useSlate();
|
|
65
|
+
const blockEntries = Array.from(Editor.nodes(editor, {
|
|
66
|
+
at: [],
|
|
67
|
+
mode: 'highest',
|
|
68
|
+
match: n => Element.isElement(n) && n.type === CODE_BLOCK
|
|
69
|
+
}));
|
|
70
|
+
const nodeToDecorations = mergeMaps(...blockEntries.map(getChildNodeToDecorations));
|
|
71
|
+
editor.nodeToDecorations = nodeToDecorations;
|
|
72
|
+
return null;
|
|
73
|
+
};
|
|
74
|
+
export default SetNodeToDecorations;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Element } from 'slate';
|
|
2
|
+
import { CODE_LINE } from '../constants/element-types';
|
|
3
|
+
export const useHighlight = editor => _ref => {
|
|
4
|
+
let [node, path] = _ref;
|
|
5
|
+
let ranges = [];
|
|
6
|
+
if (Element.isElement(node) && node.type === CODE_LINE) {
|
|
7
|
+
var _editor$nodeToDecorat;
|
|
8
|
+
ranges = (editor === null || editor === void 0 ? void 0 : (_editor$nodeToDecorat = editor.nodeToDecorations) === null || _editor$nodeToDecorat === void 0 ? void 0 : _editor$nodeToDecorat.get(node)) || [];
|
|
9
|
+
return ranges;
|
|
10
|
+
}
|
|
11
|
+
return ranges;
|
|
12
|
+
};
|
|
13
|
+
export default useHighlight;
|
package/dist/extension/index.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { ELementTypes } from './constants';
|
|
2
2
|
import { isEmptyParagraph } from './core';
|
|
3
|
+
import { useHighlight, SetNodeToDecorations } from './highlight';
|
|
3
4
|
import renderElement from './render/render-element';
|
|
4
5
|
import renderLeaf from './render/render-leaf';
|
|
5
6
|
import { Toolbar } from './toolbar';
|
|
6
7
|
import baseEditor from './editor';
|
|
7
|
-
export { ELementTypes, isEmptyParagraph, renderElement, renderLeaf, Toolbar, baseEditor };
|
|
8
|
+
export { ELementTypes, isEmptyParagraph, renderElement, renderLeaf, Toolbar, baseEditor, useHighlight, SetNodeToDecorations };
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
// Default language key name
|
|
2
|
-
export const EXPLAIN_TEXT = '
|
|
2
|
+
export const EXPLAIN_TEXT = 'text';
|
|
3
3
|
export const LANGUAGE_MAP = {
|
|
4
|
-
[EXPLAIN_TEXT]: '
|
|
5
|
-
html: '
|
|
6
|
-
css: '
|
|
7
|
-
javascript: '
|
|
8
|
-
c: '
|
|
9
|
-
cpp: '
|
|
10
|
-
csharp: '
|
|
11
|
-
java: '
|
|
12
|
-
python: '
|
|
13
|
-
sql: '
|
|
14
|
-
swift: '
|
|
15
|
-
json: '
|
|
4
|
+
[EXPLAIN_TEXT]: 'Text',
|
|
5
|
+
html: 'HTML',
|
|
6
|
+
css: 'CSS',
|
|
7
|
+
javascript: 'Javascript',
|
|
8
|
+
c: 'C',
|
|
9
|
+
cpp: 'C++',
|
|
10
|
+
csharp: 'C#',
|
|
11
|
+
java: 'Java',
|
|
12
|
+
python: 'Python',
|
|
13
|
+
sql: 'SQL',
|
|
14
|
+
swift: 'Swift',
|
|
15
|
+
json: 'JSON'
|
|
16
16
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@seafile/seafile-editor",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.8",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -43,6 +43,7 @@
|
|
|
43
43
|
"i18next-xhr-backend": "3.2.2",
|
|
44
44
|
"ignore-loader": "0.1.2",
|
|
45
45
|
"jest": "29.7.0",
|
|
46
|
+
"jest-environment-jsdom": "29.7.0",
|
|
46
47
|
"koa": "2.14.2",
|
|
47
48
|
"koa-router": "7.3.0",
|
|
48
49
|
"koa-send": "5.0.1",
|
|
@@ -50,7 +51,7 @@
|
|
|
50
51
|
"less": "4.2.0",
|
|
51
52
|
"less-loader": "11.1.3",
|
|
52
53
|
"mini-css-extract-plugin": "2.7.6",
|
|
53
|
-
"postcss": "8.4.
|
|
54
|
+
"postcss": "8.4.32",
|
|
54
55
|
"postcss-loader": "7.3.3",
|
|
55
56
|
"prop-types": "15.8.1",
|
|
56
57
|
"raw-loader": "4.0.2",
|
|
@@ -59,6 +60,7 @@
|
|
|
59
60
|
"react-i18next": "12.1.4",
|
|
60
61
|
"react-router": "6.16.0",
|
|
61
62
|
"react-router-dom": "6.16.0",
|
|
63
|
+
"seafile-js": "0.2.222",
|
|
62
64
|
"style-loader": "3.3.3",
|
|
63
65
|
"terser-webpack-plugin": "5.3.9",
|
|
64
66
|
"url-loader": "4.1.1",
|
|
@@ -87,10 +89,8 @@
|
|
|
87
89
|
"codemirror": "6.0.1",
|
|
88
90
|
"deep-copy": "1.4.2",
|
|
89
91
|
"deepmerge": "4.3.1",
|
|
90
|
-
"install": "0.13.0",
|
|
91
92
|
"is-url": "^1.2.4",
|
|
92
|
-
"
|
|
93
|
-
"npm": "10.2.4",
|
|
93
|
+
"prismjs": "1.29.0",
|
|
94
94
|
"reactstrap": "8.9.0",
|
|
95
95
|
"rehype-format": "5.0.0",
|
|
96
96
|
"rehype-mathjax": "5.0.0",
|
|
@@ -104,7 +104,6 @@
|
|
|
104
104
|
"remark-parse": "11.0.0",
|
|
105
105
|
"remark-rehype": "11.0.0",
|
|
106
106
|
"remark-stringify": "11.0.0",
|
|
107
|
-
"seafile-js": "0.2.210",
|
|
108
107
|
"slate": "0.94.1",
|
|
109
108
|
"slate-history": "0.93.0",
|
|
110
109
|
"slate-hyperscript": "^0.81.3",
|