@atlaskit/editor-common
Version:
A package that contains common classes and components for editor and renderer
92 lines (90 loc) • 3.48 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.setSelectionTopLevelBlocks = exports.setGapCursorAtPos = void 0;
var _state = require("@atlaskit/editor-prosemirror/state");
var _selection = require("./selection");
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: _selection.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 ? _selection.Side.LEFT : _selection.Side.RIGHT;
var position;
if (side === _selection.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;
}
var $pos = cursorCoords.position !== undefined ? tr.doc.resolve(cursorCoords.position) : null;
if ($pos === null) {
return;
}
var isGapCursorAllowed = cursorCoords.side === _selection.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 === _selection.Side.LEFT ? 1 : -1, true);
if (selectionTemp) {
tr.setSelection(selectionTemp);
}
}
};
var setGapCursorAtPos = exports.setGapCursorAtPos = function setGapCursorAtPos(position) {
var side = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _selection.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;
};
};