@seafile/sdoc-editor 0.5.65 → 0.5.67-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.
Files changed (51) hide show
  1. package/dist/assets/css/plugin-editor.css +3 -0
  2. package/dist/basic-sdk/extension/commons/index.js +2 -1
  3. package/dist/basic-sdk/extension/commons/select/_option.js +32 -0
  4. package/dist/basic-sdk/extension/commons/select/field-setting.js +101 -0
  5. package/dist/basic-sdk/extension/commons/select/index.js +135 -0
  6. package/dist/basic-sdk/extension/commons/select/menu/index.js +4 -0
  7. package/dist/basic-sdk/extension/commons/select/menu/item.js +32 -0
  8. package/dist/basic-sdk/extension/commons/select/menu/menu.js +27 -0
  9. package/dist/basic-sdk/extension/commons/select/menu/style.css +43 -0
  10. package/dist/basic-sdk/extension/commons/select/style.css +149 -0
  11. package/dist/basic-sdk/extension/constants/element-type.js +4 -0
  12. package/dist/basic-sdk/extension/constants/index.js +2 -2
  13. package/dist/basic-sdk/extension/constants/menus-config.js +6 -1
  14. package/dist/basic-sdk/extension/plugins/column/constants/cell-types.js +29 -0
  15. package/dist/basic-sdk/extension/plugins/column/constants/column.js +28 -0
  16. package/dist/basic-sdk/extension/plugins/column/helpers.js +62 -0
  17. package/dist/basic-sdk/extension/plugins/column/index.js +12 -0
  18. package/dist/basic-sdk/extension/plugins/column/menu/index.js +28 -0
  19. package/dist/basic-sdk/extension/plugins/column/model.js +14 -0
  20. package/dist/basic-sdk/extension/plugins/column/plugin.js +24 -0
  21. package/dist/basic-sdk/extension/plugins/column/render-elem.js +111 -0
  22. package/dist/basic-sdk/extension/plugins/font/helpers.js +1 -0
  23. package/dist/basic-sdk/extension/plugins/group/index.js +7 -0
  24. package/dist/basic-sdk/extension/plugins/group/render-elem.js +17 -0
  25. package/dist/basic-sdk/extension/plugins/index.js +4 -2
  26. package/dist/basic-sdk/extension/plugins/text-align/helpers.js +1 -0
  27. package/dist/basic-sdk/extension/render/custom-element.js +12 -1
  28. package/dist/basic-sdk/extension/toolbar/header-toolbar/index.js +7 -2
  29. package/dist/basic-sdk/extension/toolbar/insert-element-toolbar/index.js +19 -4
  30. package/dist/basic-sdk/extension/toolbar/side-toolbar/index.js +16 -1
  31. package/dist/basic-sdk/extension/toolbar/side-toolbar/side-menu.js +10 -3
  32. package/dist/basic-sdk/hooks/use-force-update.js +9 -0
  33. package/dist/basic-sdk/utils/rebase.js +93 -14
  34. package/dist/components/doc-operations/revision-operations/index.js +1 -0
  35. package/dist/index.js +3 -1
  36. package/dist/pages/document-plugin-editor.js +46 -0
  37. package/dist/pages/document-plugin-viewer.js +55 -0
  38. package/package.json +1 -1
  39. package/public/index.html +21 -22
  40. package/public/media/dtable-font.css +1566 -0
  41. package/public/media/dtable-fonts/dtable-font.eot +0 -0
  42. package/public/media/dtable-fonts/dtable-font.svg +793 -0
  43. package/public/media/dtable-fonts/dtable-font.ttf +0 -0
  44. package/public/media/dtable-fonts/dtable-font.woff +0 -0
  45. package/public/media/dtable-fonts/dtable-font.woff2 +0 -0
  46. package/public/media/sdoc-editor-font/iconfont.eot +0 -0
  47. package/public/media/sdoc-editor-font/iconfont.svg +6 -0
  48. package/public/media/sdoc-editor-font/iconfont.ttf +0 -0
  49. package/public/media/sdoc-editor-font/iconfont.woff +0 -0
  50. package/public/media/sdoc-editor-font/iconfont.woff2 +0 -0
  51. package/public/media/sdoc-editor-font.css +22 -8
@@ -25,6 +25,77 @@ export const hasConflict = content => {
25
25
  }
26
26
  return flag;
27
27
  };
28
+ const expandGroup = content => {
29
+ if ([ELEMENT_TYPE.UNORDERED_LIST, ELEMENT_TYPE.ORDERED_LIST].includes(content.type)) {
30
+ return [_objectSpread(_objectSpread({}, content), {}, {
31
+ children: content.children.map(item => {
32
+ if (item.type === ELEMENT_TYPE.GROUP) {
33
+ return expandGroup(item);
34
+ }
35
+ return item;
36
+ }).flat(1)
37
+ })];
38
+ }
39
+ return content.type === ELEMENT_TYPE.GROUP ? content.children : [content];
40
+ };
41
+ const mergeChanges = changes => {
42
+ if (!Array.isArray(changes) || changes.length === 0) return changes;
43
+ let value = [];
44
+ let i = 0;
45
+ // while (i < changes.length) {
46
+ // const change = changes[i];
47
+ // const lastChange = value[value.length - 1];
48
+ // if (change && lastChange && change[REBASE_MARK_KEY.MODIFY_TYPE] === lastChange[REBASE_MARK_KEY.MODIFY_TYPE] && [MODIFY_TYPE.ADD, MODIFY_TYPE.DELETE].includes(change[REBASE_MARK_KEY.MODIFY_TYPE])) {
49
+ // if (lastChange.type === ELEMENT_TYPE.GROUP) {
50
+ // change[REBASE_MARK_KEY.MODIFY_TYPE] && delete change[REBASE_MARK_KEY.MODIFY_TYPE];
51
+ // lastChange.children.push(change);
52
+ // } else {
53
+ // value = value.slice(0, value.length - 1);
54
+ // const modifyType = change[REBASE_MARK_KEY.MODIFY_TYPE];
55
+ // lastChange[REBASE_MARK_KEY.MODIFY_TYPE] && delete lastChange[REBASE_MARK_KEY.MODIFY_TYPE];
56
+ // change[REBASE_MARK_KEY.MODIFY_TYPE] && delete change[REBASE_MARK_KEY.MODIFY_TYPE];
57
+ // value.push({
58
+ // id: lastChange.id + '_group',
59
+ // type: ELEMENT_TYPE.GROUP,
60
+ // [REBASE_MARK_KEY.MODIFY_TYPE]: modifyType,
61
+ // children: [lastChange, change],
62
+ // });
63
+ // }
64
+ // i++;
65
+ // } else {
66
+ // value.push(change);
67
+ // i++;
68
+ // }
69
+ // }
70
+
71
+ // also add
72
+
73
+ while (i < changes.length) {
74
+ const change = changes[i];
75
+ const lastChange = value[value.length - 1];
76
+ if (change && lastChange && change[REBASE_MARK_KEY.MODIFY_TYPE] === MODIFY_TYPE.ADD && lastChange[REBASE_MARK_KEY.MODIFY_TYPE] === MODIFY_TYPE.DELETE) {
77
+ value = value.slice(0, value.length - 1);
78
+ lastChange[REBASE_MARK_KEY.MODIFY_TYPE] && delete lastChange[REBASE_MARK_KEY.MODIFY_TYPE];
79
+ change[REBASE_MARK_KEY.MODIFY_TYPE] && delete change[REBASE_MARK_KEY.MODIFY_TYPE];
80
+ value.push({
81
+ id: change.id.endsWith('_group') ? change.id : change.id + '_group',
82
+ type: ELEMENT_TYPE.GROUP,
83
+ [REBASE_MARK_KEY.MODIFY_TYPE]: MODIFY_TYPE.MODIFY,
84
+ children: expandGroup(change),
85
+ [REBASE_MARK_KEY.OLD_ELEMENT]: {
86
+ id: lastChange.id.endsWith('_group') ? lastChange.id : lastChange.id + '_group',
87
+ type: ELEMENT_TYPE.GROUP,
88
+ children: expandGroup(lastChange)
89
+ }
90
+ });
91
+ i++;
92
+ } else {
93
+ value.push(change);
94
+ i++;
95
+ }
96
+ }
97
+ return value;
98
+ };
28
99
  const getChanges = (masterContent, revisionContent) => {
29
100
  const {
30
101
  map: masterContentMap,
@@ -43,15 +114,21 @@ const getChanges = (masterContent, revisionContent) => {
43
114
  removed
44
115
  } = idDiff;
45
116
  if (added) {
46
- const addedList = value.map(item => _objectSpread(_objectSpread({}, currentContentMap[item]), {}, {
47
- [REBASE_MARK_KEY.MODIFY_TYPE]: MODIFY_TYPE.ADD
48
- }));
49
- content.push(...addedList);
117
+ // merge consecutive identical operations
118
+ content.push({
119
+ id: value[0].id + '_group',
120
+ type: ELEMENT_TYPE.GROUP,
121
+ [REBASE_MARK_KEY.MODIFY_TYPE]: MODIFY_TYPE.ADD,
122
+ children: value.map(item => currentContentMap[item])
123
+ });
50
124
  } else if (removed) {
51
- const deletedList = value.map(item => _objectSpread(_objectSpread({}, masterContentMap[item]), {}, {
52
- [REBASE_MARK_KEY.MODIFY_TYPE]: MODIFY_TYPE.DELETE
53
- }));
54
- content.push(...deletedList);
125
+ // merge consecutive identical operations
126
+ content.push({
127
+ id: value[0].id + '_group',
128
+ type: ELEMENT_TYPE.GROUP,
129
+ [REBASE_MARK_KEY.MODIFY_TYPE]: MODIFY_TYPE.DELETE,
130
+ children: value.map(item => currentContentMap[item])
131
+ });
55
132
  } else {
56
133
  value.forEach(elementId => {
57
134
  if (ObjectUtils.isSameObject(masterContentMap[elementId], currentContentMap[elementId])) {
@@ -76,7 +153,7 @@ const getChanges = (masterContent, revisionContent) => {
76
153
  });
77
154
  }
78
155
  });
79
- return content;
156
+ return mergeChanges(content);
80
157
  };
81
158
  const getMergeElement = (diffElement, baseElement) => {
82
159
  const modifyType = diffElement[REBASE_MARK_KEY.MODIFY_TYPE];
@@ -86,7 +163,7 @@ const getMergeElement = (diffElement, baseElement) => {
86
163
  // revision does not have this element, master has this element
87
164
  if (modifyType === MODIFY_TYPE.DELETE) {
88
165
  // base content does not have this element, indicating that it is newly added by master and needs to be retained, and will not be counted as a conflict.
89
- if (!baseElement) return [newElement];
166
+ if (!baseElement) return expandGroup(newElement);
90
167
 
91
168
  // base content has this element, master modified it, indicating that revision deleted it, and the user manually selected the conflict
92
169
  if (!ObjectUtils.isSameObject(baseElement, diffElement, [REBASE_MARK_KEY.MODIFY_TYPE])) {
@@ -101,7 +178,7 @@ const getMergeElement = (diffElement, baseElement) => {
101
178
  // revision has this element, master does not have this element
102
179
  if (modifyType === MODIFY_TYPE.ADD) {
103
180
  // base content does not have this element, indicating that it is newly added by revision and needs to be retained, and will not be counted as a conflict.
104
- if (!baseElement) return [newElement];
181
+ if (!baseElement) return expandGroup(newElement);
105
182
 
106
183
  // master deleted it, revision modified it, and the user manually selected the conflict
107
184
  if (!ObjectUtils.isSameObject(baseElement, diffElement, [REBASE_MARK_KEY.MODIFY_TYPE])) {
@@ -161,10 +238,10 @@ const getMergeElement = (diffElement, baseElement) => {
161
238
  [REBASE_MARK_KEY.ORIGIN]: REBASE_ORIGIN.MY
162
239
  })];
163
240
  }
164
- if (ObjectUtils.isSameObject(masterElement, baseElement)) return [newElement];
241
+ if (ObjectUtils.isSameObject(masterElement, baseElement)) return expandGroup(newElement);
165
242
  if (ObjectUtils.isSameObject(newElement, baseElement)) return [masterElement];
166
243
  if (ObjectUtils.isSameObject(masterElement, newElement, ['type'])) {
167
- if (ObjectUtils.isSameObject(masterElement, baseElement, ['type'])) return [newElement];
244
+ if (ObjectUtils.isSameObject(masterElement, baseElement, ['type'])) return expandGroup(newElement);
168
245
  if (ObjectUtils.isSameObject(newElement, baseElement, ['type'])) return [masterElement];
169
246
  }
170
247
 
@@ -175,7 +252,7 @@ const getMergeElement = (diffElement, baseElement) => {
175
252
  })];
176
253
  }
177
254
  newElement[REBASE_MARK_KEY.OLD_ELEMENT] && delete newElement[REBASE_MARK_KEY.OLD_ELEMENT];
178
- return [newElement];
255
+ return expandGroup(newElement);
179
256
  };
180
257
  const getMergeContent = (baseContent, diffChanges) => {
181
258
  const {
@@ -234,7 +311,9 @@ export const getRebase = (masterContent, baseContent, revisionContent) => {
234
311
  };
235
312
  }
236
313
  const diffChanges = getChanges(masterContent, revisionContent);
314
+ console.log('diffChanges: ', diffChanges);
237
315
  const content = getMergeContent(baseContent, diffChanges);
316
+ console.log('content: ', content);
238
317
  return {
239
318
  canMerge: canMerge(content, revisionContent.children),
240
319
  isNeedReplaceMaster: true,
@@ -33,6 +33,7 @@ const RevisionOperations = _ref => {
33
33
  loadDocument
34
34
  } = useDocument();
35
35
  useEffect(() => {
36
+ return;
36
37
  if (!isSdocRevision) return;
37
38
  if (isShowChanges) return;
38
39
  if (isPublished) return;
package/dist/index.js CHANGED
@@ -6,4 +6,6 @@ import DiffViewer from './pages/diff-viewer';
6
6
  import PublishedRevisionViewer from './pages/published-revision-viewer';
7
7
  import WikiViewer from './pages/wiki-viewer';
8
8
  import SdocWikiViewer from './pages/sdoc-wiki-viewer';
9
- export { SDocViewer, SimpleEditor, SimpleViewer, EventBus, EXTERNAL_EVENT, DiffViewer, PublishedRevisionViewer, WikiViewer, SdocWikiViewer };
9
+ import DocumentPluginEditor from './pages/document-plugin-editor';
10
+ import DocumentPluginViewer from './pages/document-plugin-viewer';
11
+ export { SDocViewer, SimpleEditor, SimpleViewer, EventBus, EXTERNAL_EVENT, DiffViewer, PublishedRevisionViewer, WikiViewer, SdocWikiViewer, DocumentPluginEditor, DocumentPluginViewer };
@@ -0,0 +1,46 @@
1
+ import React, { useMemo } from 'react';
2
+ import { withTranslation } from 'react-i18next';
3
+ import context from '../context';
4
+ import { SDocEditor } from '../basic-sdk';
5
+ import { PAGE_EDIT_AREA_WIDTH } from '../basic-sdk/constants';
6
+ import { createDefaultEditor } from '../basic-sdk/extension';
7
+ import withNodeId from '../basic-sdk/node-id';
8
+ import { withSocketIO } from '../basic-sdk/socket';
9
+ import { ColumnPlugin } from '../basic-sdk/extension/plugins';
10
+ import ErrorBoundary from './error-boundary';
11
+ import '../assets/css/simple-editor.css';
12
+ import '../assets/css/plugin-editor.css';
13
+ const DocumentPluginEditor = _ref => {
14
+ let {
15
+ document,
16
+ showOutline,
17
+ scrollRef,
18
+ columns
19
+ } = _ref;
20
+ context.initApi();
21
+ const validEditor = useMemo(() => {
22
+ const withColumnPlugin = ColumnPlugin.editorPlugin;
23
+ const defaultEditor = withColumnPlugin(createDefaultEditor());
24
+ const editorConfig = context.getEditorConfig();
25
+ const newEditor = withNodeId(withSocketIO(defaultEditor, {
26
+ document,
27
+ config: editorConfig
28
+ }));
29
+ const {
30
+ cursors
31
+ } = document;
32
+ newEditor.columns = columns || [];
33
+ newEditor.cursors = cursors || {};
34
+ newEditor.width = PAGE_EDIT_AREA_WIDTH; // default width
35
+ return newEditor;
36
+ // eslint-disable-next-line react-hooks/exhaustive-deps
37
+ }, []);
38
+ return /*#__PURE__*/React.createElement(ErrorBoundary, null, /*#__PURE__*/React.createElement(SDocEditor, {
39
+ editor: validEditor,
40
+ scrollRef: scrollRef,
41
+ document: document,
42
+ showComment: false,
43
+ showOutline: showOutline
44
+ }));
45
+ };
46
+ export default withTranslation('sdoc-editor')(DocumentPluginEditor);
@@ -0,0 +1,55 @@
1
+ import React, { useEffect, useMemo } from 'react';
2
+ import { withTranslation } from 'react-i18next';
3
+ import context from '../context';
4
+ import { SDocViewer } from '../basic-sdk';
5
+ import { PAGE_EDIT_AREA_WIDTH } from '../basic-sdk/constants';
6
+ import { createDefaultEditor } from '../basic-sdk/extension';
7
+ import withNodeId from '../basic-sdk/node-id';
8
+ import { withSocketIO } from '../basic-sdk/socket';
9
+ import { ColumnPlugin } from '../basic-sdk/extension/plugins';
10
+ import ErrorBoundary from './error-boundary';
11
+ import useForceUpdate from '../basic-sdk/hooks/use-force-update';
12
+ import '../assets/css/simple-editor.css';
13
+ import '../assets/css/plugin-editor.css';
14
+ const DocumentPluginViewer = _ref => {
15
+ let {
16
+ scrollRef,
17
+ document,
18
+ showOutline,
19
+ columns,
20
+ getColumnCellValue
21
+ } = _ref;
22
+ context.initApi();
23
+ const forceUpdate = useForceUpdate();
24
+ const validEditor = useMemo(() => {
25
+ const withColumnPlugin = ColumnPlugin.editorPlugin;
26
+ const defaultEditor = withColumnPlugin(createDefaultEditor());
27
+ const editorConfig = context.getEditorConfig();
28
+ const newEditor = withNodeId(withSocketIO(defaultEditor, {
29
+ document,
30
+ config: editorConfig
31
+ }));
32
+ const {
33
+ cursors
34
+ } = document;
35
+ newEditor.columns = columns || [];
36
+ newEditor.getColumnCellValue = getColumnCellValue ? getColumnCellValue : null;
37
+ newEditor.cursors = cursors || {};
38
+ newEditor.width = PAGE_EDIT_AREA_WIDTH; // default width
39
+ return newEditor;
40
+ // eslint-disable-next-line react-hooks/exhaustive-deps
41
+ }, []);
42
+ useEffect(() => {
43
+ validEditor.getColumnCellValue = getColumnCellValue ? getColumnCellValue : null;
44
+ forceUpdate();
45
+ }, [forceUpdate, getColumnCellValue, validEditor.getColumnCellValue]);
46
+ return /*#__PURE__*/React.createElement(ErrorBoundary, null, /*#__PURE__*/React.createElement(SDocViewer, {
47
+ editor: validEditor,
48
+ scrollRef: scrollRef,
49
+ document: document,
50
+ showComment: false,
51
+ showToolbar: true,
52
+ showOutline: showOutline
53
+ }));
54
+ };
55
+ export default withTranslation('sdoc-editor')(DocumentPluginViewer);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seafile/sdoc-editor",
3
- "version": "0.5.65",
3
+ "version": "0.5.67beta",
4
4
  "private": false,
5
5
  "description": "This is a sdoc editor",
6
6
  "main": "dist/index.js",
package/public/index.html CHANGED
@@ -1,21 +1,20 @@
1
1
  <!DOCTYPE html>
2
2
  <html lang="en">
3
- <head>
4
- <meta charset="utf-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
6
- <meta name="theme-color" content="#000000">
7
-
8
- <!--
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
6
+ <meta name="theme-color" content="#000000">
7
+ <!--
9
8
  manifest.json provides metadata used when your web app is added to the
10
9
  homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
11
10
  -->
12
- <link rel="manifest" href="%PUBLIC_URL%/manifest.json">
13
- <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
14
-
15
- <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
16
- <link rel="stylesheet" type="text/css" href="%PUBLIC_URL%/media/sdoc-editor-font.css" />
17
- <link rel="stylesheet" type="text/css" href="%PUBLIC_URL%/media/seafile-ui.css" />
18
- <!--
11
+ <link rel="manifest" href="%PUBLIC_URL%/manifest.json">
12
+ <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
13
+ <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
14
+ <link rel="stylesheet" type="text/css" href="%PUBLIC_URL%/media/sdoc-editor-font.css">
15
+ <link rel="stylesheet" type="text/css" href="%PUBLIC_URL%/media/dtable-font.css">
16
+ <link rel="stylesheet" type="text/css" href="%PUBLIC_URL%/media/seafile-ui.css">
17
+ <!--
19
18
  Notice the use of %PUBLIC_URL% in the tags above.
20
19
  It will be replaced with the URL of the `public` folder during the build.
21
20
  Only files inside the `public` folder can be referenced from the HTML.
@@ -24,14 +23,14 @@
24
23
  work correctly both with client-side routing and a non-root public URL.
25
24
  Learn how to configure a non-root public URL by running `npm run build`.
26
25
  -->
27
- <title>React App</title>
28
- </head>
29
- <body>
30
- <noscript>
31
- You need to enable JavaScript to run this app.
32
- </noscript>
33
- <div id="root"></div>
34
- <!--
26
+ <title>React App</title>
27
+ </head>
28
+ <body>
29
+ <noscript>
30
+ You need to enable JavaScript to run this app.
31
+ </noscript>
32
+ <div id="root"></div>
33
+ <!--
35
34
  This HTML file is a template.
36
35
  If you open it directly in the browser, you will see an empty page.
37
36
 
@@ -41,5 +40,5 @@
41
40
  To begin the development, run `npm start` or `yarn start`.
42
41
  To create a production bundle, use `npm run build` or `yarn build`.
43
42
  -->
44
- </body>
43
+ </body>
45
44
  </html>