@seafile/sdoc-editor 0.4.2 → 0.4.4-1

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.
@@ -1,4 +1,5 @@
1
1
  import axios from 'axios';
2
+ import slugid from 'slugid';
2
3
  class SeafileAPI {
3
4
  constructor(server, token) {
4
5
  this.deleteSdocRevision = docUuid => {
@@ -25,16 +26,15 @@ class SeafileAPI {
25
26
  return this.req.post(url, form);
26
27
  }
27
28
  }
28
- getImageFileNameWithTimestamp(file) {
29
- var d = Date.now();
30
- return 'image-' + d.toString() + file.name.slice(file.name.lastIndexOf('.'));
29
+ getImageFileNameWithUuid(file) {
30
+ return 'image-' + slugid.nice() + file.name.slice(file.name.lastIndexOf('.'));
31
31
  }
32
32
  uploadSdocImage(docUuid, imageFiles) {
33
33
  const url = '/api/v2.1/seadoc/upload-image/' + docUuid + '/';
34
34
  const form = new FormData();
35
35
  for (const fileItem of imageFiles) {
36
36
  if (fileItem.type.startsWith('image/')) {
37
- const fileName = this.getImageFileNameWithTimestamp(fileItem);
37
+ const fileName = this.getImageFileNameWithUuid(fileItem);
38
38
  const file = new File([fileItem], fileName, {
39
39
  type: fileItem.type
40
40
  });
@@ -0,0 +1,29 @@
1
+ .sdoc-editor-container {
2
+ flex: 1;
3
+ display: flex;
4
+ min-height: 0;
5
+ }
6
+
7
+ .sdoc-md-scroll-container {
8
+ display: flex;
9
+ overflow: auto;
10
+ }
11
+
12
+ .sdoc-md-scroll-container .sdoc-article-container {
13
+ width: 100%;
14
+ margin: 0 340px 0 40px !important;
15
+ }
16
+
17
+ .sdoc-md-scroll-container .sdoc-article-container .article .sdoc-header-2 {
18
+ border-bottom: 1px solid #ccc;
19
+ }
20
+
21
+ .sdoc-md-outline-container {
22
+ height: 80%;
23
+ overflow-y: auto;
24
+ padding-right: 1rem;
25
+ position: fixed;
26
+ right: 0;
27
+ top: 97px;
28
+ width: 300px;
29
+ }
@@ -1,5 +1,6 @@
1
1
  import React, { useCallback, useMemo, Fragment } from 'react';
2
2
  import { Editable, ReactEditor, Slate } from '@seafile/slate-react';
3
+ import { Editor } from '@seafile/slate';
3
4
  import { renderLeaf, renderElement, ContextToolbar, SideToolbar } from '../extension';
4
5
  import { getAboveBlockNode, getNextNode, getPrevNode, isSelectionAtBlockEnd, isSelectionAtBlockStart } from '../extension/core';
5
6
  import EventProxy from '../utils/event-handler';
@@ -12,6 +13,7 @@ import EventBus from '../utils/event-bus';
12
13
  import { ArticleContainer } from '../layout';
13
14
  import { useScrollContext } from '../hooks/use-scroll-context';
14
15
  import { SetNodeToDecorations } from '../highlight';
16
+ import { IMAGE } from '../extension/constants';
15
17
  const EditableArticle = _ref => {
16
18
  let {
17
19
  isShowComment,
@@ -132,6 +134,24 @@ const EditableArticle = _ref => {
132
134
 
133
135
  // eslint-disable-next-line react-hooks/exhaustive-deps
134
136
  }, [scrollRef]);
137
+ const handleScrollIntoView = useCallback((editor, domRange) => {
138
+ try {
139
+ const {
140
+ selection
141
+ } = editor;
142
+ const [imageNodeEntry] = Editor.nodes(editor, {
143
+ match: n => n.type === IMAGE
144
+ });
145
+ if (imageNodeEntry) return;
146
+ const domNode = ReactEditor.toDOMNode(editor, selection.focus.path);
147
+ if (!domNode) return;
148
+ domNode.scrollIntoView({
149
+ block: 'nearest'
150
+ });
151
+ } catch (error) {
152
+ //
153
+ }
154
+ }, []);
135
155
  return /*#__PURE__*/React.createElement(Slate, {
136
156
  editor: editor,
137
157
  value: slateValue,
@@ -139,6 +159,7 @@ const EditableArticle = _ref => {
139
159
  }, /*#__PURE__*/React.createElement(ArticleContainer, {
140
160
  editor: editor
141
161
  }, /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement(ContextToolbar, null), /*#__PURE__*/React.createElement(SetNodeToDecorations, null), /*#__PURE__*/React.createElement(Editable, {
162
+ scrollSelectionIntoView: handleScrollIntoView,
142
163
  cursors: cursors,
143
164
  renderElement: renderElement,
144
165
  renderLeaf: renderLeaf,
@@ -33,7 +33,8 @@ export const changeToCodeBlock = function (editor) {
33
33
  let language = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
34
34
  let position = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : INSERT_POSITION.CURRENT;
35
35
  // Summarizes the strings for the selected highest-level node
36
- let strArr = [];
36
+ let strArr = [],
37
+ path = Editor.path(editor, editor.selection);
37
38
  if (position === INSERT_POSITION.AFTER) {
38
39
  strArr = [''];
39
40
  } else {
@@ -72,7 +73,6 @@ export const changeToCodeBlock = function (editor) {
72
73
  }]
73
74
  }]
74
75
  };
75
- const path = Editor.path(editor, editor.selection);
76
76
  if (position === INSERT_POSITION.AFTER) {
77
77
  Transforms.insertNodes(editor, newCodeBlockNode, {
78
78
  mode: 'highest',
@@ -1,6 +1,6 @@
1
1
  import SDocEditor from './editor/sdoc-editor';
2
2
  import RevisionEditor from './editor/revision-editor';
3
- import { DiffViewer, SDocViewer, PublishedRevisionDiffViewer } from './views';
3
+ import { DiffViewer, SDocViewer, PublishedRevisionDiffViewer, SDocMdViewer } from './views';
4
4
  import SDocOutline from './outline';
5
5
  import EventBus from './utils/event-bus';
6
- export { SDocEditor, RevisionEditor, SDocViewer, SDocOutline, EventBus, DiffViewer, PublishedRevisionDiffViewer };
6
+ export { SDocEditor, RevisionEditor, SDocViewer, SDocOutline, EventBus, DiffViewer, PublishedRevisionDiffViewer, SDocMdViewer };
@@ -0,0 +1,70 @@
1
+ import React, { useCallback, useEffect, useState } from 'react';
2
+ import { useTranslation } from 'react-i18next';
3
+ import OutlineItem from './outline-item';
4
+ import { useScrollContext } from '../hooks/use-scroll-context';
5
+ import './style.css';
6
+ const getHeaderList = children => {
7
+ const headerList = [];
8
+ children.forEach(node => {
9
+ if (node.type === 'header2' || node.type === 'header3') {
10
+ headerList.push(node);
11
+ }
12
+ });
13
+ return headerList;
14
+ };
15
+ const Outline = _ref => {
16
+ let {
17
+ editor
18
+ } = _ref;
19
+ const {
20
+ t
21
+ } = useTranslation();
22
+ const scrollRef = useScrollContext();
23
+ const [headerList, setHeaderList] = useState([]);
24
+ const [activeId, setActiveId] = useState('');
25
+ useEffect(() => {
26
+ const headerList = getHeaderList(editor.children);
27
+ setHeaderList(headerList);
28
+ }, [editor.children]);
29
+ const handleScroll = useCallback(e => {
30
+ const scrollTop = scrollRef.current.scrollTop;
31
+ const styles = getComputedStyle(scrollRef === null || scrollRef === void 0 ? void 0 : scrollRef.current);
32
+ const paddingTop = parseInt(styles.paddingTop);
33
+ for (let i = 0; i < headerList.length; i++) {
34
+ const headerItem = headerList[i];
35
+ const dom = document.getElementById(headerItem.id);
36
+ const {
37
+ offsetTop,
38
+ offsetHeight
39
+ } = dom;
40
+ const styles = getComputedStyle(dom);
41
+ const marginTop = parseInt(styles.marginTop);
42
+ if (offsetTop + offsetHeight + marginTop > scrollTop - paddingTop) {
43
+ setActiveId(headerItem.id);
44
+ break;
45
+ }
46
+ }
47
+ }, [headerList, scrollRef]);
48
+ useEffect(() => {
49
+ let observerRefValue = null;
50
+ if (scrollRef.current) {
51
+ scrollRef.current.addEventListener('scroll', handleScroll);
52
+ observerRefValue = scrollRef.current;
53
+ }
54
+ return () => {
55
+ observerRefValue.removeEventListener('scroll', handleScroll);
56
+ };
57
+ }, [handleScroll, scrollRef]);
58
+ return /*#__PURE__*/React.createElement("div", {
59
+ className: "sdoc-md-editor-outline"
60
+ }, headerList.length === 0 && /*#__PURE__*/React.createElement("div", {
61
+ className: "empty-container"
62
+ }, t('No_out_line')), headerList.length > 0 && headerList.map((node, index) => {
63
+ return /*#__PURE__*/React.createElement(OutlineItem, {
64
+ key: index,
65
+ node: node,
66
+ activeId: activeId
67
+ });
68
+ }));
69
+ };
70
+ export default Outline;
@@ -0,0 +1,24 @@
1
+ import React, { useCallback } from 'react';
2
+ import classNames from 'classnames';
3
+ const OutlineItem = _ref => {
4
+ let {
5
+ node,
6
+ activeId
7
+ } = _ref;
8
+ const onItemClick = useCallback(() => {
9
+ const {
10
+ id
11
+ } = node;
12
+ document.getElementById(id).scrollIntoView();
13
+ }, [node]);
14
+ const className = classNames({
15
+ 'outline-h2': node.type === 'header2',
16
+ 'outline-h3': node.type === 'header3',
17
+ 'active': node.id === activeId
18
+ });
19
+ return /*#__PURE__*/React.createElement("div", {
20
+ className: className,
21
+ onClick: onItemClick
22
+ }, node.children.map(child => child.text).join(''));
23
+ };
24
+ export default OutlineItem;
@@ -0,0 +1,45 @@
1
+ .sdoc-md-editor-outline {
2
+ border-left: 1px solid #ddd;
3
+ padding: .5rem 1rem .5rem 0;
4
+ }
5
+
6
+ .sdoc-md-editor-outline .outline-h2,
7
+ .sdoc-md-editor-outline .outline-h3 {
8
+ white-space: nowrap;
9
+ overflow: hidden;
10
+ text-overflow: ellipsis;
11
+ }
12
+
13
+ .sdoc-md-editor-outline .outline-h2 {
14
+ margin-left: 20px;
15
+ line-height: 2.5;
16
+ color:#364149;
17
+ white-space: nowrap;
18
+ cursor:pointer;
19
+ }
20
+
21
+ .sdoc-md-editor-outline .outline-h2:hover {
22
+ color: #eb8205;
23
+ }
24
+
25
+ .sdoc-md-editor-outline .outline-h3 {
26
+ margin-left: 40px;
27
+ line-height: 2.5;
28
+ color:#364149;
29
+ white-space: nowrap;
30
+ cursor:pointer;
31
+ }
32
+
33
+ .sdoc-md-editor-outline .outline-h3:hover {
34
+ color: #eb8205;
35
+ }
36
+
37
+ .sdoc-md-editor-outline .empty-container {
38
+ margin-top: 10px;
39
+ text-align: center;
40
+ }
41
+
42
+ .sdoc-md-editor-outline .outline-h2.active,
43
+ .sdoc-md-editor-outline .outline-h3.active {
44
+ color: #eb8205;
45
+ }
@@ -2,4 +2,5 @@ import SDocViewer from './sdoc-viewer';
2
2
  import DiffViewer from './sdoc-diff-viewer';
3
3
  import RevisionDiffViewer from './revision-diff-viewer';
4
4
  import PublishedRevisionDiffViewer from './published-revision-diff-viewer';
5
- export { SDocViewer, DiffViewer, RevisionDiffViewer, PublishedRevisionDiffViewer };
5
+ import SDocMdViewer from './sdoc-md-viewer';
6
+ export { SDocViewer, DiffViewer, RevisionDiffViewer, PublishedRevisionDiffViewer, SDocMdViewer };
@@ -0,0 +1,46 @@
1
+ import React, { useRef } from 'react';
2
+ import { createDefaultEditor } from '../extension';
3
+ import withNodeId from '../node-id';
4
+ import { generateDefaultDocContent } from '../../utils';
5
+ import { EditorContainer } from '../layout';
6
+ import ReadOnlyArticle from './readonly-article';
7
+ import { ColorProvider } from '../hooks/use-color-context';
8
+ import { ScrollContext } from '../hooks/use-scroll-context';
9
+ import Outline from '../md-outline';
10
+ import '../assets/css/sdoc-md-viewer.css';
11
+ const SDocMdViewer = _ref => {
12
+ let {
13
+ editor,
14
+ document,
15
+ showOutline,
16
+ scrollRef: propsScrollRef
17
+ } = _ref;
18
+ const validEditor = editor || withNodeId(createDefaultEditor());
19
+ const slateValue = (document || generateDefaultDocContent()).children;
20
+ const scrollRef = useRef(null);
21
+ const currentScrollRef = propsScrollRef || scrollRef;
22
+ return /*#__PURE__*/React.createElement(EditorContainer, {
23
+ editor: validEditor,
24
+ readonly: true
25
+ }, /*#__PURE__*/React.createElement(ColorProvider, null, /*#__PURE__*/React.createElement("div", {
26
+ ref: scrollRef,
27
+ className: "sdoc-md-scroll-container"
28
+ }, /*#__PURE__*/React.createElement(ScrollContext.Provider, {
29
+ value: {
30
+ scrollRef: currentScrollRef
31
+ }
32
+ }, /*#__PURE__*/React.createElement(ReadOnlyArticle, {
33
+ editor: validEditor,
34
+ slateValue: slateValue,
35
+ isShowComment: false
36
+ }), showOutline && /*#__PURE__*/React.createElement("div", {
37
+ className: "sdoc-md-outline-container"
38
+ }, /*#__PURE__*/React.createElement(Outline, {
39
+ editor: validEditor
40
+ }))))));
41
+ };
42
+ SDocMdViewer.defaultProps = {
43
+ showToolbar: false,
44
+ showOutline: false
45
+ };
46
+ export default SDocMdViewer;
@@ -19,7 +19,9 @@ const DocInfo = _ref => {
19
19
  } = _ref;
20
20
  const onInternalLinkClick = useCallback(() => {
21
21
  const eventBus = EventBus.getInstance();
22
- eventBus.dispatch(EXTERNAL_EVENT.INTERNAL_LINK_CLICK);
22
+ eventBus.dispatch(EXTERNAL_EVENT.INTERNAL_LINK_CLICK, {
23
+ internalLink: window.location.href
24
+ });
23
25
  }, []);
24
26
  const toggleStar = useCallback(() => {
25
27
  const eventBus = EventBus.getInstance();
@@ -80,7 +82,13 @@ const DocInfo = _ref => {
80
82
  className: "doc-name"
81
83
  }, oldDocName), /*#__PURE__*/React.createElement("div", {
82
84
  className: "sdoc-revision-order"
83
- }, t('Revision') + ' ' + revisionId), isPublished && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
85
+ }, t('Revision') + ' ' + revisionId), isShowInternalLink && /*#__PURE__*/React.createElement("span", {
86
+ className: "doc-icon"
87
+ }, /*#__PURE__*/React.createElement("span", {
88
+ className: "internal-link sdocfont sdoc-link",
89
+ title: t('Internal_link'),
90
+ onClick: onInternalLinkClick
91
+ })), isPublished && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
84
92
  className: "sdoc-revision-published-tip"
85
93
  }, t('Published')), /*#__PURE__*/React.createElement("div", {
86
94
  className: "sdoc-revision-source-doc",
package/dist/index.js CHANGED
@@ -4,4 +4,5 @@ import SimpleEditor from './pages/simple-editor';
4
4
  import SimpleViewer from './pages/simple-viewer';
5
5
  import DiffViewer from './pages/diff-viewer';
6
6
  import PublishedRevisionViewer from './pages/published-revision-viewer';
7
- export { SDocViewer, SimpleEditor, SimpleViewer, EventBus, EXTERNAL_EVENT, DiffViewer, PublishedRevisionViewer };
7
+ import MarkdownViewer from './pages/markdown-viewer';
8
+ export { SDocViewer, SimpleEditor, SimpleViewer, EventBus, EXTERNAL_EVENT, DiffViewer, PublishedRevisionViewer, MarkdownViewer };
@@ -0,0 +1,19 @@
1
+ import React from 'react';
2
+ import context from '../context';
3
+ import ErrorBoundary from './error-boundary';
4
+ import { SDocMdViewer } from '../basic-sdk';
5
+ import '../assets/css/simple-viewer.css';
6
+ const MarkdownViewer = _ref => {
7
+ let {
8
+ document,
9
+ showOutline,
10
+ scrollRef
11
+ } = _ref;
12
+ context.initApi();
13
+ return /*#__PURE__*/React.createElement(ErrorBoundary, null, /*#__PURE__*/React.createElement(SDocMdViewer, {
14
+ document: document,
15
+ showOutline: showOutline,
16
+ scrollRef: scrollRef
17
+ }));
18
+ };
19
+ export default MarkdownViewer;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seafile/sdoc-editor",
3
- "version": "0.4.2",
3
+ "version": "0.4.4-1",
4
4
  "private": false,
5
5
  "description": "This is a sdoc editor",
6
6
  "main": "dist/index.js",