UNPKG

@atlaskit/editor-plugin-code-block-advanced

Version:

CodeBlockAdvanced plugin for @atlaskit/editor-core

70 lines (64 loc) 2.12 kB
import type { EditorView as CodeMirror } from '@codemirror/view'; import { RelativeSelectionPos } from '@atlaskit/editor-common/selection'; import type { getPosHandlerNode } from '@atlaskit/editor-common/types'; import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model'; import { Selection } from '@atlaskit/editor-prosemirror/state'; import type { EditorView } from '@atlaskit/editor-prosemirror/view'; interface MaybeEscapeProps { cm: CodeMirror; dir: -1 | 1; getNode: () => PMNode; getPos: getPosHandlerNode; onMaybeNodeSelection: () => void; selectCodeBlockNode: (relativeSelectionPos: RelativeSelectionPos | undefined) => void; unit: 'line' | 'char'; view: EditorView; } export const maybeEscapeKeymap = ({ unit, dir, view, cm, getPos, getNode, onMaybeNodeSelection, selectCodeBlockNode, }: MaybeEscapeProps): boolean => { if (unit === 'char') { onMaybeNodeSelection(); } const node = getNode(); const { state } = cm; let main: { empty: boolean; from: number; head: number; to: number } = state.selection.main; if (!main.empty) { return false; } if (unit === 'line') { main = { ...state.doc.lineAt(main.head), head: 0, empty: false }; } if (dir < 0 ? main.from > 0 : main.to < state.doc.length) { return false; } const targetPos = (getPos?.() ?? 0) + (dir < 0 ? 0 : node.nodeSize); if (unit === 'char') { view.focus(); selectCodeBlockNode(dir === -1 ? RelativeSelectionPos.Start : RelativeSelectionPos.End); return true; } else { createParagraphIfEndOfDoc(view, targetPos); const tr = view.state.tr; const selection = Selection.near(tr.doc.resolve(targetPos), dir); tr.setSelection(selection).scrollIntoView(); view.dispatch(tr); view.focus(); return true; } }; const createParagraphIfEndOfDoc = (view: EditorView, targetPos: number) => { if (targetPos === view.state.doc.content.size) { const paragraph = view.state.schema.nodes.paragraph.createChecked({}); const tr = view.state.tr.insert(targetPos, paragraph); // Note: we purposefully do a multi-dispatch here, otherwise we get stuck in codemirror view.dispatch(tr); } };