"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.transformsToList = void 0;
var _slate = require("slate");
var _core = require("../../../core");
var _queries = require("../queries");
var _constant = require("../constant");
var _elementTypes = require("../../../constants/element-types");
var _unwrapList = require("./unwrap-list");
const wrapLineList = (editor, type) => {
  const emptyList = (0, _core.generateElement)(type, {
    childrenOrText: []
  });
  _slate.Transforms.wrapNodes(editor, emptyList);
  const paragraphEntry = (0, _core.getSelectedNodeEntryByType)(editor, _elementTypes.PARAGRAPH);
  if (!paragraphEntry) return;
  const [, paragraphPath] = paragraphEntry;
  const emptyListItem = (0, _core.generateElement)(_elementTypes.LIST_ITEM, {
    childrenOrText: []
  });
  _slate.Transforms.wrapNodes(editor, emptyListItem, {
    at: paragraphPath
  });
};
const wrapRangeList = (editor, type) => {
  const [startPoint, endPoint] = _slate.Range.edges(editor.selection);
  const [commonAncestorNode, commonAncestorPath] = _slate.Node.common(editor, startPoint.path, endPoint.path);

  // If common anchestor is of list,order list, unordered list, list of items,wrap or un wrap it
  if ([..._constant.LIST_TYPES, _elementTypes.LIST_ITEM].includes(commonAncestorNode.type)) {
    // Change to another list type, if select different depth of list,set the shallowest depth to the given type
    if (commonAncestorNode.type !== type) {
      const options = {
        at: startPoint,
        match: {
          type: _constant.LIST_TYPES
        },
        mode: 'lowest'
      };
      const startListEntry = (0, _core.findNode)(editor, options);
      const endListEntry = (0, _core.findNode)(editor, {
        ...options,
        at: endPoint
      });
      const selectDepth = Math.min(startListEntry[1].length, endListEntry[1].length);
      _slate.Transforms.setNodes(editor, {
        type
      }, {
        match: (node, path) => _slate.Element.isElement(node) && _constant.LIST_TYPES.includes(node.type) && path.length >= selectDepth,
        mode: 'all'
      });
    } else {
      (0, _unwrapList.unwrapList)(editor);
    }
    return;
  }
  const commonAncestorDepth = commonAncestorPath.length;
  const selectedNodeEntries = _slate.Editor.nodes(editor, {
    mode: 'all'
  });
  // Filter out all the child node of selected node.
  const nodeEntryList = Array.from(selectedNodeEntries).filter(_ref => {
    let [node, path] = _ref;
    return path.length === commonAncestorDepth + 1;
  });
  nodeEntryList.forEach(_ref2 => {
    let [node, path] = _ref2;
    if (_constant.LIST_TYPES.includes(node.type)) {
      _slate.Transforms.setNodes(editor, {
        type
      }, {
        at: path,
        match: n => _slate.Element.isElement(n) && _elementTypes.LIST_ITEM.includes(n.type),
        mode: 'all'
      });
    } else {
      const emptyListItem = (0, _core.generateElement)(_elementTypes.LIST_ITEM, {
        childrenOrText: []
      });
      _slate.Transforms.wrapNodes(editor, emptyListItem, {
        at: path
      });
      const emptyList = (0, _core.generateElement)(type, {
        childrenOrText: []
      });
      _slate.Transforms.wrapNodes(editor, emptyList, {
        at: path
      });
    }
  });
};

/**
 * @param {object} editor
 * @param {keyof LIST_TYPES} type
 */
const transformsToList = (editor, type) => {
  _slate.Editor.withoutNormalizing(editor, () => {
    const {
      selection
    } = editor;
    if (!selection) return false;
    if (_slate.Range.isCollapsed(selection) || !(0, _core.isRangeAcrossBlocks)(editor)) {
      const res = (0, _queries.getListItemEntry)(editor);
      // Unwrap list if `res` exist which means selected in list,or wrap it
      if (res) {
        const {
          list
        } = res;
        const setListType = (editor, type) => _slate.Transforms.setNodes(editor, {
          type
        }, {
          match: node => _constant.LIST_TYPES.includes((0, _core.getNodeType)(node)),
          mode: 'lowest',
          at: editor.selection
        });
        // Change list type to another, if list type is different from the given type
        list[0].type !== type ? setListType(editor, type) : (0, _unwrapList.unwrapList)(editor);
      } else {
        wrapLineList(editor, type);
      }
      return;
    }
    // Selection is a range
    wrapRangeList(editor, type);
  });
};
exports.transformsToList = transformsToList;