From 09ddf954a7e6043a825ac599145f2b8e917c9883 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Ku=CC=88hn?= Date: Wed, 4 Nov 2020 17:01:51 +0100 Subject: [PATCH] add withAttributes and withMarks option to splitBlock command --- packages/core/src/CommandManager.ts | 2 +- packages/core/src/extensions/baseKeymap.ts | 4 +- packages/core/src/extensions/splitBlock.ts | 45 ++++++++++++++++++++-- packages/extension-text-align/index.ts | 4 +- 4 files changed, 47 insertions(+), 8 deletions(-) diff --git a/packages/core/src/CommandManager.ts b/packages/core/src/CommandManager.ts index 1e912fc0..824e98fd 100644 --- a/packages/core/src/CommandManager.ts +++ b/packages/core/src/CommandManager.ts @@ -131,7 +131,7 @@ export default class CommandManager { view, state: this.chainableState(tr, state), dispatch: shouldDispatch - ? () => true + ? () => undefined : undefined, chain: () => this.createChain(tr), can: () => this.createCan(tr), diff --git a/packages/core/src/extensions/baseKeymap.ts b/packages/core/src/extensions/baseKeymap.ts index 77f121c1..30d6c9fb 100644 --- a/packages/core/src/extensions/baseKeymap.ts +++ b/packages/core/src/extensions/baseKeymap.ts @@ -29,11 +29,11 @@ export const BaseKeymap = createExtension({ ]) return { - Enter: () => this.editor.try(({ state, dispatch }) => [ + Enter: () => this.editor.try(({ commands, state, dispatch }) => [ () => newlineInCode(state, dispatch), () => createParagraphNear(state, dispatch), () => liftEmptyBlock(state, dispatch), - () => splitBlockKeepMarks(state, dispatch), + () => commands.splitBlock(), ]), 'Mod-Enter': exitCode, Backspace: () => handleBackspace(), diff --git a/packages/core/src/extensions/splitBlock.ts b/packages/core/src/extensions/splitBlock.ts index 98359fd2..ae1f8c5d 100644 --- a/packages/core/src/extensions/splitBlock.ts +++ b/packages/core/src/extensions/splitBlock.ts @@ -1,6 +1,6 @@ import { canSplit } from 'prosemirror-transform' import { ContentMatch, Fragment } from 'prosemirror-model' -import { NodeSelection, TextSelection } from 'prosemirror-state' +import { EditorState, NodeSelection, TextSelection } from 'prosemirror-state' import { Command } from '../Editor' import { createExtension } from '../Extension' @@ -13,10 +13,29 @@ function defaultBlockAt(match: ContentMatch) { return null } +interface SplitBlockOptions { + withAttributes: boolean, + withMarks: boolean, +} + +function keepMarks(state: EditorState) { + const marks = state.storedMarks + || (state.selection.$to.parentOffset && state.selection.$from.marks()) + + if (marks) { + state.tr.ensureMarks(marks) + } +} + export const SplitBlock = createExtension({ addCommands() { return { - splitBlock: (copyAttributes = false): Command => ({ tr, dispatch }) => { + splitBlock: (options: Partial = {}): Command => ({ tr, state, dispatch }) => { + const defaultOptions: SplitBlockOptions = { + withAttributes: false, + withMarks: true, + } + const config = { ...defaultOptions, ...options } const { selection, doc } = tr const { $from, $to } = selection @@ -26,6 +45,10 @@ export const SplitBlock = createExtension({ } if (dispatch) { + if (config.withMarks) { + keepMarks(state) + } + tr.split($from.pos).scrollIntoView() } @@ -48,7 +71,12 @@ export const SplitBlock = createExtension({ : defaultBlockAt($from.node(-1).contentMatchAt($from.indexAfter(-1))) let types = atEnd && deflt - ? [{ type: deflt, attrs: copyAttributes ? $from.node().attrs : {} }] + ? [{ + type: deflt, + attrs: config.withAttributes + ? $from.node().attrs + : {}, + }] : undefined let can = canSplit(tr.doc, tr.mapping.map($from.pos), 1, types) @@ -60,7 +88,12 @@ export const SplitBlock = createExtension({ ) { can = true types = deflt - ? [{ type: deflt, attrs: copyAttributes ? $from.node().attrs : {} }] + ? [{ + type: deflt, + attrs: config.withAttributes + ? $from.node().attrs + : {}, + }] : undefined } @@ -77,6 +110,10 @@ export const SplitBlock = createExtension({ } } + if (config.withMarks) { + keepMarks(state) + } + tr.scrollIntoView() } diff --git a/packages/extension-text-align/index.ts b/packages/extension-text-align/index.ts index 3eaaa5ef..7a6e07ad 100644 --- a/packages/extension-text-align/index.ts +++ b/packages/extension-text-align/index.ts @@ -49,7 +49,9 @@ const TextAlign = createExtension({ // TODO: re-use only 'textAlign' attribute // TODO: use custom splitBlock only for `this.options.types` // TODO: use complete default enter handler (chainCommand) with custom splitBlock - Enter: () => this.editor.splitBlock(true), + Enter: () => this.editor.splitBlock({ + withAttributes: true, + }), } }, })