@seafile/seafile-editor 1.0.118 → 1.0.119-beta
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 +9 -6
- package/dist/containers/outline/index.js +42 -46
- package/dist/containers/outline/outline-item.js +15 -7
- package/dist/containers/outline/style.css +28 -50
- package/dist/editors/slate-editor/index.js +22 -7
- package/dist/utils/get-preview-content.js +3 -1
- package/package.json +1 -1
|
@@ -38,15 +38,18 @@ const ArticleInfo = _ref => {
|
|
|
38
38
|
}
|
|
39
39
|
}, []);
|
|
40
40
|
const resizeWidthEnd = (0, _react.useCallback)(width => {
|
|
41
|
-
const
|
|
42
|
-
window.localStorage.setItem('sf-editor
|
|
43
|
-
...
|
|
44
|
-
width
|
|
41
|
+
const settings = JSON.parse(window.localStorage.getItem('sf-editor') || '{}');
|
|
42
|
+
window.localStorage.setItem('sf-editor', JSON.stringify({
|
|
43
|
+
...settings,
|
|
44
|
+
panelWidth: width
|
|
45
45
|
}));
|
|
46
46
|
}, []);
|
|
47
47
|
(0, _react.useEffect)(() => {
|
|
48
|
-
const
|
|
49
|
-
const
|
|
48
|
+
const settings = JSON.parse(window.localStorage.getItem('sf-editor', '{}')) || {};
|
|
49
|
+
const {
|
|
50
|
+
panelWidth
|
|
51
|
+
} = settings;
|
|
52
|
+
const width = Math.max(MIN_PANEL_WIDTH, Math.min(parseInt(panelWidth, 10) || MIN_PANEL_WIDTH, MAX_PANEL_WIDTH));
|
|
50
53
|
setWidth(width);
|
|
51
54
|
}, []);
|
|
52
55
|
const handleFileDetails = (0, _react.useCallback)(fileDetails => {
|
|
@@ -5,15 +5,32 @@ var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWild
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", {
|
|
6
6
|
value: true
|
|
7
7
|
});
|
|
8
|
-
exports.default = void 0;
|
|
8
|
+
exports.setOutlineSetting = exports.getOutlineSetting = exports.default = void 0;
|
|
9
9
|
var _react = _interopRequireWildcard(require("react"));
|
|
10
10
|
var _reactI18next = require("react-i18next");
|
|
11
|
+
var _classnames = _interopRequireDefault(require("classnames"));
|
|
11
12
|
var _outlineItem = _interopRequireDefault(require("./outline-item"));
|
|
12
13
|
var _useScrollContext = require("../../hooks/use-scroll-context");
|
|
13
14
|
var _constants = require("../../constants");
|
|
14
15
|
var _eventBus = _interopRequireDefault(require("../../utils/event-bus"));
|
|
15
16
|
var _eventTypes = require("../../constants/event-types");
|
|
16
17
|
require("./style.css");
|
|
18
|
+
const getOutlineSetting = () => {
|
|
19
|
+
const currentValue = localStorage.getItem('sf-editor');
|
|
20
|
+
const config = currentValue ? JSON.parse(currentValue) : {};
|
|
21
|
+
const {
|
|
22
|
+
outlineOpen = false
|
|
23
|
+
} = config;
|
|
24
|
+
return outlineOpen;
|
|
25
|
+
};
|
|
26
|
+
exports.getOutlineSetting = getOutlineSetting;
|
|
27
|
+
const setOutlineSetting = isShown => {
|
|
28
|
+
const currentValue = localStorage.getItem('sf-editor');
|
|
29
|
+
const config = currentValue ? JSON.parse(currentValue) : {};
|
|
30
|
+
config['outlineOpen'] = isShown;
|
|
31
|
+
localStorage.setItem('sf-editor', JSON.stringify(config));
|
|
32
|
+
};
|
|
33
|
+
exports.setOutlineSetting = setOutlineSetting;
|
|
17
34
|
const getHeaderList = children => {
|
|
18
35
|
const headerList = [];
|
|
19
36
|
children.forEach(node => {
|
|
@@ -32,52 +49,22 @@ const Outline = _ref => {
|
|
|
32
49
|
} = (0, _reactI18next.useTranslation)(_constants.TRANSLATE_NAMESPACE);
|
|
33
50
|
const scrollRef = (0, _useScrollContext.useScrollContext)();
|
|
34
51
|
const [headerList, setHeaderList] = (0, _react.useState)([]);
|
|
35
|
-
const [activeId, setActiveId] = (0, _react.useState)('');
|
|
36
52
|
const [isShown, setIsShown] = (0, _react.useState)(false);
|
|
37
53
|
const [scrollLeft, setScrollLeft] = (0, _react.useState)(0);
|
|
38
54
|
(0, _react.useEffect)(() => {
|
|
39
55
|
const headerList = getHeaderList(editor.children);
|
|
40
56
|
setHeaderList(headerList);
|
|
41
57
|
}, [editor.children]);
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
const headerItem = headerList[i];
|
|
48
|
-
const dom = document.getElementById(headerItem.id);
|
|
49
|
-
const {
|
|
50
|
-
offsetTop,
|
|
51
|
-
offsetHeight
|
|
52
|
-
} = dom;
|
|
53
|
-
const styles = getComputedStyle(dom);
|
|
54
|
-
const marginTop = parseInt(styles.marginTop);
|
|
55
|
-
if (offsetTop + offsetHeight + marginTop > scrollTop - paddingTop) {
|
|
56
|
-
setActiveId(headerItem.id);
|
|
57
|
-
break;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}, [headerList, scrollRef]);
|
|
61
|
-
(0, _react.useEffect)(() => {
|
|
62
|
-
let observerRefValue = null;
|
|
63
|
-
if (scrollRef.current) {
|
|
64
|
-
scrollRef.current.addEventListener('scroll', handleScroll);
|
|
65
|
-
observerRefValue = scrollRef.current;
|
|
66
|
-
}
|
|
67
|
-
return () => {
|
|
68
|
-
observerRefValue.removeEventListener('scroll', handleScroll);
|
|
69
|
-
};
|
|
70
|
-
}, [handleScroll, scrollRef]);
|
|
71
|
-
const toggleShow = (0, _react.useCallback)(() => {
|
|
72
|
-
setIsShown(prevIsShown => {
|
|
73
|
-
const newIsShown = !prevIsShown;
|
|
74
|
-
setTimeout(() => {
|
|
75
|
-
const eventBus = _eventBus.default.getInstance();
|
|
76
|
-
eventBus.dispatch(_eventTypes.INTERNAL_EVENTS.OUTLINE_STATE_CHANGED, newIsShown);
|
|
77
|
-
}, 0);
|
|
78
|
-
return newIsShown;
|
|
79
|
-
});
|
|
58
|
+
const updateOutlineState = (0, _react.useCallback)(nextState => {
|
|
59
|
+
setOutlineSetting(nextState);
|
|
60
|
+
setIsShown(nextState);
|
|
61
|
+
const eventBus = _eventBus.default.getInstance();
|
|
62
|
+
eventBus.dispatch(_eventTypes.INTERNAL_EVENTS.OUTLINE_STATE_CHANGED);
|
|
80
63
|
}, []);
|
|
64
|
+
const toggleShow = (0, _react.useCallback)(() => {
|
|
65
|
+
const nextState = !isShown;
|
|
66
|
+
updateOutlineState(nextState);
|
|
67
|
+
}, [isShown, updateOutlineState]);
|
|
81
68
|
(0, _react.useEffect)(() => {
|
|
82
69
|
if (!scrollRef.current) return;
|
|
83
70
|
const updateScrollLeft = () => {
|
|
@@ -88,11 +75,21 @@ const Outline = _ref => {
|
|
|
88
75
|
scrollRef.current.removeEventListener('scroll', updateScrollLeft);
|
|
89
76
|
};
|
|
90
77
|
}, [scrollRef]);
|
|
78
|
+
(0, _react.useEffect)(() => {
|
|
79
|
+
const outlineState = getOutlineSetting();
|
|
80
|
+
console.log(outlineState);
|
|
81
|
+
updateOutlineState(outlineState);
|
|
82
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
83
|
+
}, []);
|
|
91
84
|
return /*#__PURE__*/_react.default.createElement("div", {
|
|
92
|
-
className:
|
|
85
|
+
className: (0, _classnames.default)('sf-editor-outline-wrapper', {
|
|
86
|
+
'active': isShown
|
|
87
|
+
}),
|
|
93
88
|
style: {
|
|
94
89
|
left: -scrollLeft
|
|
95
90
|
}
|
|
91
|
+
}, /*#__PURE__*/_react.default.createElement("div", {
|
|
92
|
+
className: "sf-editor-outline"
|
|
96
93
|
}, isShown && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("div", {
|
|
97
94
|
className: "sf-editor-outline-header"
|
|
98
95
|
}, /*#__PURE__*/_react.default.createElement("h2", {
|
|
@@ -106,14 +103,13 @@ const Outline = _ref => {
|
|
|
106
103
|
className: "sf-editor-outline-list-container"
|
|
107
104
|
}, headerList.map((node, index) => /*#__PURE__*/_react.default.createElement(_outlineItem.default, {
|
|
108
105
|
key: index,
|
|
109
|
-
node: node
|
|
110
|
-
|
|
111
|
-
})))), !isShown && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("span", {
|
|
106
|
+
node: node
|
|
107
|
+
}))))), !isShown && /*#__PURE__*/_react.default.createElement("span", {
|
|
112
108
|
id: "sf-editor-outline-menu",
|
|
113
|
-
className: "sf-editor-outline-menu sf-
|
|
109
|
+
className: "sf-editor-outline-menu sf-editor-tooltip iconfont icon-outline",
|
|
114
110
|
onClick: toggleShow
|
|
115
111
|
}, /*#__PURE__*/_react.default.createElement("span", {
|
|
116
112
|
className: "custom-tooltip"
|
|
117
|
-
}, t('Outline'))))
|
|
113
|
+
}, t('Outline'))));
|
|
118
114
|
};
|
|
119
115
|
var _default = exports.default = Outline;
|
|
@@ -10,23 +10,31 @@ var _react = _interopRequireWildcard(require("react"));
|
|
|
10
10
|
var _classnames = _interopRequireDefault(require("classnames"));
|
|
11
11
|
const OutlineItem = _ref => {
|
|
12
12
|
let {
|
|
13
|
-
node
|
|
14
|
-
activeId
|
|
13
|
+
node
|
|
15
14
|
} = _ref;
|
|
15
|
+
const [isHighlighted, setIsHighlighted] = (0, _react.useState)(false);
|
|
16
|
+
const onMouseOver = (0, _react.useCallback)(() => {
|
|
17
|
+
setIsHighlighted(true);
|
|
18
|
+
}, []);
|
|
19
|
+
const onMouseOut = (0, _react.useCallback)(() => {
|
|
20
|
+
setIsHighlighted(false);
|
|
21
|
+
}, []);
|
|
16
22
|
const onItemClick = (0, _react.useCallback)(() => {
|
|
17
23
|
const {
|
|
18
24
|
id
|
|
19
25
|
} = node;
|
|
20
26
|
document.getElementById(id).scrollIntoView();
|
|
21
27
|
}, [node]);
|
|
22
|
-
const className = (0, _classnames.default)({
|
|
23
|
-
'
|
|
24
|
-
'
|
|
25
|
-
'active':
|
|
28
|
+
const className = (0, _classnames.default)('sf-editor-outline-item', {
|
|
29
|
+
'pl-5': node.type === 'header2',
|
|
30
|
+
'pl-7': node.type === 'header3',
|
|
31
|
+
'active': isHighlighted
|
|
26
32
|
});
|
|
27
33
|
return /*#__PURE__*/_react.default.createElement("div", {
|
|
28
34
|
className: className,
|
|
29
|
-
onClick: onItemClick
|
|
35
|
+
onClick: onItemClick,
|
|
36
|
+
onMouseOver: onMouseOver,
|
|
37
|
+
onMouseOut: onMouseOut
|
|
30
38
|
}, node.children.map(child => child.text).join(''));
|
|
31
39
|
};
|
|
32
40
|
var _default = exports.default = OutlineItem;
|
|
@@ -1,16 +1,26 @@
|
|
|
1
|
-
.sf-editor-outline {
|
|
2
|
-
width: 220px;
|
|
1
|
+
.sf-editor-outline-wrapper {
|
|
3
2
|
display: flex;
|
|
3
|
+
margin: 20px 30px 20px 16px;
|
|
4
4
|
min-height: 0;
|
|
5
|
-
|
|
6
|
-
font-size: 14px;
|
|
5
|
+
pointer-events: none;
|
|
7
6
|
position: fixed;
|
|
8
|
-
|
|
7
|
+
bottom: 0;
|
|
9
8
|
top: 100px;
|
|
9
|
+
z-index: 101;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.sf-editor-outline-wrapper.active {
|
|
13
|
+
pointer-events: all;
|
|
10
14
|
}
|
|
11
15
|
|
|
12
|
-
.sf-editor-outline
|
|
13
|
-
|
|
16
|
+
.sf-editor-outline {
|
|
17
|
+
display: flex;
|
|
18
|
+
flex: 1 1;
|
|
19
|
+
flex-direction: column;
|
|
20
|
+
font-size: 14px;
|
|
21
|
+
min-height: 0;
|
|
22
|
+
position: relative;
|
|
23
|
+
width: 220px;
|
|
14
24
|
}
|
|
15
25
|
|
|
16
26
|
.sf-editor-outline-header {
|
|
@@ -38,23 +48,27 @@
|
|
|
38
48
|
}
|
|
39
49
|
|
|
40
50
|
.sf-editor-outline-list-container {
|
|
41
|
-
padding: 0.5rem 0;
|
|
42
|
-
flex: 1 1;
|
|
43
51
|
display: flex;
|
|
52
|
+
flex: 1 1;
|
|
44
53
|
flex-direction: column;
|
|
54
|
+
list-style: none;
|
|
45
55
|
overflow-x: hidden;
|
|
46
56
|
overflow-y: auto;
|
|
47
|
-
|
|
57
|
+
padding: .5rem 0;
|
|
58
|
+
word-break: break-word;
|
|
48
59
|
}
|
|
49
60
|
|
|
50
61
|
.sf-editor-outline-item {
|
|
51
|
-
padding: 4px 0;
|
|
52
|
-
|
|
53
|
-
max-width: 100%;
|
|
62
|
+
padding: 4px 6px 4px 0;
|
|
63
|
+
width: 100%;
|
|
54
64
|
overflow-wrap: anywhere;
|
|
55
65
|
cursor: pointer;
|
|
56
66
|
}
|
|
57
67
|
|
|
68
|
+
.sf-editor-outline-item.active {
|
|
69
|
+
color: #eb8205;
|
|
70
|
+
}
|
|
71
|
+
|
|
58
72
|
.sf-editor-outline-menu {
|
|
59
73
|
line-height: 1;
|
|
60
74
|
font-size: 14px;
|
|
@@ -70,7 +84,7 @@
|
|
|
70
84
|
justify-content: center;
|
|
71
85
|
position: absolute;
|
|
72
86
|
top: 20px;
|
|
73
|
-
left: -15px
|
|
87
|
+
left: -15px;;
|
|
74
88
|
pointer-events: all;
|
|
75
89
|
}
|
|
76
90
|
|
|
@@ -104,43 +118,7 @@
|
|
|
104
118
|
color: #333;
|
|
105
119
|
}
|
|
106
120
|
|
|
107
|
-
.sf-editor-outline .outline-h2,
|
|
108
|
-
.sf-editor-outline .outline-h3 {
|
|
109
|
-
white-space: nowrap;
|
|
110
|
-
overflow: hidden;
|
|
111
|
-
text-overflow: ellipsis;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
.sf-editor-outline .outline-h2 {
|
|
115
|
-
margin-left: 20px;
|
|
116
|
-
line-height: 2.5;
|
|
117
|
-
color:#364149;
|
|
118
|
-
white-space: nowrap;
|
|
119
|
-
cursor:pointer;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
.sf-editor-outline .outline-h2:hover {
|
|
123
|
-
color: #eb8205;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
.sf-editor-outline .outline-h3 {
|
|
127
|
-
margin-left: 40px;
|
|
128
|
-
line-height: 2.5;
|
|
129
|
-
color:#364149;
|
|
130
|
-
white-space: nowrap;
|
|
131
|
-
cursor:pointer;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
.sf-editor-outline .outline-h3:hover {
|
|
135
|
-
color: #eb8205;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
121
|
.sf-editor-outline .empty-container {
|
|
139
122
|
margin-top: 10px;
|
|
140
123
|
text-align: center;
|
|
141
124
|
}
|
|
142
|
-
|
|
143
|
-
.sf-editor-outline .outline-h2.active,
|
|
144
|
-
.sf-editor-outline .outline-h3.active {
|
|
145
|
-
color: #eb8205;
|
|
146
|
-
}
|
|
@@ -18,7 +18,7 @@ var _core = require("../../extension/core");
|
|
|
18
18
|
var _useScrollContext = require("../../hooks/use-scroll-context");
|
|
19
19
|
var _useInsertImage = _interopRequireDefault(require("../../hooks/use-insert-image"));
|
|
20
20
|
var _common = require("../../utils/common");
|
|
21
|
-
var _outline =
|
|
21
|
+
var _outline = _interopRequireWildcard(require("../../containers/outline"));
|
|
22
22
|
var _eventTypes = require("../../constants/event-types");
|
|
23
23
|
require("./style.css");
|
|
24
24
|
const isMacOS = (0, _common.isMac)();
|
|
@@ -45,24 +45,39 @@ function SlateEditor(_ref) {
|
|
|
45
45
|
(0, _useInsertImage.default)(editor);
|
|
46
46
|
const decorate = (0, _extension.useHighlight)(editor);
|
|
47
47
|
|
|
48
|
-
//Adjust article container margin-left value according to isShown of the outline and width of window
|
|
49
|
-
const handleWindowResize =
|
|
48
|
+
// Adjust article container margin-left value according to isShown of the outline and width of window
|
|
49
|
+
const handleWindowResize = (0, _react.useCallback)(() => {
|
|
50
50
|
const rect = scrollRef.current.getBoundingClientRect();
|
|
51
51
|
const articleElement = document.querySelector('.article');
|
|
52
52
|
const articleRect = articleElement ? articleElement.getBoundingClientRect() : null;
|
|
53
|
-
|
|
53
|
+
const isOutlineShow = (0, _outline.getOutlineSetting)();
|
|
54
|
+
if (isOutlineShow && articleRect && (rect.width - articleRect.width) / 2 < 280) {
|
|
54
55
|
setContainerStyle({
|
|
55
|
-
marginLeft:
|
|
56
|
+
marginLeft: 280
|
|
56
57
|
});
|
|
57
58
|
} else {
|
|
58
59
|
setContainerStyle({});
|
|
59
60
|
}
|
|
60
|
-
};
|
|
61
|
+
}, []);
|
|
61
62
|
(0, _react.useEffect)(() => {
|
|
62
63
|
const eventBus = _eventBus.default.getInstance();
|
|
63
64
|
const unsubscribeOutline = eventBus.subscribe(_eventTypes.INTERNAL_EVENTS.OUTLINE_STATE_CHANGED, handleWindowResize);
|
|
64
|
-
|
|
65
|
+
const unsubscribeArticleInfo = eventBus.subscribe(_eventTypes.EXTERNAL_EVENTS.ON_ARTICLE_INFO_TOGGLE, handleWindowResize);
|
|
66
|
+
const unsubscribeHelpInfo = eventBus.subscribe(_eventTypes.EXTERNAL_EVENTS.ON_HELP_INFO_TOGGLE, handleWindowResize);
|
|
67
|
+
return () => {
|
|
68
|
+
unsubscribeHelpInfo();
|
|
69
|
+
unsubscribeArticleInfo();
|
|
70
|
+
unsubscribeOutline();
|
|
71
|
+
};
|
|
65
72
|
}, [handleWindowResize]);
|
|
73
|
+
(0, _react.useEffect)(() => {
|
|
74
|
+
handleWindowResize();
|
|
75
|
+
window.addEventListener('resize', handleWindowResize);
|
|
76
|
+
return () => {
|
|
77
|
+
window.removeEventListener('resize', handleWindowResize);
|
|
78
|
+
};
|
|
79
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
80
|
+
}, []);
|
|
66
81
|
const onChange = (0, _react.useCallback)(value => {
|
|
67
82
|
setSlateValue(value);
|
|
68
83
|
if (editor.forceNormalize) return;
|
|
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
var _slate = require("slate");
|
|
8
8
|
var _seafileEditor = require("@seafile/seafile-editor");
|
|
9
|
+
const PREVIEW_TEXT_LENGTH = 150;
|
|
9
10
|
const getPreviewContent = function (content) {
|
|
10
11
|
let isMarkdown = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
|
|
11
12
|
const slateNodes = isMarkdown ? (0, _seafileEditor.mdStringToSlate)(content) : content;
|
|
@@ -48,7 +49,8 @@ const getPreviewText = (content, previewContent) => {
|
|
|
48
49
|
for (let index = 0; index < content.length; index++) {
|
|
49
50
|
previewText += getTextOfNode(content[index]) + ' ';
|
|
50
51
|
let textLength = previewText.length;
|
|
51
|
-
if (textLength >=
|
|
52
|
+
if (textLength >= PREVIEW_TEXT_LENGTH) {
|
|
53
|
+
previewText = textLength > PREVIEW_TEXT_LENGTH ? previewText.slice(0, PREVIEW_TEXT_LENGTH) : previewText;
|
|
52
54
|
break;
|
|
53
55
|
}
|
|
54
56
|
}
|