@seafile/seafile-editor 3.0.16 → 3.0.18

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.
@@ -23,6 +23,7 @@ var _userLinkClick = _interopRequireDefault(require("../../hooks/user-link-click
23
23
  require("./index.css");
24
24
  const isMacOS = (0, _common.isMac)();
25
25
  const InlineEditor = /*#__PURE__*/(0, _react.forwardRef)((_ref, ref) => {
26
+ var _editor$api;
26
27
  let {
27
28
  enableEdit,
28
29
  autoFocus,
@@ -35,13 +36,14 @@ const InlineEditor = /*#__PURE__*/(0, _react.forwardRef)((_ref, ref) => {
35
36
  isImageUploadOnly,
36
37
  isSupportMultipleFiles,
37
38
  onExpandEditorToggle,
38
- handelEnableEdit
39
+ handelEnableEdit,
40
+ onLinkClick
39
41
  } = _ref;
40
42
  const [slateValue, setSlateValue] = (0, _react.useState)(value);
41
43
  const focusRangeRef = (0, _react.useRef)(null);
42
44
  const editor = (0, _react.useMemo)(() => {
43
- const baseEditor = (0, _extension.inlineEditor)();
44
- return (0, _withPropsEditor.default)(baseEditor, {
45
+ const _editor = (0, _extension.inlineEditor)();
46
+ return (0, _withPropsEditor.default)(_editor, {
45
47
  editorApi,
46
48
  onSave,
47
49
  columns,
@@ -53,7 +55,7 @@ const InlineEditor = /*#__PURE__*/(0, _react.forwardRef)((_ref, ref) => {
53
55
  return new _eventHandler.default(editor);
54
56
  }, [editor]);
55
57
  (0, _useAttachments.default)(editor);
56
- (0, _userLinkClick.default)(editor._id);
58
+ (0, _userLinkClick.default)(editor._id, editor === null || editor === void 0 ? void 0 : (_editor$api = editor.api) === null || _editor$api === void 0 ? void 0 : _editor$api.server, onLinkClick);
57
59
  const decorate = (0, _extension.useHighlight)(editor);
58
60
  const onChange = (0, _react.useCallback)(value => {
59
61
  setSlateValue(value);
@@ -15,9 +15,12 @@ var _eventHandler = _interopRequireDefault(require("../../utils/event-handler"))
15
15
  var _withPropsEditor = _interopRequireDefault(require("./with-props-editor"));
16
16
  var _core = require("../../extension/core");
17
17
  var _common = require("../../utils/common");
18
+ var _useAttachments = _interopRequireDefault(require("../../hooks/use-attachments"));
19
+ var _userLinkClick = _interopRequireDefault(require("../../hooks/user-link-click"));
18
20
  require("./style.css");
19
21
  const isMacOS = (0, _common.isMac)();
20
22
  const SimpleSlateEditor = _ref => {
23
+ var _editor$api;
21
24
  let {
22
25
  value,
23
26
  focusEnd,
@@ -26,17 +29,23 @@ const SimpleSlateEditor = _ref => {
26
29
  columns,
27
30
  onContentChanged,
28
31
  isSupportFormula,
29
- onExpandEditorToggle
32
+ onExpandEditorToggle,
33
+ onLinkClick
30
34
  } = _ref;
31
35
  const [slateValue, setSlateValue] = (0, _react.useState)(value);
32
- const editor = (0, _react.useMemo)(() => (0, _withPropsEditor.default)(_extension.baseEditor, {
33
- editorApi,
34
- onSave,
35
- columns
36
- }), [columns, editorApi, onSave]);
36
+ const editor = (0, _react.useMemo)(() => {
37
+ const _editor = (0, _extension.baseEditor)();
38
+ return (0, _withPropsEditor.default)(_editor, {
39
+ editorApi,
40
+ onSave,
41
+ columns
42
+ });
43
+ }, [columns, editorApi, onSave]);
37
44
  const eventProxy = (0, _react.useMemo)(() => {
38
45
  return new _eventHandler.default(editor);
39
46
  }, [editor]);
47
+ (0, _useAttachments.default)(editor);
48
+ (0, _userLinkClick.default)(editor._id, editor === null || editor === void 0 ? void 0 : (_editor$api = editor.api) === null || _editor$api === void 0 ? void 0 : _editor$api.server, onLinkClick);
40
49
  const decorate = (0, _extension.useHighlight)(editor);
41
50
  const onChange = (0, _react.useCallback)(value => {
42
51
  setSlateValue(value);
@@ -20,9 +20,11 @@ var _useAttachments = _interopRequireDefault(require("../../hooks/use-attachment
20
20
  var _common = require("../../utils/common");
21
21
  var _outline = _interopRequireDefault(require("../../containers/outline"));
22
22
  var _useContainerStyle = _interopRequireDefault(require("../../hooks/use-container-style"));
23
+ var _userLinkClick = _interopRequireDefault(require("../../hooks/user-link-click"));
23
24
  require("./style.css");
24
25
  const isMacOS = (0, _common.isMac)();
25
26
  function SlateEditor(_ref) {
27
+ var _editor$api;
26
28
  let {
27
29
  value,
28
30
  editorApi,
@@ -31,6 +33,7 @@ function SlateEditor(_ref) {
31
33
  isReadonly,
32
34
  isSupportFormula,
33
35
  isSupportInsertSeafileImage,
36
+ onLinkClick,
34
37
  children
35
38
  } = _ref;
36
39
  const scrollRef = (0, _react.useRef)(null);
@@ -38,14 +41,18 @@ function SlateEditor(_ref) {
38
41
  const {
39
42
  containerStyle
40
43
  } = (0, _useContainerStyle.default)(scrollRef);
41
- const editor = (0, _react.useMemo)(() => (0, _withPropsEditor.default)(_extension.baseEditor, {
42
- editorApi,
43
- onSave
44
- }), [editorApi, onSave]);
44
+ const editor = (0, _react.useMemo)(() => {
45
+ const _editor = (0, _extension.baseEditor)();
46
+ return (0, _withPropsEditor.default)(_editor, {
47
+ editorApi,
48
+ onSave
49
+ });
50
+ }, [editorApi, onSave]);
45
51
  const eventProxy = (0, _react.useMemo)(() => {
46
52
  return new _eventHandler.default(editor);
47
53
  }, [editor]);
48
54
  (0, _useAttachments.default)(editor);
55
+ (0, _userLinkClick.default)(editor._id, editor === null || editor === void 0 ? void 0 : (_editor$api = editor.api) === null || _editor$api === void 0 ? void 0 : _editor$api.server, onLinkClick);
49
56
  const decorate = (0, _extension.useHighlight)(editor);
50
57
  const onChange = (0, _react.useCallback)(value => {
51
58
  setSlateValue(value);
@@ -18,6 +18,7 @@ var _useContainerStyle = _interopRequireDefault(require("../../hooks/use-contain
18
18
  require("./style.css");
19
19
  const isMacOS = (0, _common.isMac)();
20
20
  function SlateViewer(_ref) {
21
+ var _window, _window$location;
21
22
  let {
22
23
  value,
23
24
  isShowOutline,
@@ -34,7 +35,7 @@ function SlateViewer(_ref) {
34
35
  }, []);
35
36
  const containerScrollRef = externalScrollRef ? externalScrollRef : scrollRef;
36
37
  const decorate = (0, _extension.useHighlight)(editor);
37
- (0, _userLinkClick.default)(editor._id, onLinkClick);
38
+ (0, _userLinkClick.default)(editor._id, (_window = window) === null || _window === void 0 ? void 0 : (_window$location = _window.location) === null || _window$location === void 0 ? void 0 : _window$location.origin, onLinkClick);
38
39
 
39
40
  // willUnmount
40
41
  (0, _react.useEffect)(() => {
@@ -47,6 +48,9 @@ function SlateViewer(_ref) {
47
48
  };
48
49
  // eslint-disable-next-line react-hooks/exhaustive-deps
49
50
  }, []);
51
+ (0, _react.useEffect)(() => {
52
+ editor.children = value;
53
+ }, [editor, value]);
50
54
  return /*#__PURE__*/_react.default.createElement("div", {
51
55
  className: "sf-slate-viewer-container ".concat(_common.isMobile && 'mobile')
52
56
  }, /*#__PURE__*/_react.default.createElement(_slateReact.Slate, {
@@ -10,14 +10,18 @@ var _slateHistory = require("slate-history");
10
10
  var _slateReact = require("slate-react");
11
11
  var _slugid = require("slugid");
12
12
  var _plugins = _interopRequireDefault(require("./plugins"));
13
- const baseEditor = exports.baseEditor = _plugins.default.reduce((editor, pluginItem) => {
14
- const withPlugin = pluginItem.editorPlugin;
15
- if (withPlugin) {
16
- return withPlugin(editor);
17
- }
13
+ const baseEditor = () => {
14
+ const editor = _plugins.default.reduce((editor, pluginItem) => {
15
+ const withPlugin = pluginItem.editorPlugin;
16
+ if (withPlugin) {
17
+ return withPlugin(editor);
18
+ }
19
+ return editor;
20
+ }, (0, _slateHistory.withHistory)((0, _slateReact.withReact)((0, _slate.createEditor)())));
18
21
  editor._id = (0, _slugid.nice)();
19
22
  return editor;
20
- }, (0, _slateHistory.withHistory)((0, _slateReact.withReact)((0, _slate.createEditor)())));
23
+ };
24
+ exports.baseEditor = baseEditor;
21
25
  const inlineEditor = () => {
22
26
  const editor = _plugins.default.reduce((editor, pluginItem) => {
23
27
  const withPlugin = pluginItem.editorPlugin;
@@ -20,7 +20,8 @@ const renderLink = (_ref, editor) => {
20
20
  let {
21
21
  attributes,
22
22
  children,
23
- element
23
+ element,
24
+ option
24
25
  } = _ref;
25
26
  const [isShowPopover, setIsShowPopover] = (0, _react.useState)(false);
26
27
  const [popoverPosition, setPopoverPosition] = (0, _react.useState)({
@@ -28,6 +29,9 @@ const renderLink = (_ref, editor) => {
28
29
  left: 0
29
30
  });
30
31
  const isReadonly = (0, _slateReact.useReadOnly)();
32
+ const {
33
+ render
34
+ } = option || {};
31
35
 
32
36
  // eslint-disable-next-line react-hooks/exhaustive-deps
33
37
  const isLinkActive = (0, _react.useMemo)(() => (0, _helper.isLinkType)(editor), [editor.selection]);
@@ -71,7 +75,15 @@ const renderLink = (_ref, editor) => {
71
75
  const onHrefClick = (0, _react.useCallback)(e => {
72
76
  e.preventDefault();
73
77
  }, []);
74
- return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("span", Object.assign({
78
+ return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/(0, _react.isValidElement)(render) ? /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/(0, _react.cloneElement)(render, {
79
+ element,
80
+ isShowPopover,
81
+ onLinkClick,
82
+ onHrefClick,
83
+ attributes,
84
+ children,
85
+ editor
86
+ })) : /*#__PURE__*/_react.default.createElement("span", Object.assign({
75
87
  onClick: onLinkClick,
76
88
  "data-url": element.url,
77
89
  className: (0, _classnames.default)('sf-virtual-link', {
@@ -11,7 +11,6 @@ var _reactDom = require("react-dom");
11
11
  var _reactI18next = require("react-i18next");
12
12
  var _eventBus = _interopRequireDefault(require("../../../../utils/event-bus"));
13
13
  var _helper = require("../helper");
14
- var _common = require("../../../../utils/common");
15
14
  var _eventTypes = require("../../../../constants/event-types");
16
15
  var _constants = require("../../../../constants");
17
16
  const LinkPopover = _ref => {
@@ -30,11 +29,11 @@ const LinkPopover = _ref => {
30
29
  onClosePopover();
31
30
  };
32
31
  }, [onClosePopover]);
33
- const onLinkClick = (0, _react.useCallback)(e => {
34
- if (!(0, _common.isUrl)(linkUrl)) {
35
- e.preventDefault();
36
- }
37
- }, [linkUrl]);
32
+ const onLinkClick = (0, _react.useCallback)(event => {
33
+ const eventBus = _eventBus.default.getInstance();
34
+ eventBus.dispatch(_eventTypes.EXTERNAL_EVENTS.ON_LINK_CLICK, event, editor._id);
35
+ onClosePopover();
36
+ }, [editor, onClosePopover]);
38
37
  const onUnwrapLink = (0, _react.useCallback)(e => {
39
38
  e.stopPropagation();
40
39
  (0, _helper.unWrapLinkNode)(editor);
@@ -61,11 +60,9 @@ const LinkPopover = _ref => {
61
60
  id: "link-op-menu",
62
61
  className: "sf-link-op-menu",
63
62
  style: popoverPosition
64
- }, /*#__PURE__*/_react.default.createElement("a", {
65
- href: linkUrl,
63
+ }, /*#__PURE__*/_react.default.createElement("span", {
64
+ "data-url": linkUrl,
66
65
  onClick: onLinkClick,
67
- target: "_blank",
68
- rel: "noopener noreferrer",
69
66
  className: "sf-link-op-menu-link"
70
67
  }, t('Open_link')), /*#__PURE__*/_react.default.createElement("div", {
71
68
  className: "sf-link-op-icons d-flex "
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
+ var _common = require("../utils/common");
7
8
  const {
8
9
  useEffect
9
10
  } = require('react');
@@ -13,7 +14,7 @@ const {
13
14
  const {
14
15
  default: EventBus
15
16
  } = require('../utils/event-bus');
16
- const useLinkClick = (editorId, callback) => {
17
+ const useLinkClick = (editorId, server, callback) => {
17
18
  useEffect(() => {
18
19
  function onLinkClick(event, sourceEditorId) {
19
20
  event.preventDefault();
@@ -26,15 +27,26 @@ const useLinkClick = (editorId, callback) => {
26
27
  if (!target) return;
27
28
  link = target.dataset.url;
28
29
  if (editorId !== sourceEditorId) return;
30
+ let isValid = true;
31
+ if (!(0, _common.isUrl)(link)) {
32
+ isValid = false;
33
+ if (link.startsWith('/') && (0, _common.isUrl)(server + link)) {
34
+ isValid = true;
35
+ }
36
+ if (!link.startsWith('/') && (link.startsWith('mailto:') || link.startsWith('tel:'))) {
37
+ isValid = true;
38
+ }
39
+ }
40
+ if (!isValid) return;
29
41
  if (callback) {
30
42
  callback(link);
31
- } else {
32
- window.open(link);
43
+ return;
33
44
  }
45
+ window.open(link);
34
46
  }
35
47
  const eventBus = EventBus.getInstance();
36
48
  const unsubscribe = eventBus.subscribe(EXTERNAL_EVENTS.ON_LINK_CLICK, onLinkClick);
37
49
  return unsubscribe;
38
- }, [editorId, callback]);
50
+ }, [editorId, server, callback]);
39
51
  };
40
52
  var _default = exports.default = useLinkClick;
@@ -30,7 +30,8 @@ function LongTextEditorDialog(_ref) {
30
30
  editorApi,
31
31
  onSaveEditorValue,
32
32
  onEditorValueChanged,
33
- onCloseEditorDialog
33
+ onCloseEditorDialog,
34
+ onLinkClick
34
35
  } = _ref;
35
36
  const editorRef = (0, _react.useRef)(null);
36
37
  const [isValueChanged, setValueChanged] = (0, _react.useState)(false);
@@ -178,7 +179,8 @@ function LongTextEditorDialog(_ref) {
178
179
  focusEnd: focusEnd,
179
180
  editorApi: editorApi,
180
181
  mathJaxSource: mathJaxSource,
181
- onContentChanged: onContentChanged
182
+ onContentChanged: onContentChanged,
183
+ onLinkClick: onLinkClick
182
184
  }), (readOnly || isWindowsWechat) && /*#__PURE__*/_react.default.createElement(_markdownPreview.default, {
183
185
  isWindowsWechat: isWindowsWechat,
184
186
  value: value,
@@ -23,6 +23,7 @@ const SimpleEditor = /*#__PURE__*/(0, _react.forwardRef)((_ref, ref) => {
23
23
  isSupportInsertSeafileImage,
24
24
  onSave: propsOnSave,
25
25
  onContentChanged: propsOnContentChanged,
26
+ onLinkClick,
26
27
  children
27
28
  } = _ref;
28
29
  const [richValue, setRichValue] = (0, _react.useState)([]);
@@ -61,6 +62,7 @@ const SimpleEditor = /*#__PURE__*/(0, _react.forwardRef)((_ref, ref) => {
61
62
  editorApi: editorApi,
62
63
  onSave: propsOnSave,
63
64
  onContentChanged: onContentChanged,
65
+ onLinkClick,
64
66
  children: children
65
67
  };
66
68
  if (isFetching || isLoading || isLoadingMathJax) {
@@ -31,6 +31,7 @@ var _slateViewer = _interopRequireDefault(require("../editors/slate-viewer"));
31
31
  function MarkdownViewer(_ref) {
32
32
  let {
33
33
  isFetching,
34
+ isShowLoading = true,
34
35
  value,
35
36
  mathJaxSource,
36
37
  isShowOutline,
@@ -40,22 +41,26 @@ function MarkdownViewer(_ref) {
40
41
  options
41
42
  } = _ref;
42
43
  const [richValue, setRichValue] = (0, _react.useState)([]);
43
- const [isLoading, setIsLoading] = (0, _react.useState)(true);
44
+ const [isLoading, setIsLoading] = (0, _react.useState)(Boolean(isShowLoading));
44
45
  const {
45
46
  isLoadingMathJax
46
47
  } = (0, _useMathjax.default)(mathJaxSource);
47
48
  (0, _react.useEffect)(() => {
48
49
  if (!isFetching) {
49
- setIsLoading(true);
50
+ if (isShowLoading) {
51
+ setIsLoading(true);
52
+ }
50
53
  const richValue = (0, _slateConvert.mdStringToSlate)(value);
51
54
  beforeRenderCallback && beforeRenderCallback(richValue);
52
55
  setRichValue(richValue);
53
- setTimeout(() => {
54
- setIsLoading(false);
55
- }, 0);
56
+ if (isShowLoading) {
57
+ setTimeout(() => {
58
+ setIsLoading(false);
59
+ }, 0);
60
+ }
56
61
  }
57
62
  // eslint-disable-next-line react-hooks/exhaustive-deps
58
- }, [isFetching, value]);
63
+ }, [isFetching, value, isShowLoading]);
59
64
  const props = {
60
65
  options,
61
66
  isSupportFormula: !!mathJaxSource,
@@ -64,7 +69,7 @@ function MarkdownViewer(_ref) {
64
69
  scrollRef: scrollRef,
65
70
  onLinkClick: onLinkClick
66
71
  };
67
- if (isFetching || isLoading || isLoadingMathJax) {
72
+ if (isShowLoading && (isFetching || isLoading || isLoadingMathJax)) {
68
73
  const loadingOption = (options === null || options === void 0 ? void 0 : options.loading) || {};
69
74
  const {
70
75
  render
@@ -99,10 +99,13 @@ const applyMarkForInlineItem = function (result, item) {
99
99
  textNode['referenceType'] = item.referenceType;
100
100
  textNode['label'] = (_item$children$ = item.children[0]) === null || _item$children$ === void 0 ? void 0 : _item$children$.value;
101
101
  textNode['children'] = [{
102
- id: textNode.id,
102
+ id: _slugid.default.nice(),
103
103
  text: ''
104
104
  }];
105
105
  result.push((0, _objectSpread2.default)({}, textNode));
106
+
107
+ // reset testNode
108
+ textNode = {};
106
109
  return;
107
110
  }
108
111
  const attr_key = INLINE_KEY_MAP[type];
@@ -116,7 +119,7 @@ const applyMarkForInlineItem = function (result, item) {
116
119
  }
117
120
  textNode[attr_key] = true;
118
121
  children.forEach(item => {
119
- applyMarkForInlineItem(result, item, textNode);
122
+ applyMarkForInlineItem(result, item, (0, _objectSpread2.default)({}, textNode));
120
123
  });
121
124
  };
122
125
  const transformNodeWithInlineChildren = node => {
@@ -158,10 +161,17 @@ const transformBlockquote = node => {
158
161
  return {
159
162
  id: _slugid.default.nice(),
160
163
  type: _elementTypes.BLOCKQUOTE,
161
- children: children.map(child => {
164
+ children: Array.isArray(children) && children.length > 0 ? children.map(child => {
162
165
  const handler = elementHandlers[child.type];
163
- return handler(child);
164
- }).flat() // flat
166
+ return handler(child); // flat
167
+ }).flat() : [{
168
+ id: _slugid.default.nice(),
169
+ type: _elementTypes.PARAGRAPH,
170
+ children: [{
171
+ id: _slugid.default.nice(),
172
+ text: ''
173
+ }]
174
+ }]
165
175
  };
166
176
  };
167
177
  exports.transformBlockquote = transformBlockquote;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seafile/seafile-editor",
3
- "version": "3.0.16",
3
+ "version": "3.0.18",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -30,14 +30,14 @@
30
30
  "@babel/plugin-transform-class-properties": "7.23.3",
31
31
  "@babel/plugin-transform-private-methods": "7.23.3",
32
32
  "@babel/runtime": "7.26.10",
33
- "axios": "^1.13.2",
33
+ "axios": "^1.13.6",
34
34
  "babel-jest": "29.7.0",
35
35
  "babel-loader": "9.1.3",
36
36
  "babel-plugin-import": "^1.13.6",
37
37
  "babel-preset-react-app": "^10.0.1",
38
38
  "clean-webpack-plugin": "4.0.0",
39
39
  "css-loader": "6.8.1",
40
- "css-minimizer-webpack-plugin": "5.0.1",
40
+ "css-minimizer-webpack-plugin": "8.0.0",
41
41
  "ejs": "3.1.10",
42
42
  "eslint": "8.49.0",
43
43
  "eslint-config-react-app": "7.0.1",
@@ -48,7 +48,7 @@
48
48
  "ignore-loader": "0.1.2",
49
49
  "jest": "29.7.0",
50
50
  "jest-environment-jsdom": "29.7.0",
51
- "koa": "2.16.1",
51
+ "koa": "2.16.4",
52
52
  "koa-router": "7.3.0",
53
53
  "koa-send": "5.0.1",
54
54
  "koa2-cors": "2.0.6",
@@ -62,13 +62,13 @@
62
62
  "react": "18.3.1",
63
63
  "react-dom": "18.3.1",
64
64
  "react-i18next": "12.1.4",
65
- "react-router": "6.16.0",
66
- "react-router-dom": "6.16.0",
65
+ "react-router": "7.13.1",
66
+ "react-router-dom": "7.13.1",
67
67
  "seafile-js": "0.2.238",
68
68
  "style-loader": "3.3.3",
69
- "terser-webpack-plugin": "5.3.9",
69
+ "terser-webpack-plugin": "5.4.0",
70
70
  "url-loader": "4.1.1",
71
- "webpack": "5.98.0",
71
+ "webpack": "5.105.4",
72
72
  "webpack-dev-server": "5.2.2",
73
73
  "webpack-merge": "5.9.0"
74
74
  },