Skip to content

Commit

Permalink
feat(HorizontalRule): improve horizontal line insertion (#218)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
d3m1d0v authored Apr 8, 2024
1 parent fc78baa commit 71813a2
Showing 1 changed file with 26 additions and 3 deletions.
29 changes: 26 additions & 3 deletions src/extensions/markdown/HorizontalRule/index.ts
Original file line number Diff line number Diff line change
@@ -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 {
Expand Down Expand Up @@ -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;
};

Expand Down

0 comments on commit 71813a2

Please sign in to comment.