"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.setSelectionTopLevelBlocks = exports.setGapCursorAtPos = void 0;
var _state = require("@atlaskit/editor-prosemirror/state");
var _selection = require("./selection");
var _Side = require("./Side");
var _isValidTargetNode = require("./utils/is-valid-target-node");
// This function captures clicks outside of the ProseMirror contentEditable area
// see also description of "handleClick" in gap-cursor pm-plugin
var captureCursorCoords = function captureCursorCoords(event, editorRef, posAtCoords, tr) {
  var rect = editorRef.getBoundingClientRect();

  // capture clicks before the first block element
  if (event.clientY < rect.top) {
    return {
      position: 0,
      side: _Side.Side.LEFT
    };
  }
  if (rect.left > 0) {
    // calculate start position of a node that is vertically at the same level
    var coords = posAtCoords({
      left: rect.left,
      top: event.clientY
    });
    if (coords && coords.inside > -1) {
      var $from = tr.doc.resolve(coords.inside);
      var start = $from.before(1);
      var side = event.clientX < rect.left ? _Side.Side.LEFT : _Side.Side.RIGHT;
      var position;
      if (side === _Side.Side.LEFT) {
        position = start;
      } else {
        var node = tr.doc.nodeAt(start);
        if (node) {
          position = start + node.nodeSize;
        }
      }
      return {
        position: position,
        side: side
      };
    }
  }
  return null;
};
var setSelectionTopLevelBlocks = exports.setSelectionTopLevelBlocks = function setSelectionTopLevelBlocks(tr, event, editorRef, posAtCoords, editorFocused) {
  var cursorCoords = captureCursorCoords(event, editorRef, posAtCoords, tr);
  if (!cursorCoords) {
    return;
  }

  // Ignored via go/ees005
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
  var $pos = cursorCoords.position !== undefined ? tr.doc.resolve(cursorCoords.position) : null;
  if ($pos === null) {
    return;
  }
  var isGapCursorAllowed = cursorCoords.side === _Side.Side.LEFT ? (0, _isValidTargetNode.isValidTargetNode)($pos.nodeAfter) : (0, _isValidTargetNode.isValidTargetNode)($pos.nodeBefore);
  if (isGapCursorAllowed && _selection.GapCursorSelection.valid($pos)) {
    // this forces PM to re-render the decoration node if we change the side of the gap cursor, it doesn't do it by default
    if (tr.selection instanceof _selection.GapCursorSelection) {
      tr.setSelection(_state.Selection.near($pos));
    } else {
      tr.setSelection(new _selection.GapCursorSelection($pos, cursorCoords.side));
    }
  }
  // try to set text selection if the editor isnt focused
  // if the editor is focused, we are most likely dragging a selection outside.
  else if (editorFocused === false) {
    var selectionTemp = _state.Selection.findFrom($pos, cursorCoords.side === _Side.Side.LEFT ? 1 : -1, true);
    if (selectionTemp) {
      tr.setSelection(selectionTemp);
    }
  }
};

// eslint-disable-next-line @atlaskit/volt-strict-mode/no-multiple-exports
var setGapCursorAtPos = exports.setGapCursorAtPos = function setGapCursorAtPos(position) {
  var side = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _Side.Side.LEFT;
  return function (state, dispatch) {
    // @see ED-6231
    if (position > state.doc.content.size) {
      return false;
    }
    var $pos = state.doc.resolve(position);
    if (_selection.GapCursorSelection.valid($pos)) {
      if (dispatch) {
        dispatch(state.tr.setSelection(new _selection.GapCursorSelection($pos, side)));
      }
      return true;
    }
    return false;
  };
};