"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;
var _react = _interopRequireWildcard(require("react"));
var _slateReact = require("slate-react");
var _slate = require("slate");
var _slugid = _interopRequireDefault(require("slugid"));
var _extension = require("../../extension");
var _eventBus = _interopRequireDefault(require("../../utils/event-bus"));
var _eventHandler = _interopRequireDefault(require("../../utils/event-handler"));
var _withPropsEditor = _interopRequireDefault(require("./with-props-editor"));
var _core = require("../../extension/core");
var _common = require("../../utils/common");
var _eventTypes = require("../../constants/event-types");
var _elementTypes = require("../../extension/constants/element-types");
var _useAttachments = _interopRequireDefault(require("../../hooks/use-attachments"));
var _userLinkClick = _interopRequireDefault(require("../../hooks/user-link-click"));
require("./index.css");
const isMacOS = (0, _common.isMac)();
const InlineEditor = /*#__PURE__*/(0, _react.forwardRef)((_ref, ref) => {
  var _editor$api;
  let {
    enableEdit,
    autoFocus,
    value,
    editorApi,
    onSave,
    columns,
    onContentChanged,
    isSupportFormula,
    isImageUploadOnly,
    isSupportMultipleFiles,
    onExpandEditorToggle,
    handelEnableEdit,
    onLinkClick
  } = _ref;
  const [slateValue, setSlateValue] = (0, _react.useState)(value);
  const focusRangeRef = (0, _react.useRef)(null);
  const editor = (0, _react.useMemo)(() => {
    const _editor = (0, _extension.inlineEditor)();
    return (0, _withPropsEditor.default)(_editor, {
      editorApi,
      onSave,
      columns,
      isSupportMultipleFiles,
      isImageUploadOnly
    });
  }, [columns, isImageUploadOnly, isSupportMultipleFiles, editorApi, onSave]);
  const eventProxy = (0, _react.useMemo)(() => {
    return new _eventHandler.default(editor);
  }, [editor]);
  (0, _useAttachments.default)(editor);
  (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);
  const decorate = (0, _extension.useHighlight)(editor);
  const onChange = (0, _react.useCallback)(value => {
    setSlateValue(value);
    if (!editor.hasMovedSelection && editor.selection && _slate.Range.isCollapsed(editor.selection)) {
      const isAtStart = _slate.Editor.isStart(editor, editor.selection.anchor, _slate.Editor.start(editor, []));
      if (!isAtStart) editor.hasMovedSelection = true;
    }
    if (editor.forceNormalize) return;
    const operations = editor.operations;
    const modifyOps = operations.filter(o => o.type !== 'set_selection');
    if (modifyOps.length > 0) {
      onContentChanged && onContentChanged(value);
    }
    const eventBus = _eventBus.default.getInstance();
    eventBus.dispatch('change');
  }, [editor, onContentChanged]);
  const focusNode = (0, _react.useCallback)((editor, focusRange) => {
    const [firstNode] = editor.children;
    if (!firstNode) return;
    if (focusRange && focusRange !== null && focusRange !== void 0 && focusRange.anchor) {
      const startOfFirstNode = _slate.Editor.start(editor, focusRange.anchor.path);
      const range = {
        anchor: startOfFirstNode,
        focus: startOfFirstNode
      };
      (0, _core.focusEditor)(editor, range);
      setTimeout(() => (0, _core.focusEditor)(editor, focusRange), 0);
      focusRangeRef.current = null;
      return;
    }
    const [firstNodeFirstChild] = firstNode.children;
    if (firstNodeFirstChild) {
      const startOfFirstNode = _slate.Editor.start(editor, [0, 0]);
      const range = {
        anchor: startOfFirstNode,
        focus: startOfFirstNode
      };
      (0, _core.focusEditor)(editor, range);
    }
  }, []);

  // useMount: focus editor
  (0, _react.useEffect)(() => {
    editor.forceNormalize = true;
    _slate.Editor.normalize(editor, {
      force: true
    });
    const timer = setTimeout(() => {
      editor.forceNormalize = false;
      if (!enableEdit) return;
      if (!autoFocus) return;
      focusNode(editor);
    }, 300);
    return () => {
      editor.forceNormalize = false;
      clearTimeout(timer);
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);
  (0, _react.useEffect)(() => {
    if (!enableEdit) {
      editor.hasMovedSelection = false;
      return;
    }
    if (!autoFocus) return;
    focusNode(editor, focusRangeRef.current);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [enableEdit]);

  // willUnmount
  (0, _react.useEffect)(() => {
    return () => {
      editor.selection = null;
      editor.history = {
        redos: [],
        undos: []
      };
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);
  const handleClear = (0, _react.useCallback)(targetEditor => {
    if (targetEditor._id !== editor._id) return;
    editor.children = [{
      type: _elementTypes.PARAGRAPH,
      id: _slugid.default.nice(),
      children: [{
        id: _slugid.default.nice(),
        text: ''
      }]
    }];
    editor.selection = null;
    editor.operations = [{
      type: 'remove_text',
      path: [0, 0],
      offset: 0,
      text: ''
    }];
    editor.onChange();
    editor.operations = [];
    editor.history = {
      redos: [],
      undos: []
    };
  }, [editor]);
  (0, _react.useEffect)(() => {
    const eventBus = _eventBus.default.getInstance();
    const clearSubscribe = eventBus.subscribe(_eventTypes.EXTERNAL_EVENTS.CLEAR_ARTICLE, handleClear);
    return () => {
      clearSubscribe();
    };
  }, [handleClear]);
  (0, _react.useImperativeHandle)(ref, () => {
    return {
      getEditor: () => editor
    };
  }, [editor]);
  const onEditorClick = (0, _react.useCallback)(() => {
    if (!enableEdit) {
      focusRangeRef.current = editor.selection;
      handelEnableEdit();
      return;
    }

    // Focus at start of document, when document is empty
    const isDoEmpty = (0, _common.isDocumentEmpty)(editor);
    if (isDoEmpty) {
      focusNode(editor);
    }
  }, [enableEdit, editor, focusNode, handelEnableEdit]);
  return /*#__PURE__*/_react.default.createElement("div", {
    className: "sf-simple-slate-editor-container"
  }, enableEdit && /*#__PURE__*/_react.default.createElement(_extension.InlineToolbar, {
    editor: editor,
    isSupportFormula: isSupportFormula,
    isSupportColumn: !!columns,
    onExpandEditorToggle: onExpandEditorToggle
  }), /*#__PURE__*/_react.default.createElement("div", {
    className: "sf-slate-editor-content",
    onClick: onEditorClick
  }, /*#__PURE__*/_react.default.createElement(_slateReact.Slate, {
    editor: editor,
    initialValue: slateValue,
    onChange: onChange
  }, /*#__PURE__*/_react.default.createElement("div", {
    className: "sf-slate-scroll-container ".concat(isMacOS ? '' : 'isWin')
  }, /*#__PURE__*/_react.default.createElement("div", {
    className: "sf-slate-article-container"
  }, /*#__PURE__*/_react.default.createElement("div", {
    className: "article"
  }, /*#__PURE__*/_react.default.createElement(_extension.SetNodeToDecorations, null), /*#__PURE__*/_react.default.createElement(_slateReact.Editable, {
    readOnly: !enableEdit,
    decorate: decorate,
    renderElement: _extension.renderElement,
    renderLeaf: _extension.renderLeaf,
    onKeyDown: eventProxy.onKeyDown,
    onCopy: eventProxy.onCopy
  })))))));
});
var _default = exports.default = InlineEditor;