From 71813a294e97fd1e5262da043a4d20dfccf9a8dc Mon Sep 17 00:00:00 2001 From: Yuriy Demidov Date: Mon, 8 Apr 2024 16:08:01 +0300 Subject: [PATCH] feat(HorizontalRule): improve horizontal line insertion (#218) The behavior of inserting horizontal line: - Disabled: - when selecting any text - when cursor inside complex textblock - selection type is some other then TextSelection or NodeSelection - If node selection: replace the selected node with horizontal_rule - If cursor is in an empty paragraph: insert horizontal_rule before current paragraph - If cursor is in another textblock or a non-empty paragraph: insert horizontal_rule and a new empty paragraph after the current textblock --- .../markdown/HorizontalRule/index.ts | 29 +++++++++++++++++-- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/src/extensions/markdown/HorizontalRule/index.ts b/src/extensions/markdown/HorizontalRule/index.ts index 35825826..410556f4 100644 --- a/src/extensions/markdown/HorizontalRule/index.ts +++ b/src/extensions/markdown/HorizontalRule/index.ts @@ -1,9 +1,9 @@ import type {NodeType} from 'prosemirror-model'; -import type {Command, Selection} from 'prosemirror-state'; +import {Command, Selection, TextSelection} from 'prosemirror-state'; import type {Action, ExtensionAuto} from '../../../core'; import {nodeInputRule} from '../../../utils/inputrules'; -import {isNodeSelection} from '../../../utils/selection'; +import {get$Cursor, isNodeSelection} from '../../../utils/selection'; import {pType} from '../../base/BaseSchema/BaseSchemaSpecs'; import { @@ -65,10 +65,33 @@ declare global { const addHr = (hr: NodeType): Command => (state, dispatch) => { - if (!isHrSelection(state.selection)) { + if (isHrSelection(state.selection)) return true; + + if (isNodeSelection(state.selection)) { dispatch?.(state.tr.replaceSelectionWith(hr.create()).scrollIntoView()); + return true; } + const $cursor = get$Cursor(state.selection); + if (!$cursor || $cursor.parent.type.spec.complex) return false; + + if (!dispatch) return true; + + const {tr} = state; + const isEmptyParagraph = + $cursor.parent.type === pType(state.schema) && $cursor.parent.nodeSize === 2; + + if (isEmptyParagraph) { + const pos = $cursor.before(); + tr.insert(pos, hr.create()); + } else { + const pos = $cursor.after(); + tr.insert(pos, [hr.create(), pType(state.schema).create()]); + tr.setSelection(TextSelection.create(tr.doc, pos + 2)); // set cursor to paragraph after hr + } + + dispatch(tr.scrollIntoView()); + return true; };