"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.createInputRule = createInputRule;
exports["default"] = inputRulePlugin;
exports.insertList = void 0;

var _prosemirrorInputrules = require("prosemirror-inputrules");

var _analytics = require("../../../analytics");

var _inputRules = require("../../../utils/input-rules");

var _analytics2 = require("../../analytics");

function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }

function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }

function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }

function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }

function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }

function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }

function createInputRule(regexp, nodeType) {
  return (0, _prosemirrorInputrules.wrappingInputRule)(regexp, nodeType, {}, function (_, node) {
    return node.type === nodeType;
  });
}

var insertList = function insertList(state, listType, listTypeName, start, end) {
  // To ensure that match is done after HardBreak.
  var hardBreak = state.schema.nodes.hardBreak;

  if (state.doc.resolve(start).nodeAfter.type !== hardBreak) {
    return null;
  } // To ensure no nesting is done.


  if (state.doc.resolve(start).depth > 1) {
    return null;
  } // Track event


  _analytics.analyticsService.trackEvent("atlassian.editor.format.list.".concat(listTypeName, ".autoformatting")); // Split at the start of autoformatting and delete formatting characters.


  var tr = state.tr["delete"](start, end).split(start); // If node has more content split at the end of autoformatting.

  var currentNode = tr.doc.nodeAt(start + 1);
  tr.doc.nodesBetween(start, start + currentNode.nodeSize, function (node, pos) {
    if (node.type === hardBreak) {
      tr = tr.split(pos + 1)["delete"](pos, pos + 1);
    }
  }); // Wrap content in list node

  var listItem = state.schema.nodes.listItem;
  var position = tr.doc.resolve(start + 2);
  var range = position.blockRange(position);
  tr = tr.wrap(range, [{
    type: listType
  }, {
    type: listItem
  }]);
  return tr;
};
/**
 * Create input rules for bullet list node
 *
 * @param {Schema} schema
 * @returns {InputRule[]}
 */


exports.insertList = insertList;

function getBulletListInputRules(schema) {
  var ruleWithBulletListAnalytics = (0, _analytics2.ruleWithAnalytics)(function () {
    return {
      action: _analytics2.ACTION.FORMATTED,
      actionSubject: _analytics2.ACTION_SUBJECT.TEXT,
      actionSubjectId: _analytics2.ACTION_SUBJECT_ID.FORMAT_LIST_BULLET,
      eventType: _analytics2.EVENT_TYPE.TRACK,
      attributes: {
        inputMethod: _analytics2.INPUT_METHOD.FORMATTING
      }
    };
  }); // NOTE: we decided to restrict the creation of bullet lists to only "*"x

  var asteriskRule = (0, _inputRules.defaultInputRuleHandler)(createInputRule(/^\s*([\*\-]) $/, schema.nodes.bulletList), true);
  asteriskRule.handler = (0, _analytics.trackAndInvoke)('atlassian.editor.format.list.bullet.autoformatting', asteriskRule.handler);
  var leafNodeAsteriskRule = (0, _inputRules.createInputRule)(new RegExp("".concat(_inputRules.leafNodeReplacementCharacter, "\\s*([\\*\\-]) $")), function (state, _match, start, end) {
    return insertList(state, schema.nodes.bulletList, 'bullet', start, end);
  }, true);
  return [ruleWithBulletListAnalytics(asteriskRule), ruleWithBulletListAnalytics(leafNodeAsteriskRule)];
}
/**
 * Create input rules for strong mark
 *
 * @param {Schema} schema
 * @returns {InputRule[]}
 */


function getOrderedListInputRules(schema) {
  var ruleWithOrderedListAnalytics = (0, _analytics2.ruleWithAnalytics)(function () {
    return {
      action: _analytics2.ACTION.FORMATTED,
      actionSubject: _analytics2.ACTION_SUBJECT.TEXT,
      actionSubjectId: _analytics2.ACTION_SUBJECT_ID.FORMAT_LIST_NUMBER,
      eventType: _analytics2.EVENT_TYPE.TRACK,
      attributes: {
        inputMethod: _analytics2.INPUT_METHOD.FORMATTING
      }
    };
  }); // NOTE: There is a built in input rule for ordered lists in ProseMirror. However, that
  // input rule will allow for a list to start at any given number, which isn't allowed in
  // markdown (where a ordered list will always start on 1). This is a slightly modified
  // version of that input rule.

  var numberOneRule = (0, _inputRules.defaultInputRuleHandler)(createInputRule(/^(1)[\.\)] $/, schema.nodes.orderedList), true);
  numberOneRule.handler = (0, _analytics.trackAndInvoke)('atlassian.editor.format.list.numbered.autoformatting', numberOneRule.handler);
  var leafNodeNumberOneRule = (0, _inputRules.createInputRule)(new RegExp("".concat(_inputRules.leafNodeReplacementCharacter, "(1)[\\.\\)] $")), function (state, _match, start, end) {
    return insertList(state, schema.nodes.orderedList, 'numbered', start, end);
  }, true);
  return [ruleWithOrderedListAnalytics(numberOneRule), ruleWithOrderedListAnalytics(leafNodeNumberOneRule)];
}

function inputRulePlugin(schema) {
  var rules = [];

  if (schema.nodes.bulletList) {
    rules.push.apply(rules, _toConsumableArray(getBulletListInputRules(schema)));
  }

  if (schema.nodes.orderedList) {
    rules.push.apply(rules, _toConsumableArray(getOrderedListInputRules(schema)));
  }

  if (rules.length !== 0) {
    return (0, _prosemirrorInputrules.inputRules)({
      rules: rules
    });
  }

  return;
}