"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;
var _slate = require("slate");
var _core = require("../../core");
var _elementTypes = require("../../constants/element-types");
var _constants = require("../../constants");
const isSelectionAtLineEnd = (editor, path) => {
  const {
    selection
  } = editor;
  if (!selection) return false;
  const isAtLineEnd = _slate.Editor.isEnd(editor, selection.anchor, path) || _slate.Editor.isEnd(editor, selection.focus, path);
  return isAtLineEnd;
};
const isSelectionAtLineStart = (editor, path) => {
  const {
    selection
  } = editor;
  if (!selection) return false;
  const isAtLineEnd = _slate.Editor.isStart(editor, selection.anchor, path) || _slate.Editor.isStart(editor, selection.focus, path);
  return isAtLineEnd;
};
const withParagraph = editor => {
  const {
    deleteBackward,
    insertBreak,
    insertFragment
  } = editor;
  const newEditor = editor;
  newEditor.insertBreak = () => {
    if (!newEditor.selection) {
      insertBreak();
      return;
    }
    const [node] = _slate.Editor.nodes(newEditor, {
      mode: 'lowest'
    });
    if (node && node[0].code) {
      const aboveNode = (0, _core.getAboveBlockNode)(newEditor, {
        match: n => _slate.Element.isElement(n),
        mode: 'highest'
      });
      if (isSelectionAtLineStart(editor, node[1]) && _slate.Node.string(node[0]).length !== 0) {
        _slate.Transforms.insertNodes(newEditor, (0, _core.generateDefaultParagraph)(), {
          at: aboveNode[1],
          select: true
        });
        const startPosition = _slate.Editor.start(editor, _slate.Path.next(aboveNode[1]));
        const range = {
          anchor: startPosition,
          focus: startPosition
        };
        (0, _core.focusEditor)(newEditor, range);
        return;
      }
      if (isSelectionAtLineEnd(editor, node[1])) {
        const nextPath = _slate.Path.next(aboveNode[1]);
        _slate.Transforms.insertNodes(newEditor, (0, _core.generateDefaultParagraph)(), {
          at: nextPath,
          select: true
        });
        return;
      }
    }
    insertBreak();
  };
  newEditor.deleteBackward = unit => {
    const {
      selection
    } = newEditor;
    if (!selection) {
      deleteBackward(unit);
      return;
    }
    const selectedParagraphNodeEntry = (0, _core.getSelectedNodeEntryByType)(newEditor, _elementTypes.PARAGRAPH);
    if (selectedParagraphNodeEntry) {
      if (_slate.Node.string(selectedParagraphNodeEntry[0]) === '') {
        const previousNodeEntry = (0, _core.getPrevNode)(newEditor);
        if (previousNodeEntry && previousNodeEntry[0].type === _elementTypes.TABLE_CELL) {
          _slate.Transforms.removeNodes(newEditor, {
            at: selectedParagraphNodeEntry[1]
          });
          return;
        }
      }
    }
    return deleteBackward(unit);
  };
  newEditor.insertFragment = fragment => {
    const match = {
      type: [_elementTypes.PARAGRAPH]
    };
    const [paragraphEntry] = (0, _core.getNodeEntries)(newEditor, {
      match
    });
    if (!paragraphEntry) return insertFragment(fragment);
    const firstChild = fragment[0];
    if (fragment.length === 1 && _constants.LIST_TYPE_ARRAY.includes(firstChild.type)) {
      // insert text
      if (firstChild.children.length === 1) {
        const text = _slate.Node.string(fragment[0]);
        (0, _slate.insertText)(text);
        return;
      }

      // insert list at current path
      if ((0, _core.isSelectionAtBlockStart)(editor)) {
        _slate.Transforms.insertNodes(newEditor, fragment);
        return;
      }

      // insert list at next path
      const nextPath = _slate.Path.next(paragraphEntry[1]);
      _slate.Transforms.insertNodes(newEditor, fragment, {
        at: nextPath
      });
      return;
    }
    if (fragment.length === 1 && firstChild.type === _elementTypes.TABLE) {
      const hasVoidNode = paragraphEntry[0].children.some(item => _slate.Editor.isVoid(newEditor, item));
      if (_slate.Node.string(paragraphEntry[0]).length === 0 && !hasVoidNode) {
        _slate.Transforms.insertNodes(newEditor, fragment, {
          at: paragraphEntry[1]
        });
        return;
      }
      const nextPath = _slate.Path.next(paragraphEntry[1]);
      _slate.Transforms.insertNodes(newEditor, fragment, {
        at: nextPath
      });
      return;
    }
    return insertFragment(fragment);
  };
  return newEditor;
};
var _default = exports.default = withParagraph;