UNPKG

prosemirror-flat-list

Version:
57 lines (48 loc) 1.87 kB
import type { ResolvedPos } from 'prosemirror-model' import { type Command, TextSelection } from 'prosemirror-state' import type { ListAttributes } from '../types' import { atTextblockStart } from '../utils/at-textblock-start' import { isListNode } from '../utils/is-list-node' import { joinTextblocksAround } from './join-textblocks-around' /** * If the selection is empty and at the start of a block, and there is a * collapsed list node right before the cursor, move current block and append it * to the first child of the collapsed list node (i.e. skip the hidden content). * * @public @group Commands */ export const joinCollapsedListBackward: Command = (state, dispatch, view) => { const $cursor = atTextblockStart(state, view) if (!$cursor) return false const $cut = findCutBefore($cursor) if (!$cut) return false const { nodeBefore, nodeAfter } = $cut if ( nodeBefore && nodeAfter && isListNode(nodeBefore) && (nodeBefore.attrs as ListAttributes).collapsed && nodeAfter.isBlock ) { const tr = state.tr const listPos = $cut.pos - nodeBefore.nodeSize tr.delete($cut.pos, $cut.pos + nodeAfter.nodeSize) const insert = listPos + 1 + nodeBefore.child(0).nodeSize tr.insert(insert, nodeAfter) const $insert = tr.doc.resolve(insert) tr.setSelection(TextSelection.near($insert)) if (joinTextblocksAround(tr, $insert, dispatch)) { return true } } return false } // https://github.com/prosemirror/prosemirror-commands/blob/e607d5abda0fcc399462e6452a82450f4118702d/src/commands.ts#L150 function findCutBefore($pos: ResolvedPos): ResolvedPos | null { if (!$pos.parent.type.spec.isolating) for (let i = $pos.depth - 1; i >= 0; i--) { if ($pos.index(i) > 0) return $pos.doc.resolve($pos.before(i + 1)) if ($pos.node(i).type.spec.isolating) break } return null }