"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 _helpers = require("./helpers");
var _constant = require("../list/constant");
const getCurrentLineEntry = editor => {
  // blockquote > paragraph
  // blockquote > check_list_item
  // blockquote > list > list_item > paragraph
  const [currentLineEntry] = _slate.Editor.nodes(editor, {
    match: n => _slate.Element.isElement(n) && _slate.Editor.isBlock(editor, n),
    mode: 'lowest'
  });
  if (!currentLineEntry) return null;
  const type = currentLineEntry[0].type;
  if (type === _elementTypes.PARAGRAPH) {
    const parentPath = _slate.Path.parent(currentLineEntry[1]);
    if (parentPath.length === 1) return currentLineEntry; // top level element
    const [listEntry] = _slate.Editor.nodes(editor, {
      match: n => _slate.Element.isElement(n) && _constant.LIST_TYPES.includes(n.type),
      mode: 'highest'
    });
    return listEntry;
  }
  return currentLineEntry;
};
const withBlockquote = editor => {
  const {
    insertBreak,
    deleteBackward,
    insertFragment
  } = editor;
  const newEditor = editor;
  newEditor.insertBreak = () => {
    const {
      selection
    } = editor;
    if (selection == null) return insertBreak();
    const [blockquoteEntry] = _slate.Editor.nodes(editor, {
      match: n => _slate.Element.isElement(n) && n.type === _elementTypes.BLOCKQUOTE,
      universal: true
    });
    if (!blockquoteEntry) return insertBreak();

    // blockquote > paragraph
    // blockquote > check_list_item
    // blockquote > list > list_item
    const currentLineEntry = getCurrentLineEntry(newEditor);
    if (!currentLineEntry) return insertBreak();

    // handle this case by list plugin
    const currentLineType = currentLineEntry[0].type;
    if (_constant.LIST_TYPES.includes(currentLineType) || currentLineType === _elementTypes.CHECK_LIST_ITEM) {
      insertBreak();
      return;
    }
    const isEmptyLine = _slate.Node.string(currentLineEntry[0]).length === 0;
    const isFirst = (0, _core.isFirstChild)(blockquoteEntry, currentLineEntry[1]);
    if (isEmptyLine && isFirst && blockquoteEntry[0].children.length === 1) {
      _slate.Transforms.unwrapNodes(editor, {
        mode: 'highest',
        match: n => _slate.Element.isElement(n) && _slate.Editor.isBlock(editor, n)
      });
      return;
    }
    const isLast = (0, _core.isLastChild)(blockquoteEntry, currentLineEntry[1]);
    if (isEmptyLine && isLast) {
      const nextPath = _slate.Path.next(blockquoteEntry[1]);
      _slate.Transforms.moveNodes(newEditor, {
        at: currentLineEntry[1],
        to: nextPath
      });
      return;
    }

    // In other cases, insert a newline
    _slate.Transforms.insertNodes(newEditor, (0, _core.generateDefaultParagraph)(), {
      at: newEditor.selection,
      select: true
    });
  };
  newEditor.deleteBackward = unit => {
    const {
      selection
    } = newEditor;
    if (selection === null) {
      deleteBackward(unit);
      return;
    }
    const [blockquoteEntry] = _slate.Editor.nodes(editor, {
      match: n => _slate.Element.isElement(n) && n.type === _elementTypes.BLOCKQUOTE,
      universal: true
    });
    if (!blockquoteEntry) return deleteBackward(unit);

    // blockquote > paragraph
    // blockquote > check_list_item
    // blockquote > list > list_item
    const currentLineEntry = getCurrentLineEntry(editor);
    if (!currentLineEntry) return deleteBackward(unit);

    // handle this case by list plugin
    const currentLineType = currentLineEntry[0].type;
    if (_constant.LIST_TYPES.includes(currentLineType) || currentLineType === _elementTypes.CHECK_LIST_ITEM) {
      deleteBackward(unit);
      return;
    }
    const isEmptyLine = _slate.Node.string(currentLineEntry[0]).length === 0;
    const isFirst = (0, _core.isFirstChild)(blockquoteEntry, currentLineEntry[1]);
    if (isEmptyLine && isFirst && blockquoteEntry[0].children.length === 1) {
      (0, _helpers.setBlockQuoteType)(editor, _elementTypes.PARAGRAPH);
      return;
    }
    deleteBackward(unit);
  };
  newEditor.insertFragment = fragment => {
    const {
      selection
    } = editor;
    if (selection == null) return insertFragment(fragment);
    const [blockquoteEntry] = _slate.Editor.nodes(editor, {
      match: n => _slate.Element.isElement(n) && n.type === _elementTypes.BLOCKQUOTE,
      universal: true
    });
    if (!blockquoteEntry) return insertFragment(fragment);
    const firstChild = fragment[0];
    if (fragment.length === 1 && firstChild.type === _elementTypes.TABLE) {
      // const nodeEntry = Editor.nodes(newEditor, { mode: 'highest' });
      const nextPath = _slate.Path.next(blockquoteEntry[1]);
      _slate.Transforms.insertNodes(newEditor, fragment, {
        at: nextPath
      });
      return;
    }
    const insertData = fragment.map(node => {
      if (node.type === _elementTypes.TABLE) {
        const text = _slate.Node.string(node);
        return (0, _core.generateElement)(_elementTypes.PARAGRAPH, {
          childrenOrText: text
        });
      }
      return node;
    });
    return insertFragment(insertData);
  };
  return newEditor;
};
var _default = exports.default = withBlockquote;