@seafile/sdoc-editor 2.0.0 → 2.0.2

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 (26) hide show
  1. package/dist/basic-sdk/assets/css/sdoc-editor-plugins.css +32 -0
  2. package/dist/basic-sdk/extension/plugins/font/helpers.js +7 -0
  3. package/dist/basic-sdk/extension/plugins/header/render-elem.js +2 -1
  4. package/dist/basic-sdk/extension/plugins/image/helpers.js +9 -3
  5. package/dist/basic-sdk/extension/plugins/image/image-loader/index.css +37 -0
  6. package/dist/basic-sdk/extension/plugins/image/image-loader/index.js +23 -0
  7. package/dist/basic-sdk/extension/plugins/image/render-elem.js +36 -2
  8. package/dist/basic-sdk/extension/plugins/image/use-upload-image.js +80 -0
  9. package/dist/basic-sdk/extension/plugins/multi-column/plugin.js +1 -1
  10. package/dist/basic-sdk/extension/plugins/seatable-column/plugin.js +9 -1
  11. package/dist/basic-sdk/extension/plugins/seatable-column/render-elem.js +35 -0
  12. package/dist/basic-sdk/extension/plugins/text-style/helpers.js +1 -1
  13. package/dist/basic-sdk/extension/plugins/text-style/menu/index.js +10 -1
  14. package/dist/basic-sdk/extension/toolbar/side-toolbar/helpers.js +2 -1
  15. package/dist/components/copy-image-error-svg/index.js +64 -0
  16. package/package.json +7 -6
  17. package/public/locales/cs/sdoc-editor.json +4 -1
  18. package/public/locales/de/sdoc-editor.json +4 -1
  19. package/public/locales/en/sdoc-editor.json +5 -1
  20. package/public/locales/es/sdoc-editor.json +4 -1
  21. package/public/locales/es_AR/sdoc-editor.json +4 -1
  22. package/public/locales/es_MX/sdoc-editor.json +4 -1
  23. package/public/locales/fr/sdoc-editor.json +4 -1
  24. package/public/locales/it/sdoc-editor.json +4 -1
  25. package/public/locales/ru/sdoc-editor.json +4 -1
  26. package/public/locales/zh_CN/sdoc-editor.json +5 -1
@@ -62,6 +62,38 @@
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
+
65
97
  .sdoc-editor__article .sdoc-image-inner {
66
98
  position: relative;
67
99
  display: inline-block;
@@ -52,6 +52,13 @@ const getFontSize = editor => {
52
52
  }
53
53
  return false;
54
54
  }
55
+ if (!_slate.Editor.isEditor(n) && _slate.Editor.isVoid(editor, n)) {
56
+ const parentNode = (0, _core.getParentNode)(editor.children, n.id);
57
+ if (!parentNode) return false;
58
+ if ([_constants.TITLE, _constants.SUBTITLE, ..._constants.HEADERS, _constants.CODE_LINE].includes(parentNode.type)) {
59
+ return true;
60
+ }
61
+ }
55
62
  return false;
56
63
  }
57
64
  });
@@ -9,6 +9,7 @@ var _react = _interopRequireDefault(require("react"));
9
9
  var _slate = require("@seafile/slate");
10
10
  var _core = require("../../core");
11
11
  var _constants = require("../../constants");
12
+ var _helper = require("../paragraph/helper");
12
13
  const renderTitle = (props, editor) => {
13
14
  const {
14
15
  element,
@@ -69,7 +70,7 @@ const renderHeader = (props, editor) => {
69
70
  })
70
71
  };
71
72
  let isShowPlaceHolder = false;
72
- if (_slate.Node.string(element) === '' && !isComposing) {
73
+ if ((0, _helper.isEmptyNode)(element) && _slate.Node.string(element) === '' && !isComposing) {
73
74
  isShowPlaceHolder = true;
74
75
  }
75
76
  return /*#__PURE__*/_react.default.createElement("div", Object.assign({
@@ -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.isImagUrlIsFromCopy = exports.insertImageFiles = exports.insertImage = exports.hasSdocImages = exports.handleBase64Image = exports.getSingleImageFromFragment = exports.getImageURL = exports.getImageData = exports.generateImageNode = 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");
@@ -153,7 +153,7 @@ const getImageURL = (data, editor) => {
153
153
  return imgUrl;
154
154
  }
155
155
  }
156
- if (url && url.startsWith('http')) return url;
156
+ if (isImagUrlIsFromCopy(url)) return url;
157
157
  const serviceUrl = _context.default.getSetting('serviceUrl');
158
158
  const assetsUrl = _context.default.getSetting('assetsUrl');
159
159
  return (0, _urlJoin.default)(serviceUrl, assetsUrl, url);
@@ -277,4 +277,10 @@ const handleBase64Image = (editor, path, imgData) => {
277
277
  });
278
278
  });
279
279
  };
280
- exports.handleBase64Image = handleBase64Image;
280
+ exports.handleBase64Image = handleBase64Image;
281
+ const isImagUrlIsFromCopy = url => {
282
+ if (url && url.startsWith('http')) return true;
283
+ if (url && url.startsWith('attachment')) return true; // from yuque
284
+ return false;
285
+ };
286
+ exports.isImagUrlIsFromCopy = isImagUrlIsFromCopy;
@@ -0,0 +1,37 @@
1
+ .sdoc-image-process-container {
2
+ position: absolute;
3
+ width: 100%;
4
+ height: 100%;
5
+ display: flex;
6
+ flex-direction: column;
7
+ align-items: center;
8
+ justify-content: center;
9
+ top: 0;
10
+ left: 0;
11
+ background-color: 'rgba(0, 0, 0, 0.5)'
12
+ }
13
+
14
+ @keyframes spin {
15
+ 0% {
16
+ transform: rotate(0deg);
17
+ }
18
+
19
+ 100% {
20
+ transform: rotate(360deg);
21
+ }
22
+ }
23
+
24
+ .sdoc-image-process-container .loading-spinner {
25
+ border: 3px solid #d8d8d8;
26
+ border-top: 3px solid #939393;
27
+ border-radius: 50%;
28
+ width: 20px;
29
+ height: 20px;
30
+ animation: spin 1s linear infinite;
31
+ user-select: none;
32
+ pointer-events: none;
33
+ }
34
+
35
+ .sdoc-image-process-container .copyright {
36
+ margin-top: 4px;
37
+ }
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.default = ImageLoader;
8
+ var _react = _interopRequireDefault(require("react"));
9
+ require("./index.css");
10
+ function ImageLoader(_ref) {
11
+ let {
12
+ copyright
13
+ } = _ref;
14
+ return /*#__PURE__*/_react.default.createElement("div", {
15
+ className: "sdoc-image-process-container"
16
+ }, /*#__PURE__*/_react.default.createElement("div", {
17
+ className: "loading-spinner"
18
+ }, /*#__PURE__*/_react.default.createElement("div", {
19
+ className: "spinner"
20
+ })), copyright && /*#__PURE__*/_react.default.createElement("div", {
21
+ className: "copyright"
22
+ }, copyright));
23
+ }
@@ -21,6 +21,9 @@ var _constants2 = require("./constants");
21
21
  var _constants3 = require("../../constants");
22
22
  var _constants4 = require("../../../../constants");
23
23
  var _imagePlaceholder = _interopRequireDefault(require("../../../assets/images/image-placeholder.png"));
24
+ var _copyImageErrorSvg = _interopRequireDefault(require("../../../../components/copy-image-error-svg"));
25
+ var _useUploadImage = _interopRequireDefault(require("./use-upload-image"));
26
+ var _imageLoader = _interopRequireDefault(require("./image-loader"));
24
27
  const Image = _ref => {
25
28
  var _imageRef$current, _imageRef$current2;
26
29
  let {
@@ -57,6 +60,14 @@ const Image = _ref => {
57
60
  const [isShowImageHoverMenu, setIsShowImageHoverMenu] = (0, _react.useState)(false);
58
61
  const [menuPosition, setMenuPosition] = (0, _react.useState)({});
59
62
  const [caption, setCaption] = (0, _react.useState)((data === null || data === void 0 ? void 0 : data.caption) || '');
63
+ const {
64
+ isCopyImageLoading,
65
+ isCopyImageError,
66
+ setCopyImageLoading
67
+ } = (0, _useUploadImage.default)({
68
+ editor,
69
+ element
70
+ });
60
71
  const registerEvent = (0, _react.useCallback)(eventList => {
61
72
  eventList.forEach(element => {
62
73
  document.addEventListener(element.eventName, element.event);
@@ -197,6 +208,11 @@ const Image = _ref => {
197
208
  setIsShowImagePlaceholder(false);
198
209
  }
199
210
  }, [data, editor]);
211
+ const onImageLoaded = (0, _react.useCallback)(() => {
212
+ if ((0, _helpers.isImagUrlIsFromCopy)(data.src)) {
213
+ setCopyImageLoading(true);
214
+ }
215
+ }, [data.src, setCopyImageLoading]);
200
216
  const onImageLoadError = (0, _react.useCallback)(() => {
201
217
  // Check is due to the image is pasted from the clipboard in base64
202
218
  if (data.src.startsWith('data:image/jpeg;base64')) {
@@ -232,6 +248,7 @@ const Image = _ref => {
232
248
  },
233
249
  onMouseOver: e => (0, _helpers.selectImageWhenSelectPartial)(e, editor, element, isSelected),
234
250
  contentEditable: "false",
251
+ "data-src": (0, _helpers.getImageURL)(data, editor),
235
252
  suppressContentEditableWarning: true
236
253
  }), /*#__PURE__*/_react.default.createElement("img", {
237
254
  ref: imageRef,
@@ -239,7 +256,21 @@ const Image = _ref => {
239
256
  style: getImageStyle(),
240
257
  draggable: false,
241
258
  alt: ""
242
- }), children), !isShowImagePlaceholder && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("span", Object.assign({
259
+ }), children), isCopyImageError && /*#__PURE__*/_react.default.createElement("span", Object.assign({
260
+ className: (0, _classnames.default)('sdoc-image-wrapper', className)
261
+ }, attributes, {
262
+ style: {
263
+ ...style
264
+ },
265
+ onMouseOver: e => (0, _helpers.selectImageWhenSelectPartial)(e, editor, element, isSelected),
266
+ contentEditable: "false",
267
+ "data-src": data.src,
268
+ suppressContentEditableWarning: true
269
+ }), /*#__PURE__*/_react.default.createElement(_copyImageErrorSvg.default, {
270
+ t: t,
271
+ isSelected: isSelected,
272
+ imageRef: imageRef
273
+ }), children), !isShowImagePlaceholder && !isCopyImageError && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("span", Object.assign({
243
274
  "data-id": element.id,
244
275
  className: (0, _classnames.default)('sdoc-image-wrapper', className)
245
276
  }, attributes, {
@@ -256,16 +287,19 @@ const Image = _ref => {
256
287
  }, /*#__PURE__*/_react.default.createElement("span", {
257
288
  style: imageStyle
258
289
  }, /*#__PURE__*/_react.default.createElement("img", {
290
+ ref: imageRef,
259
291
  className: (0, _classnames.default)({
260
292
  'image-selected': isSelected
261
293
  }),
262
294
  onClick: onClickImage,
263
- ref: imageRef,
264
295
  src: (0, _helpers.getImageURL)(data, editor),
265
296
  style: getImageStyle(),
266
297
  draggable: false,
298
+ onLoad: onImageLoaded,
267
299
  onError: onImageLoadError,
268
300
  alt: ""
301
+ }), isCopyImageLoading && /*#__PURE__*/_react.default.createElement(_imageLoader.default, {
302
+ copyright: t('Image_is_uploading')
269
303
  }), isSelected && /*#__PURE__*/_react.default.createElement("span", {
270
304
  className: "image-resizer",
271
305
  ref: resizerRef,
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.default = void 0;
8
+ var _react = require("react");
9
+ var _slate = require("@seafile/slate");
10
+ var _slateReact = require("@seafile/slate-react");
11
+ var _context = _interopRequireDefault(require("../../../../context"));
12
+ var _helpers = require("./helpers");
13
+ const updateImageNode = async function (editor, element, newUrl) {
14
+ let isError = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
15
+ const nodePath = _slateReact.ReactEditor.findPath(editor, element);
16
+ const newData = {
17
+ ...element.data,
18
+ src: newUrl,
19
+ is_copy_error: isError
20
+ };
21
+ _slate.Transforms.setNodes(editor, {
22
+ data: newData
23
+ }, {
24
+ at: nodePath
25
+ });
26
+ };
27
+ const useImageUpload = _ref => {
28
+ let {
29
+ editor,
30
+ element
31
+ } = _ref;
32
+ const {
33
+ data
34
+ } = element;
35
+ const {
36
+ is_copy_error = false
37
+ } = data;
38
+ const [isLoading, setIsLoading] = (0, _react.useState)(false);
39
+ const [isCopyError, setIsCopyError] = (0, _react.useState)(is_copy_error);
40
+ (0, _react.useEffect)(() => {
41
+ const {
42
+ src: url
43
+ } = data;
44
+ if (isCopyError) return;
45
+ if (!(0, _helpers.isImagUrlIsFromCopy)(url)) return;
46
+ const downloadAndUploadImages = async url => {
47
+ try {
48
+ const response = await fetch(url);
49
+ if (response.ok) {
50
+ const blob = await response.blob();
51
+ const file = new File([blob], 'downloaded_image.png', {
52
+ type: blob.type
53
+ });
54
+ const imageUrl = await _context.default.uploadLocalImage([file]);
55
+ if (imageUrl && imageUrl[0]) {
56
+ updateImageNode(editor, element, imageUrl[0]);
57
+ }
58
+ } else {
59
+ throw new Error(`HTTP error status: ${response.status}`);
60
+ }
61
+ } catch (error) {
62
+ console.error(error);
63
+ updateImageNode(editor, element, url, true);
64
+ setIsCopyError(true);
65
+ } finally {
66
+ setTimeout(() => {
67
+ setIsLoading(false);
68
+ }, 500);
69
+ }
70
+ };
71
+ downloadAndUploadImages(url);
72
+ // eslint-disable-next-line react-hooks/exhaustive-deps
73
+ }, []);
74
+ return {
75
+ isCopyImageLoading: isLoading,
76
+ setCopyImageLoading: setIsLoading,
77
+ isCopyImageError: isCopyError
78
+ };
79
+ };
80
+ var _default = exports.default = useImageUpload;
@@ -82,7 +82,7 @@ const withMultiColumn = editor => {
82
82
  const nextNode = _slate.Editor.next(newEditor);
83
83
  const nextColumnIndex = nextNode[1][1];
84
84
  const currentMultiColumnEntry = (0, _core.getSelectedNodeEntryByType)(editor, _constants.ELEMENT_TYPE.MULTI_COLUMN);
85
- if (!currentMultiColumnEntry) return deleteBackward(unit);
85
+ if (!currentMultiColumnEntry) return deleteForward(unit);
86
86
  const {
87
87
  column,
88
88
  children: childColumn
@@ -8,7 +8,8 @@ var _constants = require("../../constants");
8
8
  const withColumn = editor => {
9
9
  const {
10
10
  isInline,
11
- isVoid
11
+ isVoid,
12
+ markableVoid
12
13
  } = editor;
13
14
  const newEditor = editor;
14
15
  newEditor.isInline = element => {
@@ -25,6 +26,13 @@ const withColumn = editor => {
25
26
  if (type === _constants.ELEMENT_TYPE.SEATABLE_COLUMN) return true;
26
27
  return isVoid(element);
27
28
  };
29
+ newEditor.markableVoid = element => {
30
+ const {
31
+ type
32
+ } = element;
33
+ if (type === _constants.ELEMENT_TYPE.SEATABLE_COLUMN) return true;
34
+ return markableVoid(element);
35
+ };
28
36
  return newEditor;
29
37
  };
30
38
  var _default = exports.default = withColumn;
@@ -36,11 +36,46 @@ const Column = _ref => {
36
36
  setIsClicked(false);
37
37
  }
38
38
  }, [isSelected, isReadOnly]);
39
+ const {
40
+ font_size = null,
41
+ font = null,
42
+ bold = null,
43
+ italic = null,
44
+ underline = null,
45
+ color = null,
46
+ highlight_color = null,
47
+ strikethrough = null
48
+ } = element.children[0];
39
49
  const style = {
40
50
  margin: '0 10px',
41
51
  border: '1px solid transparent',
52
+ userSelect: 'none',
42
53
  ...(isClicked && {
43
54
  border: '1px solid red'
55
+ }),
56
+ ...(font_size && {
57
+ fontSize: font_size
58
+ }),
59
+ ...(font && {
60
+ fontFamily: font
61
+ }),
62
+ ...(bold && {
63
+ fontWeight: 600
64
+ }),
65
+ ...(italic && {
66
+ fontStyle: 'italic'
67
+ }),
68
+ ...(underline && {
69
+ textDecoration: 'underline'
70
+ }),
71
+ ...(color && {
72
+ color: color
73
+ }),
74
+ ...(highlight_color && {
75
+ backgroundColor: highlight_color
76
+ }),
77
+ ...(strikethrough && {
78
+ textDecoration: 'line-through'
44
79
  })
45
80
  };
46
81
  return /*#__PURE__*/_react.default.createElement("span", Object.assign({}, attributes, {
@@ -16,7 +16,7 @@ const isMenuDisabled = (editor, readonly) => {
16
16
  match: n => {
17
17
  const type = (0, _core.getNodeType)(n);
18
18
  if (type === _elementType.CODE_BLOCK) return true; // Code block
19
- if (_slate.Editor.isVoid(editor, n)) return true; // void node
19
+ if (_slate.Editor.isVoid(editor, n) && (n === null || n === void 0 ? void 0 : n.type) !== _elementType.SEATABLE_COLUMN) return true; // void node
20
20
 
21
21
  return false;
22
22
  },
@@ -49,6 +49,10 @@ const TextStyleMenuList = _ref => {
49
49
  return (0, _helpers2.isMenuDisabled)(editor, readonly);
50
50
  // eslint-disable-next-line react-hooks/exhaustive-deps
51
51
  }, [editor, readonly]);
52
+ const isSelectedSeaTableColumn = (0, _react.useCallback)(() => {
53
+ const entery = (0, _core.getSelectedNodeByType)(editor, _constants.SEATABLE_COLUMN);
54
+ return !!entery;
55
+ }, [editor]);
52
56
  const openLinkDialog = (0, _react.useCallback)(() => {
53
57
  const eventBus = _eventBus.default.getInstance();
54
58
  eventBus.dispatch(_constants2.INTERNAL_EVENT.INSERT_ELEMENT, {
@@ -99,11 +103,16 @@ const TextStyleMenuList = _ref => {
99
103
  }, [editor, selectedFontSize, selectedFontSizeValue]);
100
104
  const getTextStyleList = (0, _react.useCallback)(key => {
101
105
  return _constants.MENUS_CONFIG_MAP[key].map(item => {
106
+ let disable = isDisabled();
107
+ const disableTypes = [_constants.TEXT_STYLE_MAP.CODE, _constants.TEXT_STYLE_MAP.LINK, _constants.TEXT_STYLE_MAP.SUPERSCRIPT, _constants.TEXT_STYLE_MAP.SUBSCRIPT];
108
+ if (disableTypes.includes(item.type)) {
109
+ disable = isSelectedSeaTableColumn() ? true : disable;
110
+ }
102
111
  let itemProps = {
103
112
  isRichEditor,
104
113
  className,
105
114
  ariaLabel: item === null || item === void 0 ? void 0 : item.ariaLabel,
106
- disabled: isDisabled(),
115
+ disabled: disable,
107
116
  isActive: isActive(item.type),
108
117
  onMouseDown: item.isColor ? () => {} : onMouseDown
109
118
  };
@@ -134,7 +134,8 @@ const isVoidNode = node => {
134
134
  const isCodeBlock = node.type === _constants.CODE_BLOCK;
135
135
  const isCallout = node.type === _constants.CALL_OUT;
136
136
  const isSeaTableTable = node.type === _constants.SEATABLE_TABLE;
137
- return _slate.Node.string(node) === '' && !hasImage && !isVideo && !isTable && !isCodeBlock && !isCallout && !isSeaTableTable;
137
+ const isSeaTableColumn = node.type === _constants.SEATABLE_COLUMN;
138
+ return _slate.Node.string(node) === '' && !hasImage && !isVideo && !isTable && !isCodeBlock && !isCallout && !isSeaTableTable && !isSeaTableColumn;
138
139
  };
139
140
  exports.isVoidNode = isVoidNode;
140
141
  const isNotSupportTransform = node => {
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.default = void 0;
8
+ var _react = _interopRequireDefault(require("react"));
9
+ var _classnames = _interopRequireDefault(require("classnames"));
10
+ const Svg = _ref => {
11
+ let {
12
+ t,
13
+ isSelected,
14
+ imageRef
15
+ } = _ref;
16
+ return /*#__PURE__*/_react.default.createElement("svg", {
17
+ xmlns: "http://www.w3.org/2000/svg",
18
+ viewBox: "0 0 360 360",
19
+ preserveAspectRatio: "xMinYMin meet",
20
+ className: (0, _classnames.default)('sdoc-image-placeholder-wrapper', {
21
+ 'image-selected': isSelected
22
+ }),
23
+ ref: imageRef,
24
+ draggable: false
25
+ }, /*#__PURE__*/_react.default.createElement("rect", {
26
+ width: "100%",
27
+ height: "100%",
28
+ fill: "#f0f0f0"
29
+ }), /*#__PURE__*/_react.default.createElement("g", {
30
+ className: "sdoc-image-content-wrapper",
31
+ transform: "translate(180, 180) scale(1)"
32
+ }, /*#__PURE__*/_react.default.createElement("g", {
33
+ className: "sdoc-image-title",
34
+ transform: "translate(0, 0)"
35
+ }, /*#__PURE__*/_react.default.createElement("foreignObject", {
36
+ x: "-85",
37
+ y: "-16",
38
+ width: "20",
39
+ height: "28"
40
+ }, /*#__PURE__*/_react.default.createElement("div", {
41
+ className: "sdocfont sdoc-exclamation-circle"
42
+ })), /*#__PURE__*/_react.default.createElement("text", {
43
+ className: "sdoc-image-tip-title",
44
+ transform: "translate(-55, 4)",
45
+ fontSize: "20",
46
+ fill: "red",
47
+ fontFamily: "Arial, sans-serif"
48
+ }, t('Image_copy_error'))), /*#__PURE__*/_react.default.createElement("text", {
49
+ className: "sdoc-image-tip-content",
50
+ transform: "translate(0, 35)",
51
+ fontSize: "12",
52
+ textAnchor: "middle",
53
+ fill: "black",
54
+ fontFamily: "Arial, sans-serif"
55
+ }, t('Image_cannot_be_copied_Please_download_the_source_image')), /*#__PURE__*/_react.default.createElement("text", {
56
+ className: "sdoc-image-tip-content",
57
+ transform: "translate(0, 55)",
58
+ fontSize: "12",
59
+ textAnchor: "middle",
60
+ fill: "black",
61
+ fontFamily: "Arial, sans-serif"
62
+ }, t('And_select_insert_-_image_to_upload'))));
63
+ };
64
+ var _default = exports.default = Svg;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seafile/sdoc-editor",
3
- "version": "2.0.0",
3
+ "version": "2.0.2",
4
4
  "private": false,
5
5
  "description": "This is a sdoc editor",
6
6
  "main": "dist/index.js",
@@ -39,7 +39,7 @@
39
39
  "remark-rehype": "11.0.0",
40
40
  "remark-stringify": "11.0.0",
41
41
  "slugid": "3.2.0",
42
- "socket.io-client": "4.6.1",
42
+ "socket.io-client": "4.8.1",
43
43
  "type-of": "2.0.1",
44
44
  "unified": "11.0.3",
45
45
  "url-join": "4.0.1",
@@ -99,6 +99,7 @@
99
99
  "css-minimizer-webpack-plugin": "5.0.1",
100
100
  "dotenv": "^10.0.0",
101
101
  "dotenv-expand": "^5.1.0",
102
+ "dtable-sdk": "5.0.6",
102
103
  "dtable-utils": "5.0.1",
103
104
  "ejs": "3.1.10",
104
105
  "eslint": "^8.3.0",
@@ -119,7 +120,7 @@
119
120
  "koa-router": "7.3.0",
120
121
  "koa-send": "5.0.1",
121
122
  "koa2-cors": "2.0.6",
122
- "lint-staged": "14.0.0",
123
+ "lint-staged": "15.4.3",
123
124
  "mini-css-extract-plugin": "^2.4.5",
124
125
  "node-polyfill-webpack-plugin": "2.0.1",
125
126
  "postcss": "^8.4.31",
@@ -140,7 +141,7 @@
140
141
  "react-router-dom": "7.1.3",
141
142
  "release-it": "17.3.0",
142
143
  "resolve": "^1.20.0",
143
- "resolve-url-loader": "^4.0.0",
144
+ "resolve-url-loader": "5.0.0",
144
145
  "sass-loader": "^12.3.0",
145
146
  "seafile-js": "0.2.235",
146
147
  "source-map-loader": "^3.0.0",
@@ -149,8 +150,8 @@
149
150
  "terser-webpack-plugin": "^5.2.5",
150
151
  "url-loader": "^4.1.1",
151
152
  "web-vitals": "2.1.4",
152
- "webpack": "5.64.4",
153
- "webpack-dev-server": "4.15.1",
153
+ "webpack": "5.98.0",
154
+ "webpack-dev-server": "5.2.0",
154
155
  "webpack-manifest-plugin": "5.0.0",
155
156
  "webpack-merge": "5.8.0",
156
157
  "workbox-webpack-plugin": "7.0.0"
@@ -610,5 +610,8 @@
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.",
616
+ "Image_copy_error": "Image copy error"
614
617
  }
@@ -610,5 +610,8 @@
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.",
616
+ "Image_copy_error": "Image copy error"
614
617
  }
@@ -610,5 +610,9 @@
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.",
616
+ "Image_copy_error": "Image copy error",
617
+ "Image_is_uploading": "Image is uploading..."
614
618
  }
@@ -610,5 +610,8 @@
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.",
616
+ "Image_copy_error": "Image copy error"
614
617
  }
@@ -610,5 +610,8 @@
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.",
616
+ "Image_copy_error": "Image copy error"
614
617
  }
@@ -610,5 +610,8 @@
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.",
616
+ "Image_copy_error": "Image copy error"
614
617
  }
@@ -610,5 +610,8 @@
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.",
616
+ "Image_copy_error": "Image copy error"
614
617
  }
@@ -610,5 +610,8 @@
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.",
616
+ "Image_copy_error": "Image copy error"
614
617
  }
@@ -610,5 +610,8 @@
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": "Изображение не может быть скопировано. Скачайте исходное изображение,",
615
+ "And_select_insert_-_image_to_upload": "и выбрать 「вставить」 - 「изображение」 для загрузки.",
616
+ "Image_copy_error": "Image copy error"
614
617
  }
@@ -610,5 +610,9 @@
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": "后点击工具栏「插入」- 「照片」上传",
616
+ "Image_copy_error": "图片复制错误",
617
+ "Image_is_uploading": "图片正在上传..."
614
618
  }