From 079c39a7d0ebca72e25f82bec5f480ebcf930a07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Ku=CC=88hn?= Date: Tue, 27 Oct 2020 23:16:45 +0100 Subject: [PATCH] refactor splitblock command --- packages/core/src/extensions/splitBlock.ts | 74 ++++++++++++++-------- 1 file changed, 48 insertions(+), 26 deletions(-) diff --git a/packages/core/src/extensions/splitBlock.ts b/packages/core/src/extensions/splitBlock.ts index b82be5e5..37aaa7da 100644 --- a/packages/core/src/extensions/splitBlock.ts +++ b/packages/core/src/extensions/splitBlock.ts @@ -1,12 +1,8 @@ -// import { -// baseKeymap, chainCommands, newlineInCode, createParagraphNear, liftEmptyBlock, splitBlock, -// } from 'prosemirror-commands' import { canSplit } from 'prosemirror-transform' import { ContentMatch, Fragment } from 'prosemirror-model' import { NodeSelection, TextSelection } from 'prosemirror-state' import { Command } from '../Editor' import { createExtension } from '../Extension' -// import getNodeType from '../utils/getNodeType' function defaultBlockAt(match: ContentMatch) { for (let i = 0; i < match.edgeCount; i + 1) { @@ -20,41 +16,67 @@ function defaultBlockAt(match: ContentMatch) { export const SplitBlock = createExtension({ addCommands() { return { - splitBlock: (copyAttributes = false): Command => ({ state, dispatch }) => { - // const type = getNodeType(typeOrName, state.schema) + splitBlock: (copyAttributes = false): Command => ({ tr, dispatch }) => { + const { selection, doc } = tr + const { $from, $to } = selection + + if (selection instanceof NodeSelection && selection.node.isBlock) { + if (!$from.parentOffset || !canSplit(doc, $from.pos)) { + return false + } + + if (dispatch) { + dispatch(tr.split($from.pos).scrollIntoView()) + } - const { $from, $to } = state.selection - if (state.selection instanceof NodeSelection && state.selection.node.isBlock) { - if (!$from.parentOffset || !canSplit(state.doc, $from.pos)) return false - if (dispatch) dispatch(state.tr.split($from.pos).scrollIntoView()) return true } - if (!$from.parent.isBlock) return false + if (!$from.parent.isBlock) { + return false + } if (dispatch) { const atEnd = $to.parentOffset === $to.parent.content.size - const { tr } = state - if (state.selection instanceof TextSelection) tr.deleteSelection() - const deflt = $from.depth === 0 ? null : defaultBlockAt($from.node(-1).contentMatchAt($from.indexAfter(-1))) - let types = atEnd && deflt ? [{ type: deflt, attrs: copyAttributes ? $from.node().attrs : {} }] : null - // let types = atEnd && deflt ? [{ type: deflt }] : null - // @ts-ignore + + if (selection instanceof TextSelection) { + tr.deleteSelection() + } + + const deflt = $from.depth === 0 + ? undefined + : defaultBlockAt($from.node(-1).contentMatchAt($from.indexAfter(-1))) + + let types = atEnd && deflt + ? [{ type: deflt, attrs: copyAttributes ? $from.node().attrs : {} }] + : undefined + let can = canSplit(tr.doc, tr.mapping.map($from.pos), 1, types) - // @ts-ignore - if (!types && !can && canSplit(tr.doc, tr.mapping.map($from.pos), 1, deflt && [{ type: deflt }])) { - // @ts-ignore - types = [{ type: deflt, attrs: copyAttributes ? $from.node().attrs : {} }] - // types = [{ type: deflt }] + + if ( + !types + && !can + && canSplit(tr.doc, tr.mapping.map($from.pos), 1, deflt ? [{ type: deflt }] : undefined) + ) { can = true + types = deflt + ? [{ type: deflt, attrs: copyAttributes ? $from.node().attrs : {} }] + : undefined } + if (can) { - // @ts-ignore tr.split(tr.mapping.map($from.pos), 1, types) - if (!atEnd && !$from.parentOffset && $from.parent.type !== deflt - // @ts-ignore - && $from.node(-1).canReplace($from.index(-1), $from.indexAfter(-1), Fragment.from(deflt.create(), $from.parent))) { tr.setNodeMarkup(tr.mapping.map($from.before()), deflt) } + + if ( + !atEnd + && !$from.parentOffset + && $from.parent.type !== deflt + && $from.node(-1).canReplace($from.index(-1), $from.indexAfter(-1), Fragment.from(deflt?.create())) + ) { + tr.setNodeMarkup(tr.mapping.map($from.before()), deflt || undefined) + } } + dispatch(tr.scrollIntoView()) }