@seafile/sdoc-editor 1.0.212-alph-0.1.9 → 1.0.212-alph-2.1.0
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/api/seafile-api.js +4 -0
- package/dist/basic-sdk/assets/css/sdoc-editor-plugins.css +55 -0
- package/dist/basic-sdk/extension/commons/insert-element-dialog/index.js +2 -0
- package/dist/basic-sdk/extension/constants/element-type.js +4 -1
- package/dist/basic-sdk/extension/constants/index.js +6 -0
- package/dist/basic-sdk/extension/core/transforms/index.js +12 -1
- package/dist/basic-sdk/extension/core/transforms/rebase.js +75 -0
- package/dist/basic-sdk/extension/core/transforms/replace-node.js +2 -16
- package/dist/basic-sdk/extension/core/transforms/update-parent-node.js +8 -5
- package/dist/basic-sdk/extension/plugins/group/index.js +13 -0
- package/dist/basic-sdk/extension/plugins/group/render-elem.js +25 -0
- package/dist/basic-sdk/extension/plugins/image/constants/index.js +3 -2
- package/dist/basic-sdk/extension/plugins/image/helpers.js +21 -2
- package/dist/basic-sdk/extension/plugins/image/render-elem.js +86 -16
- package/dist/basic-sdk/extension/plugins/index.js +8 -1
- package/dist/basic-sdk/extension/plugins/list/plugin/normalize-list.js +3 -2
- package/dist/basic-sdk/extension/plugins/list/transforms/normalize-list-item.js +1 -1
- package/dist/basic-sdk/extension/render/custom-element.js +5 -0
- package/dist/basic-sdk/extension/render/element-decorate/rebase-decorate/index.css +2 -1
- package/dist/basic-sdk/extension/render/element-decorate/rebase-decorate/rebase-delete-modify-decorate.js +1 -1
- package/dist/basic-sdk/extension/render/element-decorate/rebase-decorate/rebase-modify-delete-decorate.js +1 -1
- package/dist/basic-sdk/extension/render/element-decorate/rebase-decorate/rebase-modify-modify-decorate.js +63 -31
- package/dist/basic-sdk/utils/diff.js +2 -0
- package/dist/basic-sdk/utils/rebase.js +63 -16
- package/dist/components/doc-operations/revision-operations/changes-count/index.js +0 -5
- package/dist/components/doc-operations/revision-operations/revisions/index.css +1 -1
- package/dist/pages/simple-editor.js +0 -1
- package/package.json +1 -1
- package/public/locales/cs/sdoc-editor.json +3 -1
- package/public/locales/de/sdoc-editor.json +3 -1
- package/public/locales/en/sdoc-editor.json +3 -1
- package/public/locales/es/sdoc-editor.json +3 -1
- package/public/locales/es_AR/sdoc-editor.json +3 -1
- package/public/locales/es_MX/sdoc-editor.json +3 -1
- package/public/locales/fr/sdoc-editor.json +3 -1
- package/public/locales/it/sdoc-editor.json +3 -1
- package/public/locales/ru/sdoc-editor.json +3 -1
- package/public/locales/zh_CN/sdoc-editor.json +3 -1
package/dist/api/seafile-api.js
CHANGED
|
@@ -40,13 +40,17 @@ class SeafileAPI {
|
|
|
40
40
|
uploadSdocImage(docUuid, imageFiles) {
|
|
41
41
|
const url = '/api/v2.1/seadoc/upload-image/' + docUuid + '/';
|
|
42
42
|
const form = new FormData();
|
|
43
|
+
console.log(form, imageFiles);
|
|
43
44
|
for (const fileItem of imageFiles) {
|
|
45
|
+
console.log(imageFiles, fileItem);
|
|
44
46
|
if (fileItem.type.startsWith('image/')) {
|
|
45
47
|
const fileName = this.getImageFileNameWithUuid(fileItem);
|
|
46
48
|
const file = new File([fileItem], fileName, {
|
|
47
49
|
type: fileItem.type
|
|
48
50
|
});
|
|
51
|
+
console.log(1, file);
|
|
49
52
|
form.append('file', file);
|
|
53
|
+
console.log(form);
|
|
50
54
|
}
|
|
51
55
|
}
|
|
52
56
|
return this.req.post(url, form);
|
|
@@ -62,6 +62,61 @@
|
|
|
62
62
|
caret-color: transparent;
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
+
.sdoc-editor__article .sdoc-image-wrapper .sdoc-image-placeholder-wrapper {
|
|
66
|
+
width: 100%;
|
|
67
|
+
aspect-ratio: 1;
|
|
68
|
+
background-color: #f0f0f0;
|
|
69
|
+
border: 1px solid #ccc;
|
|
70
|
+
padding: 0 3%;
|
|
71
|
+
max-width: 100%;
|
|
72
|
+
user-select: all;
|
|
73
|
+
pointer-events: all;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.sdoc-editor__article .sdoc-image-wrapper .sdoc-image-tip-content,
|
|
77
|
+
.sdoc-editor__article .sdoc-image-wrapper .sdoc-image-title {
|
|
78
|
+
user-select: none;
|
|
79
|
+
pointer-events: none;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.sdoc-editor__article .sdoc-image-title .sdoc-exclamation-circle {
|
|
83
|
+
font-size: 18px;
|
|
84
|
+
align-items: center;
|
|
85
|
+
justify-content: center;
|
|
86
|
+
color: red;
|
|
87
|
+
display: flex;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.sdoc-editor__article .sdoc-image-title .sdoc-image-tip-title {
|
|
91
|
+
color: red;
|
|
92
|
+
font-size: 18px;
|
|
93
|
+
user-select: none;
|
|
94
|
+
pointer-events: none;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.sdoc-editor__article .sdoc-image-process-container {
|
|
98
|
+
width: 40px;
|
|
99
|
+
height: 40px;
|
|
100
|
+
display: flex;
|
|
101
|
+
align-items: center;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.sdoc-editor__article .sdoc-image-process-container .loading-spinner {
|
|
105
|
+
border: 5px solid #d8d8d8;
|
|
106
|
+
border-top: 5px solid #939393;
|
|
107
|
+
border-radius: 50%;
|
|
108
|
+
width: 30px;
|
|
109
|
+
height: 30px;
|
|
110
|
+
animation: spin 1s linear infinite;
|
|
111
|
+
user-select: none;
|
|
112
|
+
pointer-events: none;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
@keyframes spin {
|
|
116
|
+
0% { transform: rotate(0deg); }
|
|
117
|
+
100% { transform: rotate(360deg); }
|
|
118
|
+
}
|
|
119
|
+
|
|
65
120
|
.sdoc-editor__article .sdoc-image-inner {
|
|
66
121
|
position: relative;
|
|
67
122
|
display: inline-block;
|
|
@@ -44,7 +44,9 @@ const InsertElementDialog = _ref => {
|
|
|
44
44
|
const uploadLocalVideoInputRef = (0, _react.useRef)();
|
|
45
45
|
const onFileChanged = (0, _react.useCallback)(event => {
|
|
46
46
|
const files = event.target.files;
|
|
47
|
+
console.log(1, files);
|
|
47
48
|
_context.default.uploadLocalImage(files).then(fileUrl => {
|
|
49
|
+
console.log(2, fileUrl);
|
|
48
50
|
(0, _helpers.insertImage)(validEditor, fileUrl, validEditor.selection, insertPosition);
|
|
49
51
|
if (uploadLocalImageInputRef.current) {
|
|
50
52
|
uploadLocalImageInputRef.current.value = '';
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.WIKI_LINK = exports.VIDEO_LINK = exports.VIDEO = exports.UNORDERED_LIST = exports.TWO_COLUMN = exports.TOP_LEVEL_TYPES = exports.TITLE = exports.THREE_COLUMN = exports.TABLE_ROW = exports.TABLE_CELL = exports.TABLE = exports.SUBTITLE = exports.SEATABLE_TABLE = exports.SEATABLE_COLUMN = exports.SDOC_LINK = exports.QUICK_INSERT = exports.PARAGRAPH = exports.ORDERED_LIST = exports.MULTI_COLUMN = exports.MENTION_TEMP = exports.MENTION = exports.LIST_ITEM = exports.LINK = exports.INLINE_LEVEL_TYPES = exports.IMAGE_BLOCK = exports.IMAGE = exports.HEADER6 = exports.HEADER5 = exports.HEADER4 = exports.HEADER3 = exports.HEADER2 = exports.HEADER1 = exports.HEADER = exports.FOUR_COLUMN = exports.FONT_SIZE_REDUCE = exports.FONT_SIZE_INCREASE = exports.FONT_SIZE = exports.FIVE_COLUMN = exports.FILE_LINK_INSET_INPUT_TEMP = exports.FILE_LINK = exports.COLUMN = exports.CODE_LINE = exports.CODE_BLOCK = exports.CHECK_LIST_ITEM = exports.CALL_OUT = exports.BLOCKQUOTE = exports.ASK_AI = void 0;
|
|
6
|
+
exports.WIKI_LINK = exports.VIDEO_LINK = exports.VIDEO = exports.UNORDERED_LIST = exports.TWO_COLUMN = exports.TOP_LEVEL_TYPES = exports.TITLE = exports.THREE_COLUMN = exports.TABLE_ROW = exports.TABLE_CELL = exports.TABLE = exports.SUBTITLE = exports.SEATABLE_TABLE = exports.SEATABLE_COLUMN = exports.SDOC_LINK = exports.QUICK_INSERT = exports.PARAGRAPH = exports.ORDERED_LIST = exports.MULTI_COLUMN = exports.MENTION_TEMP = exports.MENTION = exports.LIST_ITEM = exports.LINK = exports.INLINE_LEVEL_TYPES = exports.IMAGE_BLOCK = exports.IMAGE = exports.HEADER6 = exports.HEADER5 = exports.HEADER4 = exports.HEADER3 = exports.HEADER2 = exports.HEADER1 = exports.HEADER = exports.GROUP = exports.FOUR_COLUMN = exports.FONT_SIZE_REDUCE = exports.FONT_SIZE_INCREASE = exports.FONT_SIZE = exports.FIVE_COLUMN = exports.FILE_LINK_INSET_INPUT_TEMP = exports.FILE_LINK = exports.COLUMN = exports.CODE_LINE = exports.CODE_BLOCK = exports.CHECK_LIST_ITEM = exports.CALL_OUT = exports.BLOCKQUOTE = exports.ASK_AI = void 0;
|
|
7
7
|
const BLOCKQUOTE = exports.BLOCKQUOTE = 'blockquote';
|
|
8
8
|
const TITLE = exports.TITLE = 'title';
|
|
9
9
|
const SUBTITLE = exports.SUBTITLE = 'subtitle';
|
|
@@ -51,5 +51,8 @@ const ASK_AI = exports.ASK_AI = 'ask_ai';
|
|
|
51
51
|
const FONT_SIZE = exports.FONT_SIZE = 'font-size';
|
|
52
52
|
const FONT_SIZE_INCREASE = exports.FONT_SIZE_INCREASE = 'font-size-increase';
|
|
53
53
|
const FONT_SIZE_REDUCE = exports.FONT_SIZE_REDUCE = 'font-size-reduce';
|
|
54
|
+
|
|
55
|
+
// group
|
|
56
|
+
const GROUP = exports.GROUP = 'group';
|
|
54
57
|
const TOP_LEVEL_TYPES = exports.TOP_LEVEL_TYPES = [BLOCKQUOTE, HEADER1, HEADER2, HEADER3, HEADER4, HEADER5, HEADER6, ORDERED_LIST, UNORDERED_LIST, CHECK_LIST_ITEM, PARAGRAPH, CODE_BLOCK, TABLE];
|
|
55
58
|
const INLINE_LEVEL_TYPES = exports.INLINE_LEVEL_TYPES = [IMAGE, LINK, MENTION, MENTION_TEMP];
|
|
@@ -158,6 +158,12 @@ Object.defineProperty(exports, "GOOGLE_FONT_CLASS", {
|
|
|
158
158
|
return _font.GOOGLE_FONT_CLASS;
|
|
159
159
|
}
|
|
160
160
|
});
|
|
161
|
+
Object.defineProperty(exports, "GROUP", {
|
|
162
|
+
enumerable: true,
|
|
163
|
+
get: function () {
|
|
164
|
+
return _elementType.GROUP;
|
|
165
|
+
}
|
|
166
|
+
});
|
|
161
167
|
Object.defineProperty(exports, "HEADER", {
|
|
162
168
|
enumerable: true,
|
|
163
169
|
get: function () {
|
|
@@ -47,7 +47,7 @@ Object.keys(_replaceNode).forEach(function (key) {
|
|
|
47
47
|
}
|
|
48
48
|
});
|
|
49
49
|
});
|
|
50
|
-
var _updateParentNode = require("./update-parent-node
|
|
50
|
+
var _updateParentNode = require("./update-parent-node");
|
|
51
51
|
Object.keys(_updateParentNode).forEach(function (key) {
|
|
52
52
|
if (key === "default" || key === "__esModule") return;
|
|
53
53
|
if (key in exports && exports[key] === _updateParentNode[key]) return;
|
|
@@ -57,4 +57,15 @@ Object.keys(_updateParentNode).forEach(function (key) {
|
|
|
57
57
|
return _updateParentNode[key];
|
|
58
58
|
}
|
|
59
59
|
});
|
|
60
|
+
});
|
|
61
|
+
var _rebase = require("./rebase");
|
|
62
|
+
Object.keys(_rebase).forEach(function (key) {
|
|
63
|
+
if (key === "default" || key === "__esModule") return;
|
|
64
|
+
if (key in exports && exports[key] === _rebase[key]) return;
|
|
65
|
+
Object.defineProperty(exports, key, {
|
|
66
|
+
enumerable: true,
|
|
67
|
+
get: function () {
|
|
68
|
+
return _rebase[key];
|
|
69
|
+
}
|
|
70
|
+
});
|
|
60
71
|
});
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.replaceRebaseNodeChildren = exports.replaceRebaseNode = exports.rebaseNode = exports.deleteRebaseNodeMark = void 0;
|
|
7
|
+
var _slate = require("@seafile/slate");
|
|
8
|
+
var _removeNodeChildren = require("./remove-node-children");
|
|
9
|
+
var _queries = require("../queries");
|
|
10
|
+
var _constants = require("../../constants");
|
|
11
|
+
const replaceRebaseNodeChildren = (editor, _ref) => {
|
|
12
|
+
let {
|
|
13
|
+
at,
|
|
14
|
+
nodes,
|
|
15
|
+
insertOptions,
|
|
16
|
+
removeOptions
|
|
17
|
+
} = _ref;
|
|
18
|
+
(0, _removeNodeChildren.removeNodeChildren)(editor, at, removeOptions);
|
|
19
|
+
_slate.Transforms.insertNodes(editor, nodes, {
|
|
20
|
+
...insertOptions,
|
|
21
|
+
at: at.concat([0])
|
|
22
|
+
});
|
|
23
|
+
};
|
|
24
|
+
exports.replaceRebaseNodeChildren = replaceRebaseNodeChildren;
|
|
25
|
+
const replaceRebaseNode = function (editor) {
|
|
26
|
+
let {
|
|
27
|
+
at,
|
|
28
|
+
nodes,
|
|
29
|
+
insertOptions,
|
|
30
|
+
removeOptions
|
|
31
|
+
} = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
32
|
+
const parentPath = at.slice(0, -1);
|
|
33
|
+
const parentNode = at.length > 1 ? (0, _queries.getNode)(editor, parentPath) : {};
|
|
34
|
+
if ([_constants.ELEMENT_TYPE.ORDERED_LIST, _constants.ELEMENT_TYPE.UNORDERED_LIST].includes(parentNode.type)) {
|
|
35
|
+
const newChildren = parentNode.children.slice(0);
|
|
36
|
+
newChildren.splice(at[at.length - 1], 1, ...nodes);
|
|
37
|
+
replaceRebaseNodeChildren(editor, {
|
|
38
|
+
at: parentPath,
|
|
39
|
+
nodes: newChildren
|
|
40
|
+
});
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
_slate.Transforms.removeNodes(editor, {
|
|
44
|
+
at,
|
|
45
|
+
...removeOptions
|
|
46
|
+
});
|
|
47
|
+
_slate.Transforms.insertNodes(editor, nodes, {
|
|
48
|
+
...insertOptions,
|
|
49
|
+
at
|
|
50
|
+
});
|
|
51
|
+
};
|
|
52
|
+
exports.replaceRebaseNode = replaceRebaseNode;
|
|
53
|
+
const deleteRebaseNodeMark = function (editor, path, element) {
|
|
54
|
+
let marks = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : [];
|
|
55
|
+
const newElement = {
|
|
56
|
+
...element
|
|
57
|
+
};
|
|
58
|
+
marks.forEach(markItem => {
|
|
59
|
+
newElement[markItem] && delete newElement[markItem];
|
|
60
|
+
});
|
|
61
|
+
_slate.Transforms.removeNodes(editor, {
|
|
62
|
+
at: path
|
|
63
|
+
});
|
|
64
|
+
_slate.Transforms.insertNodes(editor, newElement, {
|
|
65
|
+
at: path
|
|
66
|
+
});
|
|
67
|
+
};
|
|
68
|
+
exports.deleteRebaseNodeMark = deleteRebaseNodeMark;
|
|
69
|
+
const rebaseNode = (editor, callback) => {
|
|
70
|
+
if (!callback) return;
|
|
71
|
+
_slate.Editor.withoutNormalizing(editor, () => {
|
|
72
|
+
callback && callback();
|
|
73
|
+
});
|
|
74
|
+
};
|
|
75
|
+
exports.rebaseNode = rebaseNode;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.replaceNodeChildren = exports.replaceNode =
|
|
6
|
+
exports.replaceNodeChildren = exports.replaceNode = void 0;
|
|
7
7
|
var _slate = require("@seafile/slate");
|
|
8
8
|
var _removeNodeChildren = require("./remove-node-children");
|
|
9
9
|
const replaceNodeChildren = (editor, _ref) => {
|
|
@@ -40,18 +40,4 @@ const replaceNode = function (editor) {
|
|
|
40
40
|
});
|
|
41
41
|
});
|
|
42
42
|
};
|
|
43
|
-
exports.replaceNode = replaceNode;
|
|
44
|
-
const deleteNodeMark = function (editor, path, element) {
|
|
45
|
-
let marks = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : [];
|
|
46
|
-
const newElement = {
|
|
47
|
-
...element
|
|
48
|
-
};
|
|
49
|
-
marks.forEach(markItem => {
|
|
50
|
-
newElement[markItem] && delete newElement[markItem];
|
|
51
|
-
});
|
|
52
|
-
replaceNode(editor, {
|
|
53
|
-
at: path,
|
|
54
|
-
nodes: newElement
|
|
55
|
-
});
|
|
56
|
-
};
|
|
57
|
-
exports.deleteNodeMark = deleteNodeMark;
|
|
43
|
+
exports.replaceNode = replaceNode;
|
|
@@ -4,13 +4,14 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.updateRebaseParentNodeByPath = void 0;
|
|
7
|
+
var _slate = require("@seafile/slate");
|
|
7
8
|
var _constants = require("../../../constants");
|
|
9
|
+
var _constants2 = require("../../constants");
|
|
8
10
|
var _queries = require("../queries");
|
|
9
|
-
var _replaceNode = require("./replace-node");
|
|
10
11
|
const updateRebaseParentNodeByPath = (editor, path) => {
|
|
11
12
|
const parentPath = path.slice(0, -1);
|
|
12
13
|
const parentNode = (0, _queries.getNode)(editor, parentPath);
|
|
13
|
-
if (
|
|
14
|
+
if (![_constants2.ELEMENT_TYPE.ORDERED_LIST, _constants2.ELEMENT_TYPE.UNORDERED_LIST].includes(parentNode.type)) return;
|
|
14
15
|
const newParentElement = {
|
|
15
16
|
...parentNode
|
|
16
17
|
};
|
|
@@ -23,9 +24,11 @@ const updateRebaseParentNodeByPath = (editor, path) => {
|
|
|
23
24
|
item[_constants.REBASE_MARK_KEY.ORIGIN] && delete item[_constants.REBASE_MARK_KEY.ORIGIN];
|
|
24
25
|
return item;
|
|
25
26
|
});
|
|
26
|
-
|
|
27
|
-
at: parentPath
|
|
28
|
-
|
|
27
|
+
_slate.Transforms.removeNodes(editor, {
|
|
28
|
+
at: parentPath
|
|
29
|
+
});
|
|
30
|
+
_slate.Transforms.insertNodes(editor, newParentElement, {
|
|
31
|
+
at: parentPath
|
|
29
32
|
});
|
|
30
33
|
};
|
|
31
34
|
exports.updateRebaseParentNodeByPath = updateRebaseParentNodeByPath;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _constants = require("../../constants");
|
|
8
|
+
var _renderElem = require("./render-elem");
|
|
9
|
+
const GroupPlugin = {
|
|
10
|
+
type: _constants.ELEMENT_TYPE.GROUP,
|
|
11
|
+
renderElements: [_renderElem.renderGroup]
|
|
12
|
+
};
|
|
13
|
+
var _default = exports.default = GroupPlugin;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.renderGroup = void 0;
|
|
8
|
+
var _react = _interopRequireDefault(require("react"));
|
|
9
|
+
const Group = _ref => {
|
|
10
|
+
let {
|
|
11
|
+
element,
|
|
12
|
+
attributes,
|
|
13
|
+
children,
|
|
14
|
+
className
|
|
15
|
+
} = _ref;
|
|
16
|
+
return /*#__PURE__*/_react.default.createElement("div", Object.assign({
|
|
17
|
+
"data-id": element.id
|
|
18
|
+
}, attributes, {
|
|
19
|
+
className: className
|
|
20
|
+
}), children);
|
|
21
|
+
};
|
|
22
|
+
const renderGroup = props => {
|
|
23
|
+
return /*#__PURE__*/_react.default.createElement(Group, props);
|
|
24
|
+
};
|
|
25
|
+
exports.renderGroup = renderGroup;
|
|
@@ -4,7 +4,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
|
|
|
4
4
|
Object.defineProperty(exports, "__esModule", {
|
|
5
5
|
value: true
|
|
6
6
|
});
|
|
7
|
-
exports.IMAGE_DISPLAY_TYPE = exports.IMAGE_BORDER_TYPE = void 0;
|
|
7
|
+
exports.SVG_WIDTH = exports.IMAGE_DISPLAY_TYPE = exports.IMAGE_BORDER_TYPE = void 0;
|
|
8
8
|
var _blackBorder = _interopRequireDefault(require("../../../../assets/images/black-border.png"));
|
|
9
9
|
var _greyBorder = _interopRequireDefault(require("../../../../assets/images/grey-border.png"));
|
|
10
10
|
var _noBorder = _interopRequireDefault(require("../../../../assets/images/no-border.png"));
|
|
@@ -27,4 +27,5 @@ const IMAGE_BORDER_TYPE = exports.IMAGE_BORDER_TYPE = [{
|
|
|
27
27
|
type: 'black',
|
|
28
28
|
imgUrl: _blackBorder.default,
|
|
29
29
|
value: '2px solid #41464A'
|
|
30
|
-
}];
|
|
30
|
+
}];
|
|
31
|
+
const SVG_WIDTH = exports.SVG_WIDTH = 360;
|
|
@@ -4,7 +4,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
|
|
|
4
4
|
Object.defineProperty(exports, "__esModule", {
|
|
5
5
|
value: true
|
|
6
6
|
});
|
|
7
|
-
exports.updateImage = exports.selectImageWhenSelectPartial = exports.resetCursor = exports.queryCopyMoveProgressView = exports.isInsertImageMenuDisabled = exports.insertImageFiles = exports.insertImage = exports.hasSdocImages = exports.handleBase64Image = exports.getSingleImageFromFragment = exports.getImageURL = exports.getImageData = exports.generateImageNode = void 0;
|
|
7
|
+
exports.updateImage = exports.selectImageWhenSelectPartial = exports.resetCursor = exports.queryCopyMoveProgressView = exports.isInsertImageMenuDisabled = exports.insertImageFiles = exports.insertImage = exports.hasSdocImages = exports.handleBase64Image = exports.getSingleImageFromFragment = exports.getImageURL = exports.getImageData = exports.generateImageNode = exports.downloadImage = void 0;
|
|
8
8
|
var _urlJoin = _interopRequireDefault(require("url-join"));
|
|
9
9
|
var _slate = require("@seafile/slate");
|
|
10
10
|
var _slateReact = require("@seafile/slate-react");
|
|
@@ -133,11 +133,25 @@ const updateImage = (editor, data) => {
|
|
|
133
133
|
});
|
|
134
134
|
};
|
|
135
135
|
exports.updateImage = updateImage;
|
|
136
|
+
const downloadImage = async url => {
|
|
137
|
+
const response = await fetch(url);
|
|
138
|
+
const blob = await response.blob();
|
|
139
|
+
const file = new File([blob], 'downloaded_image', {
|
|
140
|
+
type: blob.type
|
|
141
|
+
});
|
|
142
|
+
// console.log(file, context.uploadLocalImage(file));
|
|
143
|
+
console.log(10);
|
|
144
|
+
const fileUrl = await _context.default.uploadLocalImage([file]);
|
|
145
|
+
console.log(fileUrl);
|
|
146
|
+
return fileUrl;
|
|
147
|
+
};
|
|
148
|
+
exports.downloadImage = downloadImage;
|
|
136
149
|
const getImageURL = (data, editor) => {
|
|
137
150
|
const {
|
|
138
151
|
src: url,
|
|
139
152
|
column_key
|
|
140
153
|
} = data;
|
|
154
|
+
console.log('data', data);
|
|
141
155
|
if (column_key) {
|
|
142
156
|
const column = (0, _helpers.getColumnByKey)(editor.columns || [], column_key);
|
|
143
157
|
const {
|
|
@@ -153,7 +167,12 @@ const getImageURL = (data, editor) => {
|
|
|
153
167
|
return imgUrl;
|
|
154
168
|
}
|
|
155
169
|
}
|
|
156
|
-
if (url && url.startsWith('http'))
|
|
170
|
+
if (url && url.startsWith('http')) {
|
|
171
|
+
// return url;
|
|
172
|
+
console.log(6, url);
|
|
173
|
+
// debugger;
|
|
174
|
+
return Promise.resolve().then(() => downloadImage(url));
|
|
175
|
+
}
|
|
157
176
|
const serviceUrl = _context.default.getSetting('serviceUrl');
|
|
158
177
|
const assetsUrl = _context.default.getSetting('assetsUrl');
|
|
159
178
|
return (0, _urlJoin.default)(serviceUrl, assetsUrl, url);
|
|
@@ -20,9 +20,8 @@ var _useScrollContext = require("../../../hooks/use-scroll-context");
|
|
|
20
20
|
var _constants2 = require("./constants");
|
|
21
21
|
var _constants3 = require("../../constants");
|
|
22
22
|
var _constants4 = require("../../../../constants");
|
|
23
|
-
var _imagePlaceholder = _interopRequireDefault(require("../../../assets/images/image-placeholder.png"));
|
|
24
23
|
const Image = _ref => {
|
|
25
|
-
var _imageRef$current, _imageRef$current2;
|
|
24
|
+
var _imageRef$current, _imageRef$current2, _imageRef$current3;
|
|
26
25
|
let {
|
|
27
26
|
element,
|
|
28
27
|
editor,
|
|
@@ -57,6 +56,8 @@ const Image = _ref => {
|
|
|
57
56
|
const [isShowImageHoverMenu, setIsShowImageHoverMenu] = (0, _react.useState)(false);
|
|
58
57
|
const [menuPosition, setMenuPosition] = (0, _react.useState)({});
|
|
59
58
|
const [caption, setCaption] = (0, _react.useState)((data === null || data === void 0 ? void 0 : data.caption) || '');
|
|
59
|
+
const [isLoading, setIsLoading] = (0, _react.useState)(true);
|
|
60
|
+
const svgWidth = movingWidth || element.data.width || _constants2.SVG_WIDTH;
|
|
60
61
|
const registerEvent = (0, _react.useCallback)(eventList => {
|
|
61
62
|
eventList.forEach(element => {
|
|
62
63
|
document.addEventListener(element.eventName, element.event);
|
|
@@ -71,12 +72,17 @@ const Image = _ref => {
|
|
|
71
72
|
var _resizerRef$current;
|
|
72
73
|
event.preventDefault();
|
|
73
74
|
event.stopPropagation();
|
|
75
|
+
if (!imageRef.current) return;
|
|
74
76
|
const changeX = event.clientX - ((_resizerRef$current = resizerRef.current) === null || _resizerRef$current === void 0 ? void 0 : _resizerRef$current.getBoundingClientRect().left) - 5;
|
|
75
|
-
|
|
76
|
-
if (
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
77
|
+
let newWidth = isShowImagePlaceholder ? imageRef.current.getBoundingClientRect().width + changeX : imageRef.current.width + changeX;
|
|
78
|
+
if (newWidth < 20) return;
|
|
79
|
+
if (isShowImagePlaceholder) {
|
|
80
|
+
imageRef.current.width.baseVal.value = newWidth;
|
|
81
|
+
} else {
|
|
82
|
+
imageRef.current.width = newWidth;
|
|
83
|
+
}
|
|
84
|
+
setMovingWidth(newWidth);
|
|
85
|
+
}, [isShowImagePlaceholder]);
|
|
80
86
|
const onResizeEnd = (0, _react.useCallback)(event => {
|
|
81
87
|
event.preventDefault();
|
|
82
88
|
event.stopPropagation();
|
|
@@ -89,7 +95,7 @@ const Image = _ref => {
|
|
|
89
95
|
}]);
|
|
90
96
|
const newData = {
|
|
91
97
|
...element.data,
|
|
92
|
-
width: imageRef.current.width
|
|
98
|
+
width: parseFloat(imageRef.current.style.width)
|
|
93
99
|
};
|
|
94
100
|
(0, _helpers.updateImage)(editor, newData);
|
|
95
101
|
|
|
@@ -194,6 +200,7 @@ const Image = _ref => {
|
|
|
194
200
|
const reloadImage = (0, _react.useCallback)(() => {
|
|
195
201
|
if (imageRef.current) {
|
|
196
202
|
imageRef.current['src'] = (0, _helpers.getImageURL)(data, editor);
|
|
203
|
+
console.log((0, _helpers.getImageURL)(data, editor));
|
|
197
204
|
setIsShowImagePlaceholder(false);
|
|
198
205
|
}
|
|
199
206
|
}, [data, editor]);
|
|
@@ -202,6 +209,7 @@ const Image = _ref => {
|
|
|
202
209
|
if (data.src.startsWith('data:image/jpeg;base64')) {
|
|
203
210
|
return (0, _helpers.handleBase64Image)(editor, path, data);
|
|
204
211
|
}
|
|
212
|
+
setIsLoading(false);
|
|
205
213
|
setIsShowImagePlaceholder(true);
|
|
206
214
|
// External network images do not reload after failure to load
|
|
207
215
|
if (!data.src.startsWith('http')) {
|
|
@@ -224,7 +232,22 @@ const Image = _ref => {
|
|
|
224
232
|
});
|
|
225
233
|
}
|
|
226
234
|
}, [data, editor, element]);
|
|
227
|
-
|
|
235
|
+
(0, _react.useEffect)(() => {
|
|
236
|
+
if (imageRef.current) {
|
|
237
|
+
imageRef.current.onload = () => setIsLoading(false);
|
|
238
|
+
imageRef.current.onerror = onImageLoadError;
|
|
239
|
+
}
|
|
240
|
+
}, [element.data]);
|
|
241
|
+
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("div", {
|
|
242
|
+
className: "sdoc-image-process-container",
|
|
243
|
+
style: {
|
|
244
|
+
display: isLoading ? 'inline-block' : 'none'
|
|
245
|
+
}
|
|
246
|
+
}, /*#__PURE__*/_react.default.createElement("div", {
|
|
247
|
+
className: "loading-spinner"
|
|
248
|
+
}, /*#__PURE__*/_react.default.createElement("div", {
|
|
249
|
+
className: "spinner"
|
|
250
|
+
})), children), isShowImagePlaceholder && /*#__PURE__*/_react.default.createElement("span", Object.assign({
|
|
228
251
|
className: (0, _classnames.default)('sdoc-image-wrapper', className)
|
|
229
252
|
}, attributes, {
|
|
230
253
|
style: {
|
|
@@ -233,13 +256,60 @@ const Image = _ref => {
|
|
|
233
256
|
onMouseOver: e => (0, _helpers.selectImageWhenSelectPartial)(e, editor, element, isSelected),
|
|
234
257
|
contentEditable: "false",
|
|
235
258
|
suppressContentEditableWarning: true
|
|
236
|
-
}), /*#__PURE__*/_react.default.createElement("
|
|
259
|
+
}), /*#__PURE__*/_react.default.createElement("svg", {
|
|
260
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
261
|
+
viewBox: `0 0 ${svgWidth} ${svgWidth}`,
|
|
262
|
+
preserveAspectRatio: "xMinYMin meet",
|
|
263
|
+
className: (0, _classnames.default)('sdoc-image-placeholder-wrapper', {
|
|
264
|
+
'image-selected': isSelected
|
|
265
|
+
}),
|
|
237
266
|
ref: imageRef,
|
|
238
|
-
src: _imagePlaceholder.default,
|
|
239
267
|
style: getImageStyle(),
|
|
240
|
-
draggable: false
|
|
241
|
-
|
|
242
|
-
|
|
268
|
+
draggable: false
|
|
269
|
+
}, /*#__PURE__*/_react.default.createElement("rect", {
|
|
270
|
+
width: "100%",
|
|
271
|
+
height: "100%",
|
|
272
|
+
fill: "#f0f0f0"
|
|
273
|
+
}), /*#__PURE__*/_react.default.createElement("g", {
|
|
274
|
+
className: "sdoc-image-content-wrapper",
|
|
275
|
+
transform: `translate(${svgWidth / 2}, ${svgWidth / 2}) scale(${svgWidth / _constants2.SVG_WIDTH})`
|
|
276
|
+
}, /*#__PURE__*/_react.default.createElement("g", {
|
|
277
|
+
className: "sdoc-image-title",
|
|
278
|
+
transform: "translate(0, 0)"
|
|
279
|
+
}, /*#__PURE__*/_react.default.createElement("foreignObject", {
|
|
280
|
+
x: "-85",
|
|
281
|
+
y: "-16",
|
|
282
|
+
width: "20",
|
|
283
|
+
height: "28"
|
|
284
|
+
}, /*#__PURE__*/_react.default.createElement("div", {
|
|
285
|
+
className: "sdocfont sdoc-exclamation-circle"
|
|
286
|
+
})), /*#__PURE__*/_react.default.createElement("text", {
|
|
287
|
+
className: "sdoc-image-tip-title",
|
|
288
|
+
transform: "translate(-55, 4)",
|
|
289
|
+
fontSize: "20",
|
|
290
|
+
fill: "red",
|
|
291
|
+
fontFamily: "Arial, sans-serif"
|
|
292
|
+
}, t('Image_copy_error'))), /*#__PURE__*/_react.default.createElement("text", {
|
|
293
|
+
className: "sdoc-image-tip-content",
|
|
294
|
+
transform: "translate(0, 35)",
|
|
295
|
+
fontSize: "12",
|
|
296
|
+
textAnchor: "middle",
|
|
297
|
+
fill: "black",
|
|
298
|
+
fontFamily: "Arial, sans-serif"
|
|
299
|
+
}, t('Image_cannot_be_copied_Please_download_the_source_image')), /*#__PURE__*/_react.default.createElement("text", {
|
|
300
|
+
className: "sdoc-image-tip-content",
|
|
301
|
+
transform: "translate(0, 55)",
|
|
302
|
+
fontSize: "12",
|
|
303
|
+
textAnchor: "middle",
|
|
304
|
+
fill: "black",
|
|
305
|
+
fontFamily: "Arial, sans-serif"
|
|
306
|
+
}, t('And_select_insert_-_image_to_upload')))), isSelected && /*#__PURE__*/_react.default.createElement("span", {
|
|
307
|
+
className: "image-resizer",
|
|
308
|
+
ref: resizerRef,
|
|
309
|
+
onMouseDown: onResizeStart
|
|
310
|
+
}), isResizing && /*#__PURE__*/_react.default.createElement("span", {
|
|
311
|
+
className: "image-size"
|
|
312
|
+
}, /*#__PURE__*/_react.default.createElement("span", null, t('Width'), ':', parseInt(movingWidth || ((_imageRef$current = imageRef.current) === null || _imageRef$current === void 0 ? void 0 : _imageRef$current.clientWidth))), /*#__PURE__*/_react.default.createElement("span", null, "\xA0\xA0"), /*#__PURE__*/_react.default.createElement("span", null, t('Height'), ':', imageRef.current.clientHeight)), children), !isShowImagePlaceholder && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("span", Object.assign({
|
|
243
313
|
"data-id": element.id,
|
|
244
314
|
className: (0, _classnames.default)('sdoc-image-wrapper', className)
|
|
245
315
|
}, attributes, {
|
|
@@ -272,12 +342,12 @@ const Image = _ref => {
|
|
|
272
342
|
onMouseDown: onResizeStart
|
|
273
343
|
}), isResizing && /*#__PURE__*/_react.default.createElement("span", {
|
|
274
344
|
className: "image-size"
|
|
275
|
-
}, /*#__PURE__*/_react.default.createElement("span", null, t('Width'), ':', parseInt(movingWidth || ((_imageRef$
|
|
345
|
+
}, /*#__PURE__*/_react.default.createElement("span", null, t('Width'), ':', parseInt(movingWidth || ((_imageRef$current2 = imageRef.current) === null || _imageRef$current2 === void 0 ? void 0 : _imageRef$current2.clientWidth))), /*#__PURE__*/_react.default.createElement("span", null, "\xA0\xA0"), /*#__PURE__*/_react.default.createElement("span", null, t('Height'), ':', imageRef.current.clientHeight))), nodeEntry[0].type === _constants3.IMAGE_BLOCK && show_caption && /*#__PURE__*/_react.default.createElement("input", {
|
|
276
346
|
id: "sdoc-image-caption-input",
|
|
277
347
|
ref: imageCaptionInputRef,
|
|
278
348
|
className: "sdoc-image-caption-input-wrapper",
|
|
279
349
|
style: {
|
|
280
|
-
width: (data === null || data === void 0 ? void 0 : data.width) || ((_imageRef$
|
|
350
|
+
width: (data === null || data === void 0 ? void 0 : data.width) || ((_imageRef$current3 = imageRef.current) === null || _imageRef$current3 === void 0 ? void 0 : _imageRef$current3.clientWidth)
|
|
281
351
|
},
|
|
282
352
|
placeholder: t('Caption'),
|
|
283
353
|
autoComplete: "off",
|
|
@@ -41,6 +41,12 @@ Object.defineProperty(exports, "FontPlugin", {
|
|
|
41
41
|
return _font.default;
|
|
42
42
|
}
|
|
43
43
|
});
|
|
44
|
+
Object.defineProperty(exports, "GroupPlugin", {
|
|
45
|
+
enumerable: true,
|
|
46
|
+
get: function () {
|
|
47
|
+
return _group.default;
|
|
48
|
+
}
|
|
49
|
+
});
|
|
44
50
|
Object.defineProperty(exports, "HeaderPlugin", {
|
|
45
51
|
enumerable: true,
|
|
46
52
|
get: function () {
|
|
@@ -181,7 +187,8 @@ var _quickInsert = _interopRequireDefault(require("./quick-insert"));
|
|
|
181
187
|
var _wikiLink = _interopRequireDefault(require("./wiki-link"));
|
|
182
188
|
var _seatableColumn = _interopRequireDefault(require("./seatable-column"));
|
|
183
189
|
var _seatableTables = _interopRequireDefault(require("./seatable-tables"));
|
|
184
|
-
|
|
190
|
+
var _group = _interopRequireDefault(require("./group"));
|
|
191
|
+
const Plugins = [_markdown.default, _html.default, _header.default, _link.default, _blockquote.default, _list.default, _checkList.default, _codeBlock.default, _image.default, _video.default, _table.default, _multiColumn.default, _textStyle.default, _textAlign.default, _font.default, _sdocLink.default, _paragraph.default, _fileLink.default, _callout.default, _searchReplace.default, _quickInsert.default, _group.default];
|
|
185
192
|
const WikiPlugins = exports.WikiPlugins = [...Plugins, _wikiLink.default];
|
|
186
193
|
const CommentPlugins = exports.CommentPlugins = [_markdown.default, _html.default, _paragraph.default, _textStyle.default, _list.default, _image.default, _link.default, _mention.default, _blockquote.default];
|
|
187
194
|
var _default = exports.default = Plugins;
|
|
@@ -10,6 +10,7 @@ var _core = require("../../../core");
|
|
|
10
10
|
var _queries = require("../queries");
|
|
11
11
|
var _transforms = require("../transforms");
|
|
12
12
|
var _model = require("../model");
|
|
13
|
+
const validChildrenTypes = [_constants.GROUP, _constants.LIST_ITEM];
|
|
13
14
|
const normalizeList = editor => {
|
|
14
15
|
const {
|
|
15
16
|
normalizeNode
|
|
@@ -26,7 +27,7 @@ const normalizeList = editor => {
|
|
|
26
27
|
const children = (0, _core.getChildren)([node, path]);
|
|
27
28
|
const nonLiChild = children.find(_ref2 => {
|
|
28
29
|
let [child] = _ref2;
|
|
29
|
-
return child.type
|
|
30
|
+
return !validChildrenTypes.includes(child.type);
|
|
30
31
|
});
|
|
31
32
|
if (nonLiChild) {
|
|
32
33
|
const listItem = (0, _model.generateEmptyListItem)();
|
|
@@ -39,7 +40,7 @@ const normalizeList = editor => {
|
|
|
39
40
|
if ((0, _core.match)(node, [], {
|
|
40
41
|
type: listTypes
|
|
41
42
|
})) {
|
|
42
|
-
if (!node.children.length || !node.children.find(
|
|
43
|
+
if (!node.children.length || !node.children.find(child => validChildrenTypes.includes(child.type))) {
|
|
43
44
|
_slate.Transforms.removeNodes(editor, {
|
|
44
45
|
at: path
|
|
45
46
|
});
|
|
@@ -15,7 +15,7 @@ const normalizeListItem = (editor, _ref) => {
|
|
|
15
15
|
listItem
|
|
16
16
|
} = _ref;
|
|
17
17
|
let changed = false;
|
|
18
|
-
const validLiChildrenTypes = [...(0, _queries.getListTypes)(), _constants.PARAGRAPH];
|
|
18
|
+
const validLiChildrenTypes = [...(0, _queries.getListTypes)(), _constants.PARAGRAPH, _constants.GROUP];
|
|
19
19
|
const [, liPath] = listItem;
|
|
20
20
|
const liChildren = (0, _core.getChildren)(listItem);
|
|
21
21
|
const invalidLiChildrenPathRefs = liChildren.filter(_ref2 => {
|
|
@@ -210,6 +210,11 @@ const CustomRenderElement = props => {
|
|
|
210
210
|
const [renderSeaTableTable] = _plugins.SeaTableViewsPlugin.renderElements;
|
|
211
211
|
return renderSeaTableTable(props, editor);
|
|
212
212
|
}
|
|
213
|
+
case _constants.ELEMENT_TYPE.GROUP:
|
|
214
|
+
{
|
|
215
|
+
const [renderGroup] = _plugins.GroupPlugin.renderElements;
|
|
216
|
+
return renderGroup(props);
|
|
217
|
+
}
|
|
213
218
|
default:
|
|
214
219
|
{
|
|
215
220
|
const [renderParagraph] = _plugins.ParagraphPlugin.renderElements;
|
|
@@ -34,7 +34,7 @@ const RebaseDeleteModifyDecorate = _ref => {
|
|
|
34
34
|
}, [editor, element]);
|
|
35
35
|
const deleteMark = (0, _react.useCallback)(() => {
|
|
36
36
|
const path = (0, _core.findPath)(editor, element);
|
|
37
|
-
(0, _core.
|
|
37
|
+
(0, _core.deleteRebaseNodeMark)(editor, path, element, _constants2.REBASE_MARKS);
|
|
38
38
|
if (element.type === _constants.ELEMENT_TYPE.LIST_ITEM) {
|
|
39
39
|
(0, _core.updateRebaseParentNodeByPath)(editor, path);
|
|
40
40
|
}
|
|
@@ -34,7 +34,7 @@ const RebaseModifyDeleteDecorate = _ref => {
|
|
|
34
34
|
}, [editor, element]);
|
|
35
35
|
const deleteMark = (0, _react.useCallback)(() => {
|
|
36
36
|
const path = (0, _core.findPath)(editor, element);
|
|
37
|
-
(0, _core.
|
|
37
|
+
(0, _core.deleteRebaseNodeMark)(editor, path, element, _constants2.REBASE_MARKS);
|
|
38
38
|
if (element.type === _constants.ELEMENT_TYPE.LIST_ITEM) {
|
|
39
39
|
(0, _core.updateRebaseParentNodeByPath)(editor, path);
|
|
40
40
|
}
|
|
@@ -24,47 +24,79 @@ const RebaseModifyModifyDecorate = _ref => {
|
|
|
24
24
|
} = (0, _reactI18next.useTranslation)('sdoc-editor');
|
|
25
25
|
const editor = (0, _slateReact.useSlateStatic)();
|
|
26
26
|
const useMasterChanges = (0, _react.useCallback)(() => {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
27
|
+
(0, _core.rebaseNode)(editor, () => {
|
|
28
|
+
const path = (0, _core.findPath)(editor, element);
|
|
29
|
+
|
|
30
|
+
// delete my changes
|
|
31
|
+
const nextElementPath = [...path];
|
|
32
|
+
nextElementPath[path.length - 1] = path[path.length - 1] + 1;
|
|
33
|
+
_slate.Transforms.removeNodes(editor, {
|
|
34
|
+
at: nextElementPath
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
// update master changes
|
|
38
|
+
if (element.type === _constants.ELEMENT_TYPE.GROUP) {
|
|
39
|
+
(0, _core.replaceRebaseNode)(editor, {
|
|
40
|
+
at: path,
|
|
41
|
+
nodes: element.children
|
|
42
|
+
});
|
|
43
|
+
} else {
|
|
44
|
+
(0, _core.deleteRebaseNodeMark)(editor, path, element[_constants2.REBASE_MARK_KEY.OLD_ELEMENT], _constants2.REBASE_MARKS);
|
|
45
|
+
}
|
|
35
46
|
(0, _core.updateRebaseParentNodeByPath)(editor, path);
|
|
36
|
-
}
|
|
47
|
+
});
|
|
37
48
|
|
|
38
49
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
39
50
|
}, [editor, element]);
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
+
const useMyChanges = (0, _react.useCallback)(() => {
|
|
52
|
+
(0, _core.rebaseNode)(editor, () => {
|
|
53
|
+
const path = (0, _core.findPath)(editor, element);
|
|
54
|
+
const currentElementPath = [...path];
|
|
55
|
+
currentElementPath[path.length - 1] = path[path.length - 1] + 1;
|
|
56
|
+
const currentElement = (0, _core.getNode)(editor, currentElementPath);
|
|
57
|
+
const newCurrentElement = (0, _deepCopy.default)(currentElement);
|
|
58
|
+
if (element.type === _constants.ELEMENT_TYPE.GROUP) {
|
|
59
|
+
(0, _core.replaceRebaseNode)(editor, {
|
|
60
|
+
at: currentElementPath,
|
|
61
|
+
nodes: newCurrentElement.children
|
|
62
|
+
});
|
|
63
|
+
} else {
|
|
64
|
+
(0, _core.deleteRebaseNodeMark)(editor, currentElementPath, newCurrentElement, _constants2.REBASE_MARKS);
|
|
65
|
+
}
|
|
66
|
+
_slate.Transforms.removeNodes(editor, {
|
|
67
|
+
at: path
|
|
68
|
+
});
|
|
51
69
|
(0, _core.updateRebaseParentNodeByPath)(editor, path);
|
|
52
|
-
}
|
|
70
|
+
});
|
|
53
71
|
|
|
54
72
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
55
73
|
}, [editor, element]);
|
|
56
74
|
const useBothChanges = (0, _react.useCallback)(() => {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
75
|
+
(0, _core.rebaseNode)(editor, () => {
|
|
76
|
+
const path = (0, _core.findPath)(editor, element);
|
|
77
|
+
const nextElementPath = [...path.slice(0, -1), path[path.length - 1] + 1];
|
|
78
|
+
const nextElement = (0, _core.getNode)(editor, nextElementPath);
|
|
79
|
+
if (element.type === _constants.ELEMENT_TYPE.GROUP) {
|
|
80
|
+
// replace next element
|
|
81
|
+
(0, _core.replaceRebaseNode)(editor, {
|
|
82
|
+
at: nextElementPath,
|
|
83
|
+
nodes: nextElement.children
|
|
84
|
+
});
|
|
60
85
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
86
|
+
// replace current element
|
|
87
|
+
(0, _core.replaceRebaseNode)(editor, {
|
|
88
|
+
at: path,
|
|
89
|
+
nodes: element.children
|
|
90
|
+
});
|
|
91
|
+
} else {
|
|
92
|
+
// delete element marks
|
|
93
|
+
(0, _core.deleteRebaseNodeMark)(editor, path, element, _constants2.REBASE_MARKS);
|
|
94
|
+
|
|
95
|
+
// delete next element marks
|
|
96
|
+
(0, _core.deleteRebaseNodeMark)(editor, nextElementPath, nextElement, _constants2.REBASE_MARKS);
|
|
97
|
+
}
|
|
66
98
|
(0, _core.updateRebaseParentNodeByPath)(editor, path);
|
|
67
|
-
}
|
|
99
|
+
});
|
|
68
100
|
|
|
69
101
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
70
102
|
}, [editor, element]);
|
|
@@ -79,7 +111,7 @@ const RebaseModifyModifyDecorate = _ref => {
|
|
|
79
111
|
className: "mr-2 ml-2"
|
|
80
112
|
}, '|'), /*#__PURE__*/_react.default.createElement("div", {
|
|
81
113
|
className: "sdoc-rebase-btn",
|
|
82
|
-
onClick:
|
|
114
|
+
onClick: useMyChanges
|
|
83
115
|
}, t('Keep_my_modification')), /*#__PURE__*/_react.default.createElement("div", {
|
|
84
116
|
className: "mr-2 ml-2"
|
|
85
117
|
}, '|'), /*#__PURE__*/_react.default.createElement("div", {
|
|
@@ -37,7 +37,9 @@ const getTopLevelChanges = changes => {
|
|
|
37
37
|
if (parentNode instanceof Document) {
|
|
38
38
|
break;
|
|
39
39
|
} else {
|
|
40
|
+
var _dom4, _dom4$dataset;
|
|
40
41
|
dom = parentNode;
|
|
42
|
+
if ((_dom4 = dom) !== null && _dom4 !== void 0 && (_dom4$dataset = _dom4.dataset) !== null && _dom4$dataset !== void 0 && _dom4$dataset.id && !dom.classList.contains('table-cell')) break;
|
|
41
43
|
}
|
|
42
44
|
}
|
|
43
45
|
topLevelChanges.push(dom.dataset.id);
|
|
@@ -32,6 +32,49 @@ const hasConflict = content => {
|
|
|
32
32
|
return flag;
|
|
33
33
|
};
|
|
34
34
|
exports.hasConflict = hasConflict;
|
|
35
|
+
const expandGroup = content => {
|
|
36
|
+
if ([_constants2.ELEMENT_TYPE.UNORDERED_LIST, _constants2.ELEMENT_TYPE.ORDERED_LIST].includes(content.type)) {
|
|
37
|
+
return [{
|
|
38
|
+
...content,
|
|
39
|
+
children: content.children.map(item => {
|
|
40
|
+
if (item.type === _constants2.ELEMENT_TYPE.GROUP) {
|
|
41
|
+
return expandGroup(item);
|
|
42
|
+
}
|
|
43
|
+
return item;
|
|
44
|
+
}).flat(1)
|
|
45
|
+
}];
|
|
46
|
+
}
|
|
47
|
+
return content.type === _constants2.ELEMENT_TYPE.GROUP ? content.children : [content];
|
|
48
|
+
};
|
|
49
|
+
const mergeChanges = changes => {
|
|
50
|
+
if (!Array.isArray(changes) || changes.length === 0) return changes;
|
|
51
|
+
let value = [];
|
|
52
|
+
let i = 0;
|
|
53
|
+
while (i < changes.length) {
|
|
54
|
+
const change = changes[i];
|
|
55
|
+
const lastChange = value[value.length - 1];
|
|
56
|
+
if (change && lastChange && change[_constants.REBASE_MARK_KEY.MODIFY_TYPE] === _constants.MODIFY_TYPE.ADD && lastChange[_constants.REBASE_MARK_KEY.MODIFY_TYPE] === _constants.MODIFY_TYPE.DELETE) {
|
|
57
|
+
value = value.slice(0, value.length - 1);
|
|
58
|
+
lastChange[_constants.REBASE_MARK_KEY.MODIFY_TYPE] && delete lastChange[_constants.REBASE_MARK_KEY.MODIFY_TYPE];
|
|
59
|
+
change[_constants.REBASE_MARK_KEY.MODIFY_TYPE] && delete change[_constants.REBASE_MARK_KEY.MODIFY_TYPE];
|
|
60
|
+
value.push({
|
|
61
|
+
id: change.id.endsWith('_group') ? change.id : change.id + '_group',
|
|
62
|
+
type: _constants2.ELEMENT_TYPE.GROUP,
|
|
63
|
+
[_constants.REBASE_MARK_KEY.MODIFY_TYPE]: _constants.MODIFY_TYPE.MODIFY,
|
|
64
|
+
children: expandGroup(change),
|
|
65
|
+
[_constants.REBASE_MARK_KEY.OLD_ELEMENT]: {
|
|
66
|
+
id: lastChange.id.endsWith('_group') ? lastChange.id : lastChange.id + '_group',
|
|
67
|
+
type: _constants2.ELEMENT_TYPE.GROUP,
|
|
68
|
+
children: expandGroup(lastChange)
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
} else {
|
|
72
|
+
value.push(change);
|
|
73
|
+
}
|
|
74
|
+
i++;
|
|
75
|
+
}
|
|
76
|
+
return value;
|
|
77
|
+
};
|
|
35
78
|
const getChanges = function (masterContent, revisionContent) {
|
|
36
79
|
let childrenName = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'children';
|
|
37
80
|
const {
|
|
@@ -51,17 +94,21 @@ const getChanges = function (masterContent, revisionContent) {
|
|
|
51
94
|
removed
|
|
52
95
|
} = idDiff;
|
|
53
96
|
if (added) {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
[
|
|
57
|
-
|
|
58
|
-
|
|
97
|
+
// merge consecutive identical operations
|
|
98
|
+
content.push({
|
|
99
|
+
id: value[0] + '_group',
|
|
100
|
+
type: _constants2.ELEMENT_TYPE.GROUP,
|
|
101
|
+
[_constants.REBASE_MARK_KEY.MODIFY_TYPE]: _constants.MODIFY_TYPE.ADD,
|
|
102
|
+
children: value.map(item => currentContentMap[item])
|
|
103
|
+
});
|
|
59
104
|
} else if (removed) {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
[
|
|
63
|
-
|
|
64
|
-
|
|
105
|
+
// merge consecutive identical operations
|
|
106
|
+
content.push({
|
|
107
|
+
id: value[0] + '_group',
|
|
108
|
+
type: _constants2.ELEMENT_TYPE.GROUP,
|
|
109
|
+
[_constants.REBASE_MARK_KEY.MODIFY_TYPE]: _constants.MODIFY_TYPE.DELETE,
|
|
110
|
+
children: value.map(item => masterContentMap[item])
|
|
111
|
+
});
|
|
65
112
|
} else {
|
|
66
113
|
value.forEach(elementId => {
|
|
67
114
|
if (_objectUtils.default.isSameObject(masterContentMap[elementId], currentContentMap[elementId])) {
|
|
@@ -87,7 +134,7 @@ const getChanges = function (masterContent, revisionContent) {
|
|
|
87
134
|
});
|
|
88
135
|
}
|
|
89
136
|
});
|
|
90
|
-
return content;
|
|
137
|
+
return mergeChanges(content);
|
|
91
138
|
};
|
|
92
139
|
const getMergeElement = (diffElement, baseElement) => {
|
|
93
140
|
const modifyType = diffElement[_constants.REBASE_MARK_KEY.MODIFY_TYPE];
|
|
@@ -99,7 +146,7 @@ const getMergeElement = (diffElement, baseElement) => {
|
|
|
99
146
|
// revision does not have this element, master has this element
|
|
100
147
|
if (modifyType === _constants.MODIFY_TYPE.DELETE) {
|
|
101
148
|
// 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.
|
|
102
|
-
if (!baseElement) return
|
|
149
|
+
if (!baseElement) return expandGroup(newElement);
|
|
103
150
|
|
|
104
151
|
// base content has this element, master modified it, indicating that revision deleted it, and the user manually selected the conflict
|
|
105
152
|
if (!_objectUtils.default.isSameObject(baseElement, diffElement, [_constants.REBASE_MARK_KEY.MODIFY_TYPE])) {
|
|
@@ -114,7 +161,7 @@ const getMergeElement = (diffElement, baseElement) => {
|
|
|
114
161
|
// revision has this element, master does not have this element
|
|
115
162
|
if (modifyType === _constants.MODIFY_TYPE.ADD) {
|
|
116
163
|
// 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.
|
|
117
|
-
if (!baseElement) return
|
|
164
|
+
if (!baseElement) return expandGroup(newElement);
|
|
118
165
|
|
|
119
166
|
// master deleted it, revision modified it, and the user manually selected the conflict
|
|
120
167
|
if (!_objectUtils.default.isSameObject(baseElement, diffElement, [_constants.REBASE_MARK_KEY.MODIFY_TYPE])) {
|
|
@@ -184,10 +231,10 @@ const getMergeElement = (diffElement, baseElement) => {
|
|
|
184
231
|
[_constants.REBASE_MARK_KEY.ORIGIN]: _constants.REBASE_ORIGIN.MY
|
|
185
232
|
}];
|
|
186
233
|
}
|
|
187
|
-
if (_objectUtils.default.isSameObject(masterElement, baseElement)) return
|
|
234
|
+
if (_objectUtils.default.isSameObject(masterElement, baseElement)) return expandGroup(newElement);
|
|
188
235
|
if (_objectUtils.default.isSameObject(newElement, baseElement)) return [masterElement];
|
|
189
236
|
if (_objectUtils.default.isSameObject(masterElement, newElement, ['type'])) {
|
|
190
|
-
if (_objectUtils.default.isSameObject(masterElement, baseElement, ['type'])) return
|
|
237
|
+
if (_objectUtils.default.isSameObject(masterElement, baseElement, ['type'])) return expandGroup(newElement);
|
|
191
238
|
if (_objectUtils.default.isSameObject(newElement, baseElement, ['type'])) return [masterElement];
|
|
192
239
|
}
|
|
193
240
|
|
|
@@ -199,7 +246,7 @@ const getMergeElement = (diffElement, baseElement) => {
|
|
|
199
246
|
}];
|
|
200
247
|
}
|
|
201
248
|
newElement[_constants.REBASE_MARK_KEY.OLD_ELEMENT] && delete newElement[_constants.REBASE_MARK_KEY.OLD_ELEMENT];
|
|
202
|
-
return
|
|
249
|
+
return expandGroup(newElement);
|
|
203
250
|
};
|
|
204
251
|
const getMergeContent = function (baseContent, diffChanges) {
|
|
205
252
|
let childrenName = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'children';
|
|
@@ -33,12 +33,9 @@ const ChangesCount = _ref => {
|
|
|
33
33
|
}
|
|
34
34
|
}, 100);
|
|
35
35
|
}).then(() => {
|
|
36
|
-
console.log('allchange', allChanges);
|
|
37
36
|
if (allChanges.changes.length !== 0) {
|
|
38
37
|
const topLevelChanges = (0, _diff.getTopLevelChanges)(allChanges.changes);
|
|
39
|
-
console.log(topLevelChanges);
|
|
40
38
|
const changes = (0, _diff.getMergedChanges)(topLevelChanges, allChanges.value);
|
|
41
|
-
console.log(9, changes);
|
|
42
39
|
setChanges(changes);
|
|
43
40
|
}
|
|
44
41
|
});
|
|
@@ -78,12 +75,10 @@ const ChangesCount = _ref => {
|
|
|
78
75
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
79
76
|
}, [changes, currentDiffIndex]);
|
|
80
77
|
if (!Array.isArray(changes) || changes.length === 0) {
|
|
81
|
-
console.log('change', changes);
|
|
82
78
|
return /*#__PURE__*/_react.default.createElement("div", {
|
|
83
79
|
className: "sdoc-revision-changes-container d-flex align-items-center pl-2 pr-2 ml-4"
|
|
84
80
|
}, t('No_changes'));
|
|
85
81
|
}
|
|
86
|
-
console.log('changes', changes);
|
|
87
82
|
const changesCount = changes.length;
|
|
88
83
|
return /*#__PURE__*/_react.default.createElement("div", {
|
|
89
84
|
className: "sdoc-revision-changes-container d-flex align-items-center ml-4"
|
|
@@ -52,7 +52,6 @@ const SimpleEditor = _ref => {
|
|
|
52
52
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
53
53
|
}, []);
|
|
54
54
|
const setDiffChanges = (0, _react.useCallback)(diff => {
|
|
55
|
-
console.log(32323);
|
|
56
55
|
setChanges(diff);
|
|
57
56
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
58
57
|
}, [isShowChanges]);
|
package/package.json
CHANGED
|
@@ -610,5 +610,7 @@
|
|
|
610
610
|
"Add_video_link": "Add video link",
|
|
611
611
|
"Link_Seafile_video_file": "Link Seafile video file",
|
|
612
612
|
"Select_video_file": "Select video file",
|
|
613
|
-
"Support_Youtube_Tencent_Bilibili_and_more": "Support Youtube, Tencent, Bilibili and more"
|
|
613
|
+
"Support_Youtube_Tencent_Bilibili_and_more": "Support Youtube, Tencent, Bilibili and more",
|
|
614
|
+
"Image_cannot_be_copied_Please_download_the_source_image": "Image cannot be copied. Please download the source image,",
|
|
615
|
+
"And_select_insert_-_image_to_upload": "and select 「insert」 - 「image」 to upload."
|
|
614
616
|
}
|
|
@@ -610,5 +610,7 @@
|
|
|
610
610
|
"Add_video_link": "Videolink hinzufügen",
|
|
611
611
|
"Link_Seafile_video_file": "Link Seafile video file",
|
|
612
612
|
"Select_video_file": "Select video file",
|
|
613
|
-
"Support_Youtube_Tencent_Bilibili_and_more": "Support Youtube, Tencent, Bilibili and more"
|
|
613
|
+
"Support_Youtube_Tencent_Bilibili_and_more": "Support Youtube, Tencent, Bilibili and more",
|
|
614
|
+
"Image_cannot_be_copied_Please_download_the_source_image": "Image cannot be copied. Please download the source image,",
|
|
615
|
+
"And_select_insert_-_image_to_upload": "and select 「insert」 - 「image」 to upload."
|
|
614
616
|
}
|
|
@@ -610,5 +610,7 @@
|
|
|
610
610
|
"Add_video_link": "Add video link",
|
|
611
611
|
"Link_Seafile_video_file": "Link Seafile video file",
|
|
612
612
|
"Select_video_file": "Select video file",
|
|
613
|
-
"Support_Youtube_Tencent_Bilibili_and_more": "Support Youtube, Tencent, Bilibili and more"
|
|
613
|
+
"Support_Youtube_Tencent_Bilibili_and_more": "Support Youtube, Tencent, Bilibili and more",
|
|
614
|
+
"Image_cannot_be_copied_Please_download_the_source_image": "Image cannot be copied. Please download the source image,",
|
|
615
|
+
"And_select_insert_-_image_to_upload": "and select 「insert」 - 「image」 to upload."
|
|
614
616
|
}
|
|
@@ -610,5 +610,7 @@
|
|
|
610
610
|
"Add_video_link": "Add video link",
|
|
611
611
|
"Link_Seafile_video_file": "Link Seafile video file",
|
|
612
612
|
"Select_video_file": "Select video file",
|
|
613
|
-
"Support_Youtube_Tencent_Bilibili_and_more": "Support Youtube, Tencent, Bilibili and more"
|
|
613
|
+
"Support_Youtube_Tencent_Bilibili_and_more": "Support Youtube, Tencent, Bilibili and more",
|
|
614
|
+
"Image_cannot_be_copied_Please_download_the_source_image": "Image cannot be copied. Please download the source image,",
|
|
615
|
+
"And_select_insert_-_image_to_upload": "and select 「insert」 - 「image」 to upload."
|
|
614
616
|
}
|
|
@@ -610,5 +610,7 @@
|
|
|
610
610
|
"Add_video_link": "Add video link",
|
|
611
611
|
"Link_Seafile_video_file": "Link Seafile video file",
|
|
612
612
|
"Select_video_file": "Select video file",
|
|
613
|
-
"Support_Youtube_Tencent_Bilibili_and_more": "Support Youtube, Tencent, Bilibili and more"
|
|
613
|
+
"Support_Youtube_Tencent_Bilibili_and_more": "Support Youtube, Tencent, Bilibili and more",
|
|
614
|
+
"Image_cannot_be_copied_Please_download_the_source_image": "Image cannot be copied. Please download the source image,",
|
|
615
|
+
"And_select_insert_-_image_to_upload": "and select 「insert」 - 「image」 to upload."
|
|
614
616
|
}
|
|
@@ -610,5 +610,7 @@
|
|
|
610
610
|
"Add_video_link": "Add video link",
|
|
611
611
|
"Link_Seafile_video_file": "Link Seafile video file",
|
|
612
612
|
"Select_video_file": "Select video file",
|
|
613
|
-
"Support_Youtube_Tencent_Bilibili_and_more": "Support Youtube, Tencent, Bilibili and more"
|
|
613
|
+
"Support_Youtube_Tencent_Bilibili_and_more": "Support Youtube, Tencent, Bilibili and more",
|
|
614
|
+
"Image_cannot_be_copied_Please_download_the_source_image": "Image cannot be copied. Please download the source image,",
|
|
615
|
+
"And_select_insert_-_image_to_upload": "and select 「insert」 - 「image」 to upload."
|
|
614
616
|
}
|
|
@@ -610,5 +610,7 @@
|
|
|
610
610
|
"Add_video_link": "Add video link",
|
|
611
611
|
"Link_Seafile_video_file": "Link Seafile video file",
|
|
612
612
|
"Select_video_file": "Select video file",
|
|
613
|
-
"Support_Youtube_Tencent_Bilibili_and_more": "Support Youtube, Tencent, Bilibili and more"
|
|
613
|
+
"Support_Youtube_Tencent_Bilibili_and_more": "Support Youtube, Tencent, Bilibili and more",
|
|
614
|
+
"Image_cannot_be_copied_Please_download_the_source_image": "Image cannot be copied. Please download the source image,",
|
|
615
|
+
"And_select_insert_-_image_to_upload": "and select 「insert」 - 「image」 to upload."
|
|
614
616
|
}
|
|
@@ -610,5 +610,7 @@
|
|
|
610
610
|
"Add_video_link": "Add video link",
|
|
611
611
|
"Link_Seafile_video_file": "Link Seafile video file",
|
|
612
612
|
"Select_video_file": "Select video file",
|
|
613
|
-
"Support_Youtube_Tencent_Bilibili_and_more": "Support Youtube, Tencent, Bilibili and more"
|
|
613
|
+
"Support_Youtube_Tencent_Bilibili_and_more": "Support Youtube, Tencent, Bilibili and more",
|
|
614
|
+
"Image_cannot_be_copied_Please_download_the_source_image": "Image cannot be copied. Please download the source image,",
|
|
615
|
+
"And_select_insert_-_image_to_upload": "and select 「insert」 - 「image」 to upload."
|
|
614
616
|
}
|
|
@@ -610,5 +610,7 @@
|
|
|
610
610
|
"Add_video_link": "Добавить ссылку на видео",
|
|
611
611
|
"Link_Seafile_video_file": "Ссылка на видео файл Seafile",
|
|
612
612
|
"Select_video_file": "Выбрать видео файл",
|
|
613
|
-
"Support_Youtube_Tencent_Bilibili_and_more": "Support Youtube, Tencent, Bilibili and more"
|
|
613
|
+
"Support_Youtube_Tencent_Bilibili_and_more": "Support Youtube, Tencent, Bilibili and more",
|
|
614
|
+
"Image_cannot_be_copied_Please_download_the_source_image": "Image cannot be copied. Please download the source image,",
|
|
615
|
+
"And_select_insert_-_image_to_upload": "and select 「insert」 - 「image」 to upload."
|
|
614
616
|
}
|
|
@@ -610,5 +610,7 @@
|
|
|
610
610
|
"Add_video_link": "添加视频链接",
|
|
611
611
|
"Link_Seafile_video_file": "链接Seafile视频文件",
|
|
612
612
|
"Select_video_file": "选择视频文件",
|
|
613
|
-
"Support_Youtube_Tencent_Bilibili_and_more": "支持Youtube,腾讯视频,B站及其他平台"
|
|
613
|
+
"Support_Youtube_Tencent_Bilibili_and_more": "支持Youtube,腾讯视频,B站及其他平台",
|
|
614
|
+
"Image_cannot_be_copied_Please_download_the_source_image": "此照片不支持复制,请下载原图",
|
|
615
|
+
"And_select_insert_-_image_to_upload": "后点击工具栏「插入」- 「照片」上传"
|
|
614
616
|
}
|