@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.
- package/dist/basic-sdk/extension/constants/element-type.js +3 -0
- package/dist/basic-sdk/extension/constants/index.js +2 -2
- package/dist/basic-sdk/extension/plugins/group/index.js +7 -0
- package/dist/basic-sdk/extension/plugins/group/render-elem.js +17 -0
- package/dist/basic-sdk/extension/plugins/index.js +3 -2
- package/dist/basic-sdk/extension/render/custom-element.js +6 -1
- package/dist/basic-sdk/utils/rebase.js +93 -14
- package/dist/components/doc-operations/revision-operations/index.js +1 -0
- package/package.json +1 -1
|
@@ -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,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
|
-
|
|
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
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
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
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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,
|