Skip to content

Commit

Permalink
HorizontalRule: fix setHorizontalRule putting cursor at non-text posi…
Browse files Browse the repository at this point in the history
…tions (#4319)

* fix setHorizontalRule putting cursor at non-text positions

* improve selections after inserting horizontalRules
  • Loading branch information
bdbch authored Aug 16, 2023
1 parent 0e65d95 commit dd6d3d3
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 10 deletions.
16 changes: 12 additions & 4 deletions packages/core/src/inputRules/nodeInputRule.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { NodeType } from '@tiptap/pm/model'
import { TextSelection } from '@tiptap/pm/state'
import { NodeSelection, TextSelection } from '@tiptap/pm/state'

import { InputRule, InputRuleFinder } from '../InputRule.js'
import { ExtendedRegExpMatchArray } from '../types.js'
Expand Down Expand Up @@ -52,6 +52,8 @@ export function nodeInputRule(config: {

const newNode = config.type.create(attributes)

const { $to } = tr.selection

if (match[1]) {
const offset = match[0].lastIndexOf(match[1])
let matchStart = start + offset
Expand All @@ -74,18 +76,24 @@ export function nodeInputRule(config: {
}

if (config.blockReplace && config.addExtraNewline) {
const { $to } = tr.selection
const posAfter = $to.end()

if ($to.nodeAfter) {
tr.setSelection(TextSelection.create(tr.doc, $to.pos))
console.log($to.node().type.name)
if ($to.nodeAfter.isTextblock) {
tr.setSelection(TextSelection.create(tr.doc, $to.pos + 1))
} else if ($to.nodeAfter.isBlock) {
tr.setSelection(NodeSelection.create(tr.doc, $to.pos))
} else {
tr.setSelection(TextSelection.create(tr.doc, $to.pos))
}
} else {
// add node after horizontal rule if it’s the end of the document
const node = $to.parent.type.contentMatch.defaultType?.create()

if (node) {
tr.insert(posAfter, node)
tr.setSelection(TextSelection.create(tr.doc, posAfter))
tr.setSelection(TextSelection.create(tr.doc, posAfter + 1))
}
}

Expand Down
27 changes: 21 additions & 6 deletions packages/extension-horizontal-rule/src/horizontal-rule.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { mergeAttributes, Node, nodeInputRule } from '@tiptap/core'
import { TextSelection } from '@tiptap/pm/state'
import { NodeSelection, TextSelection } from '@tiptap/pm/state'

export interface HorizontalRuleOptions {
HTMLAttributes: Record<string, any>
Expand Down Expand Up @@ -38,25 +38,40 @@ export const HorizontalRule = Node.create<HorizontalRuleOptions>({
addCommands() {
return {
setHorizontalRule:
() => ({ chain }) => {
() => ({ chain, state }) => {
const { $to: $originTo } = state.selection

const currentChain = chain()

if ($originTo.parentOffset === 0) {
currentChain.insertContentAt($originTo.pos - 2, { type: this.name })
} else {
currentChain.insertContent({ type: this.name })
}

return (
chain()
.insertContent({ type: this.name })
currentChain
// set cursor after horizontal rule
.command(({ tr, dispatch }) => {
if (dispatch) {
const { $to } = tr.selection
const posAfter = $to.end()

if ($to.nodeAfter) {
tr.setSelection(TextSelection.create(tr.doc, $to.pos))
if ($to.nodeAfter.isTextblock) {
tr.setSelection(TextSelection.create(tr.doc, $to.pos + 1))
} else if ($to.nodeAfter.isBlock) {
tr.setSelection(NodeSelection.create(tr.doc, $to.pos))
} else {
tr.setSelection(TextSelection.create(tr.doc, $to.pos))
}
} else {
// add node after horizontal rule if it’s the end of the document
const node = $to.parent.type.contentMatch.defaultType?.create()

if (node) {
tr.insert(posAfter, node)
tr.setSelection(TextSelection.create(tr.doc, posAfter))
tr.setSelection(TextSelection.create(tr.doc, posAfter + 1))
}
}

Expand Down

0 comments on commit dd6d3d3

Please sign in to comment.