@seafile/sdoc-editor 0.5.66 → 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.
@@ -34,5 +34,8 @@ export const COLUMN = 'column';
34
34
  export const FONT_SIZE = 'font-size';
35
35
  export const FONT_SIZE_INCREASE = 'font-size-increase';
36
36
  export const FONT_SIZE_REDUCE = 'font-size-reduce';
37
+
38
+ // block
39
+ export const GROUP = 'group';
37
40
  export const TOP_LEVEL_TYPES = [BLOCKQUOTE, HEADER1, HEADER2, HEADER3, HEADER4, HEADER5, HEADER6, ORDERED_LIST, UNORDERED_LIST, CHECK_LIST_ITEM, PARAGRAPH, CODE_BLOCK, TABLE];
38
41
  export const INLINE_LEVEL_TYPES = [IMAGE, LINK, MENTION, MENTION_TEMP];
@@ -1,7 +1,7 @@
1
1
  // extension plugin
2
2
  import * as ELEMENT_TYPE from './element-type';
3
3
  // eslint-disable-next-line no-duplicate-imports
4
- import { BLOCKQUOTE, TITLE, SUBTITLE, HEADER, HEADER1, HEADER2, HEADER3, HEADER4, HEADER5, HEADER6, PARAGRAPH, ORDERED_LIST, UNORDERED_LIST, LIST_ITEM, CHECK_LIST_ITEM, CODE_BLOCK, CODE_LINE, TABLE, TABLE_CELL, TABLE_ROW, LINK, SDOC_LINK, FILE_LINK, IMAGE, IMAGE_BLOCK, TOP_LEVEL_TYPES, INLINE_LEVEL_TYPES, CALL_OUT, MENTION, MENTION_TEMP, FILE_LINK_INSET_INPUT_TEMP, QUICK_INSERT } from './element-type';
4
+ import { BLOCKQUOTE, TITLE, SUBTITLE, HEADER, HEADER1, HEADER2, HEADER3, HEADER4, HEADER5, HEADER6, PARAGRAPH, ORDERED_LIST, UNORDERED_LIST, LIST_ITEM, CHECK_LIST_ITEM, CODE_BLOCK, CODE_LINE, TABLE, TABLE_CELL, TABLE_ROW, LINK, SDOC_LINK, FILE_LINK, IMAGE, IMAGE_BLOCK, TOP_LEVEL_TYPES, INLINE_LEVEL_TYPES, CALL_OUT, MENTION, MENTION_TEMP, FILE_LINK_INSET_INPUT_TEMP, QUICK_INSERT, GROUP } from './element-type';
5
5
  export { DEFAULT_COLORS, STANDARD_COLORS, DEFAULT_RECENT_USED_LIST, DEFAULT_FONT_COLOR, RECENT_USED_HIGHLIGHT_COLORS_KEY, RECENT_USED_FONT_COLORS_KEY, RECENT_USED_TABLE_CELL_BACKGROUND_COLORS_KEY, DEFAULT_LAST_USED_FONT_COLOR, DEFAULT_LAST_USED_HIGHLIGHT_COLOR, DEFAULT_LAST_USED_TABLE_CELL_BACKGROUND_COLOR } from './color';
6
6
  export { FONT_SIZE, DEFAULT_FONT, FONT, GOOGLE_FONT_CLASS, RECENT_USED_FONTS_KEY, SDOC_FONT_SIZE } from './font';
7
7
  export { DIFF_TYPE, ADDED_STYLE, DELETED_STYLE } from './diff-view';
@@ -57,4 +57,4 @@ export const MOUSE_ENTER_EVENT_DISABLED_MAP = {
57
57
  [CALL_OUT]: [CALL_OUT]
58
58
  };
59
59
  export const ROOT_ELEMENT_TYPES = [PARAGRAPH, TITLE, SUBTITLE, CHECK_LIST_ITEM, ORDERED_LIST, UNORDERED_LIST, BLOCKQUOTE, HEADER1, HEADER2, HEADER3, HEADER4, HEADER5, HEADER6, CALL_OUT, TABLE, CODE_BLOCK, IMAGE_BLOCK];
60
- export { ELEMENT_TYPE, BLOCKQUOTE, TITLE, SUBTITLE, HEADER, HEADER1, HEADER2, HEADER3, HEADER4, HEADER5, HEADER6, PARAGRAPH, ORDERED_LIST, UNORDERED_LIST, LIST_ITEM, CHECK_LIST_ITEM, CODE_BLOCK, CODE_LINE, TABLE, TABLE_CELL, TABLE_ROW, LINK, SDOC_LINK, FILE_LINK, IMAGE, IMAGE_BLOCK, TOP_LEVEL_TYPES, INLINE_LEVEL_TYPES, CALL_OUT, MENTION, MENTION_TEMP, FILE_LINK_INSET_INPUT_TEMP, QUICK_INSERT };
60
+ export { ELEMENT_TYPE, BLOCKQUOTE, TITLE, SUBTITLE, HEADER, HEADER1, HEADER2, HEADER3, HEADER4, HEADER5, HEADER6, PARAGRAPH, ORDERED_LIST, UNORDERED_LIST, LIST_ITEM, CHECK_LIST_ITEM, CODE_BLOCK, CODE_LINE, TABLE, TABLE_CELL, TABLE_ROW, LINK, SDOC_LINK, FILE_LINK, IMAGE, IMAGE_BLOCK, TOP_LEVEL_TYPES, INLINE_LEVEL_TYPES, CALL_OUT, MENTION, MENTION_TEMP, FILE_LINK_INSET_INPUT_TEMP, QUICK_INSERT, GROUP };
@@ -0,0 +1,7 @@
1
+ import { ELEMENT_TYPE } from '../../constants';
2
+ import { renderGroup } from './render-elem';
3
+ const GroupPlugin = {
4
+ type: ELEMENT_TYPE.GROUP,
5
+ renderElements: [renderGroup]
6
+ };
7
+ export default GroupPlugin;
@@ -0,0 +1,17 @@
1
+ import React from 'react';
2
+ const Group = _ref => {
3
+ let {
4
+ element,
5
+ attributes,
6
+ children,
7
+ className
8
+ } = _ref;
9
+ return /*#__PURE__*/React.createElement("div", Object.assign({
10
+ "data-id": element.id
11
+ }, attributes, {
12
+ className: className
13
+ }), children);
14
+ };
15
+ export const renderGroup = props => {
16
+ return /*#__PURE__*/React.createElement(Group, props);
17
+ };
@@ -19,8 +19,9 @@ import SearchReplacePlugin from './search-replace';
19
19
  import MentionPlugin from './mention';
20
20
  import QuickInsertPlugin from './quick-insert';
21
21
  import ColumnPlugin from './column';
22
- const Plugins = [MarkDownPlugin, HtmlPlugin, HeaderPlugin, LinkPlugin, BlockquotePlugin, ListPlugin, CheckListPlugin, CodeBlockPlugin, ImagePlugin, TablePlugin, TextPlugin, TextAlignPlugin, FontPlugin, SdocLinkPlugin, ParagraphPlugin, FileLinkPlugin, CalloutPlugin, SearchReplacePlugin];
22
+ import GroupPlugin from './group';
23
+ const Plugins = [MarkDownPlugin, HtmlPlugin, HeaderPlugin, LinkPlugin, BlockquotePlugin, ListPlugin, CheckListPlugin, CodeBlockPlugin, ImagePlugin, TablePlugin, TextPlugin, TextAlignPlugin, FontPlugin, SdocLinkPlugin, ParagraphPlugin, FileLinkPlugin, CalloutPlugin, SearchReplacePlugin, GroupPlugin];
23
24
  const WikiPlugins = [MarkDownPlugin, HtmlPlugin, HeaderPlugin, LinkPlugin, BlockquotePlugin, ListPlugin, CheckListPlugin, CodeBlockPlugin, ImagePlugin, TablePlugin, TextPlugin, TextAlignPlugin, FontPlugin, SdocLinkPlugin, ParagraphPlugin, FileLinkPlugin, CalloutPlugin, SearchReplacePlugin, QuickInsertPlugin];
24
25
  const CommentPlugins = [MarkDownPlugin, HtmlPlugin, ParagraphPlugin, TextPlugin, ListPlugin, ImagePlugin, LinkPlugin, MentionPlugin, BlockquotePlugin];
25
26
  export default Plugins;
26
- export { MarkDownPlugin, HeaderPlugin, LinkPlugin, BlockquotePlugin, ListPlugin, CheckListPlugin, CodeBlockPlugin, ImagePlugin, TablePlugin, TextPlugin, HtmlPlugin, TextAlignPlugin, FontPlugin, SdocLinkPlugin, ParagraphPlugin, FileLinkPlugin, CalloutPlugin, SearchReplacePlugin, MentionPlugin, QuickInsertPlugin, CommentPlugins, WikiPlugins, ColumnPlugin };
27
+ export { MarkDownPlugin, HeaderPlugin, LinkPlugin, BlockquotePlugin, ListPlugin, CheckListPlugin, CodeBlockPlugin, ImagePlugin, TablePlugin, TextPlugin, HtmlPlugin, TextAlignPlugin, FontPlugin, SdocLinkPlugin, ParagraphPlugin, FileLinkPlugin, CalloutPlugin, SearchReplacePlugin, MentionPlugin, QuickInsertPlugin, CommentPlugins, WikiPlugins, ColumnPlugin, GroupPlugin };
@@ -1,7 +1,7 @@
1
1
  import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
2
2
  import { useReadOnly, useSlateStatic } from '@seafile/slate-react';
3
3
  import { BLOCKQUOTE, LINK, CHECK_LIST_ITEM, HEADER1, HEADER2, HEADER3, HEADER4, HEADER5, HEADER6, LIST_ITEM, ORDERED_LIST, PARAGRAPH, UNORDERED_LIST, CODE_BLOCK, CODE_LINE, IMAGE, IMAGE_BLOCK, ELEMENT_TYPE, SDOC_LINK, FILE_LINK, TITLE, SUBTITLE, CALL_OUT, SUPPORTED_SIDE_OPERATION_TYPE, MENTION, MENTION_TEMP, FILE_LINK_INSET_INPUT_TEMP, QUICK_INSERT } from '../constants';
4
- import { BlockquotePlugin, LinkPlugin, CheckListPlugin, HeaderPlugin, ListPlugin, CodeBlockPlugin, ImagePlugin, TablePlugin, SdocLinkPlugin, ParagraphPlugin, FileLinkPlugin, CalloutPlugin, MentionPlugin, QuickInsertPlugin, ColumnPlugin } from '../plugins';
4
+ import { BlockquotePlugin, LinkPlugin, CheckListPlugin, HeaderPlugin, ListPlugin, CodeBlockPlugin, ImagePlugin, TablePlugin, SdocLinkPlugin, ParagraphPlugin, FileLinkPlugin, CalloutPlugin, MentionPlugin, QuickInsertPlugin, ColumnPlugin, GroupPlugin } from '../plugins';
5
5
  import { onDragOver, onDragLeave, onDrop } from '../toolbar/side-toolbar/event';
6
6
  import { getParentNode } from '../core';
7
7
  import { setDataRoot, setMouseEnter } from './helper';
@@ -165,6 +165,11 @@ const CustomRenderElement = props => {
165
165
  const [renderColumn] = ColumnPlugin.renderElements;
166
166
  return renderColumn(props, editor);
167
167
  }
168
+ case ELEMENT_TYPE.GROUP:
169
+ {
170
+ const [renderGroup] = GroupPlugin.renderElements;
171
+ return renderGroup(props);
172
+ }
168
173
  default:
169
174
  {
170
175
  const [renderParagraph] = ParagraphPlugin.renderElements;
@@ -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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seafile/sdoc-editor",
3
- "version": "0.5.66",
3
+ "version": "0.5.67beta",
4
4
  "private": false,
5
5
  "description": "This is a sdoc editor",
6
6
  "main": "dist/index.js",