"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;
var _slate = require("slate");
var _isHotkey = _interopRequireDefault(require("is-hotkey"));
var _core = require("../../core");
var _helper = require("./helper");
var _keyboard = require("../../constants/keyboard");
var _common = require("../../../utils/common");
var _constants = require("../../constants");
var _elementTypes = require("../../constants/element-types");
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 withHeader = editor => {
  const {
    insertBreak,
    insertFragment,
    insertText,
    deleteBackward,
    onHotKeyDown
  } = editor;
  const newEditor = editor;

  // Rewrite insertBreak - insert paragraph when carriage return at the end of header
  newEditor.insertBreak = () => {
    const [match] = _slate.Editor.nodes(newEditor, {
      match: n => {
        if (!_slate.Element.isElement(n)) return false;
        if (n.type.startsWith(_constants.ELementTypes.HEADER)) return true;
        return false;
      },
      // Matches nodes whose node.type starts with header
      universal: true
    });
    if (!match) {
      insertBreak();
      return;
    }
    const isAtLineEnd = isSelectionAtLineEnd(editor, match[1]);
    // If an empty p is inserted at the end of the line, otherwise wrap normally
    if (isAtLineEnd) {
      const p = (0, _core.generateEmptyElement)(_constants.ELementTypes.PARAGRAPH);
      _slate.Transforms.insertNodes(newEditor, p, {
        mode: 'highest'
      });
    } else {
      insertBreak();
    }
  };
  newEditor.deleteBackward = unit => {
    const {
      selection
    } = editor;
    if (!selection) return deleteBackward(unit);
    const [headerEntry] = _slate.Editor.nodes(newEditor, {
      match: n => {
        if (!_slate.Element.isElement(n)) return false;
        if (n.type && n.type.startsWith(_constants.ELementTypes.HEADER)) return true;
        return false;
      },
      // Matches nodes whose node.type starts with header
      universal: true
    });
    if (!headerEntry) {
      deleteBackward(unit);
      return false;
    }
    const isAtLineStart = isSelectionAtLineStart(editor, headerEntry[1]);
    if (isAtLineStart) {
      (0, _helper.setHeaderType)(editor, _constants.ELementTypes.PARAGRAPH);
      return true;
    }
    return deleteBackward(unit);
  };
  newEditor.insertFragment = fragment => {
    const headerEntry = (0, _core.getSelectedNodeEntryByTypes)(editor, _constants.HEADERS);
    if (!headerEntry) return insertFragment(fragment);
    const firstChild = fragment[0];
    if (fragment.length === 1) {
      // is single list item
      if (_constants.LIST_TYPE_ARRAY.includes(firstChild.type)) {
        if (firstChild.children.length === 1) {
          const text = _slate.Node.string(fragment[0]);
          insertText(text);
          return;
        }

        // insert list at current path
        if ((0, _core.isSelectionAtBlockStart)(editor)) {
          _slate.Transforms.insertNodes(newEditor, fragment);
          return;
        }
        const nextPath = _slate.Path.next(headerEntry[1]);
        _slate.Transforms.insertNodes(newEditor, fragment, {
          at: nextPath
        });
        return;
      }
      if (firstChild.type === _elementTypes.TABLE) {
        const nextPath = _slate.Path.next(headerEntry[1]);
        _slate.Transforms.insertNodes(newEditor, fragment, {
          at: nextPath
        });
        return;
      }
    }
    return insertFragment(fragment);
  };
  newEditor.onHotKeyDown = event => {
    const HOT_KEYS = (0, _common.isMac)() ? _keyboard.MAC_HOTKEYS_EVENT_HEADER : _keyboard.WIN_HOTKEYS_EVENT_HEADER;
    const hotEntries = Object.entries(HOT_KEYS);
    let isHeaderEvent = false;
    let headerType = '';
    for (const element of hotEntries) {
      const [key, value] = element;
      isHeaderEvent = (0, _isHotkey.default)(value, event);
      if (isHeaderEvent) {
        headerType = key;
        break;
      }
    }
    if (!isHeaderEvent) {
      return onHotKeyDown && onHotKeyDown(event);
    }
    event.preventDefault();
    if ((0, _helper.isMenuDisabled)(newEditor)) return true;
    const currentHeaderType = (0, _helper.getHeaderType)(editor);
    if (currentHeaderType === headerType) {
      (0, _helper.setHeaderType)(newEditor, _constants.ELementTypes.PARAGRAPH);
    } else {
      (0, _helper.setHeaderType)(newEditor, headerType);
    }
    return true;
  };
  return newEditor;
};
var _default = exports.default = withHeader;