import _asyncToGenerator from '@babel/runtime/helpers/esm/asyncToGenerator';
import _classCallCheck from '@babel/runtime/helpers/esm/classCallCheck';
import _createClass from '@babel/runtime/helpers/esm/createClass';
import _defineProperty from '@babel/runtime/helpers/esm/defineProperty';
import _regeneratorRuntime from '@babel/runtime/regenerator';
import { Node } from 'prosemirror-model';
import { TextSelection, Selection } from 'prosemirror-state';
import { safeInsert } from 'prosemirror-utils';
import { c as compose, t as toJSON, d as getEditorValueWithMedia, p as processRawValue } from '../../dist/index-cfb3e237.esm.js';
import _objectSpread from '@babel/runtime/helpers/esm/objectSpread2';
import { traverse } from '@uidu/adf-utils';
import '@uidu/editor-common';
import '@uidu/editor-json-transformer';
import 'prosemirror-commands';
import 'prosemirror-transform';
import '@babel/runtime/helpers/inherits';
import '@babel/runtime/helpers/createSuper';
import 'prosemirror-view';
import '@uidu/editor-common/selection';
import '@uidu/mentions';
import '@uidu/editor-common/utils';
import '@babel/runtime/helpers/typeof';
import '@babel/runtime/helpers/assertThisInitialized';

function removeMarks(node) {
  var newNode = _objectSpread({}, node);
  delete newNode.marks;
  return newNode;
}
function sanitizeNode(json) {
  var sanitizedJSON = traverse(json, {
    text: function text(node) {
      if (!node || !Array.isArray(node.marks)) {
        return node;
      }
      return _objectSpread(_objectSpread({}, node), {}, {
        marks: node.marks.filter(function (mark) {
          return mark.type !== 'typeAheadQuery';
        })
      });
    },
    status: function status(node) {
      if (node.attrs && !!node.attrs.text) {
        return removeMarks(node);
      }
      return false; // empty status
    },

    emoji: removeMarks,
    mention: removeMarks,
    date: removeMarks,
    hardBreak: removeMarks,
    inlineCard: removeMarks
  });
  return sanitizedJSON;
}

var EditorActions = /*#__PURE__*/function () {
  function EditorActions() {
    _classCallCheck(this, EditorActions);
    _defineProperty(this, "editorView", void 0);
    _defineProperty(this, "contentTransformer", void 0);
    _defineProperty(this, "contentEncode", void 0);
    _defineProperty(this, "eventDispatcher", void 0);
    _defineProperty(this, "listeners", []);
  }
  _createClass(EditorActions, [{
    key: "_privateGetEditorView",
    value:
    // This method needs to be public for context based helper components.
    function _privateGetEditorView() {
      return this.editorView;
    }
  }, {
    key: "_privateGetEventDispatcher",
    value: function _privateGetEventDispatcher() {
      return this.eventDispatcher;
    }

    // This method needs to be public for EditorContext component.
  }, {
    key: "_privateRegisterEditor",
    value: function _privateRegisterEditor(editorView, eventDispatcher, contentTransformer) {
      this.contentTransformer = contentTransformer;
      this.eventDispatcher = eventDispatcher;
      if (!this.editorView && editorView) {
        this.editorView = editorView;
        this.listeners.forEach(function (cb) {
          return cb(editorView, eventDispatcher);
        });
      } else if (this.editorView !== editorView) {
        throw new Error("Editor has already been registered! It's not allowed to re-register editor with the new Editor instance.");
      }
      if (this.contentTransformer) {
        this.contentEncode = this.contentTransformer.encode.bind(this.contentTransformer);
      }
    }

    // This method needs to be public for EditorContext component.
  }, {
    key: "_privateUnregisterEditor",
    value: function _privateUnregisterEditor() {
      this.editorView = undefined;
      this.contentTransformer = undefined;
      this.contentEncode = undefined;
      this.eventDispatcher = undefined;
    }
  }, {
    key: "_privateSubscribe",
    value: function _privateSubscribe(cb) {
      // If editor is registered and somebody is trying to add a listener,
      // just call it first.
      if (this.editorView && this.eventDispatcher) {
        cb(this.editorView, this.eventDispatcher);
      }
      this.listeners.push(cb);
    }
  }, {
    key: "_privateUnsubscribe",
    value: function _privateUnsubscribe(cb) {
      this.listeners = this.listeners.filter(function (c) {
        return c !== cb;
      });
    }
  }, {
    key: "focus",
    value: function focus() {
      if (!this.editorView || this.editorView.hasFocus()) {
        return false;
      }
      this.editorView.focus();
      this.editorView.dispatch(this.editorView.state.tr.scrollIntoView());
      return true;
    }
  }, {
    key: "blur",
    value: function blur() {
      if (!this.editorView || !this.editorView.hasFocus()) {
        return false;
      }
      this.editorView.dom.blur();
      return true;
    }
  }, {
    key: "clear",
    value: function clear() {
      if (!this.editorView) {
        return false;
      }
      var editorView = this.editorView;
      var state = editorView.state;
      var tr = editorView.state.tr.setSelection(TextSelection.create(state.doc, 0, state.doc.nodeSize - 2)).deleteSelection();
      editorView.dispatch(tr);
      return true;
    }
  }, {
    key: "getValue",
    value: function () {
      var _getValue = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
        var _this = this;
        var doc;
        return _regeneratorRuntime.wrap(function _callee$(_context) {
          while (1) switch (_context.prev = _context.next) {
            case 0:
              _context.next = 2;
              return getEditorValueWithMedia(this.editorView);
            case 2:
              doc = _context.sent;
              if (doc) {
                _context.next = 5;
                break;
              }
              return _context.abrupt("return");
            case 5:
              return _context.abrupt("return", compose(function (doc) {
                return _this.contentEncode ? _this.contentEncode(Node.fromJSON(_this.editorView.state.schema, doc)) : doc;
              }, sanitizeNode, toJSON)(doc));
            case 6:
            case "end":
              return _context.stop();
          }
        }, _callee, this);
      }));
      function getValue() {
        return _getValue.apply(this, arguments);
      }
      return getValue;
    }()
  }, {
    key: "replaceDocument",
    value: function replaceDocument(rawValue) {
      var shouldScrollToBottom = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
      var shouldAddToHistory = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
      if (!this.editorView || rawValue === undefined || rawValue === null) {
        return false;
      }
      var state = this.editorView.state;
      var schema = state.schema;
      var content = processRawValue(schema, rawValue, undefined, undefined, this.contentTransformer);
      if (!content) {
        return false;
      }

      // In case of replacing a whole document, we only need a content of a top level node e.g. document.
      var tr = state.tr.replaceWith(0, state.doc.nodeSize - 2, content.content);
      if (!shouldScrollToBottom && !tr.selectionSet) {
        // Restore selection at start of document instead of the end.
        tr.setSelection(Selection.atStart(tr.doc));
      }
      if (shouldScrollToBottom) {
        tr = tr.scrollIntoView();
      }
      if (!shouldAddToHistory) {
        tr.setMeta('addToHistory', false);
      }
      this.editorView.dispatch(tr);
      return true;
    }
  }, {
    key: "replaceSelection",
    value: function replaceSelection(rawValue, tryToReplace) {
      if (!this.editorView) {
        return false;
      }
      var state = this.editorView.state;
      if (!rawValue) {
        var tr = state.tr.deleteSelection().scrollIntoView();
        this.editorView.dispatch(tr);
        return true;
      }
      var schema = state.schema;
      var content = processRawValue(schema, rawValue);
      if (!content) {
        return false;
      }

      // try to find a place in the document where to insert a node if its not allowed at the cursor position by schema
      this.editorView.dispatch(safeInsert(content, undefined, tryToReplace)(state.tr).scrollIntoView());
      return true;
    }
  }, {
    key: "appendText",
    value: function appendText(text) {
      if (!this.editorView || !text) {
        return false;
      }
      var state = this.editorView.state;
      var lastChild = state.doc.lastChild;
      if (lastChild && lastChild.type !== state.schema.nodes.paragraph) {
        return false;
      }
      var tr = state.tr.insertText(text).scrollIntoView();
      this.editorView.dispatch(tr);
      return true;
    }
  }], [{
    key: "from",
    value: function from(view, eventDispatcher, transformer) {
      var editorActions = new EditorActions();
      editorActions._privateRegisterEditor(view, eventDispatcher, transformer);
      return editorActions;
    }
  }]);
  return EditorActions;
}();

export { EditorActions as default };
