import { TextSelection } from "prosemirror-state"; import { UxCommand } from "../constants"; import { Bias, CartesianAxis, Command, DirString } from "../types"; import { WedgeSelection } from "./WedgeSelection"; /** * Build a command that handles the user intent of moving the cursor in a * particular direction (up / down / left / right) by switching to a wedge * selection if the current selection is at a barrier. */ function arrow(axis: CartesianAxis, bias: Bias): Command { const dirStr: DirString = axis == CartesianAxis.VERTICAL ? (bias == Bias.FORWARD ? "down" : "up") : bias == Bias.FORWARD ? "right" : "left"; return (state, dispatch, view) => { const sel = state.selection; let $start = bias == Bias.FORWARD ? sel.$to : sel.$from; let mustMove = sel.empty; if (sel instanceof TextSelection) { if (view !== undefined && !view.endOfTextblock(dirStr)) { return false; } mustMove = false; $start = state.doc.resolve(bias == Bias.FORWARD ? $start.after() : $start.before()); } const newSelection = WedgeSelection.findFrom($start, bias == Bias.FORWARD ? 1 : -1, undefined, mustMove); if (newSelection == null) { return false; } if (dispatch !== undefined) { dispatch(state.tr.setSelection(newSelection)); } return true; }; } export const tryWedgeUp = arrow(CartesianAxis.VERTICAL, Bias.BACKWARD); export const tryWedgeRight = arrow(CartesianAxis.HORIZONTAL, Bias.FORWARD); export const tryWedgeDown = arrow(CartesianAxis.VERTICAL, Bias.FORWARD); export const tryWedgeLeft = arrow(CartesianAxis.HORIZONTAL, Bias.BACKWARD); export const ux = { [UxCommand.ArrowDown]: tryWedgeDown, [UxCommand.ArrowLeft]: tryWedgeLeft, [UxCommand.ArrowRight]: tryWedgeRight, [UxCommand.ArrowUp]: tryWedgeUp };