mirror of
https://github.com/ueberdosis/tiptap.git
synced 2025-06-11 11:45:15 +08:00
fix(horizontal-rule): fix insertion behavior (#4898)
This commit is contained in:
parent
ca2a2284f0
commit
33de6fef67
@ -54,4 +54,26 @@ context('/src/Nodes/HorizontalRule/React/', () => {
|
|||||||
cy.get('.tiptap hr').should('exist')
|
cy.get('.tiptap hr').should('exist')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should replace selection correctly', () => {
|
||||||
|
cy.get('.tiptap').then(([{ editor }]) => {
|
||||||
|
editor.commands.setContent('<p>Example Text</p><p>Example Text</p>')
|
||||||
|
|
||||||
|
// From the start of the document to the start of the second textblock.
|
||||||
|
editor.commands.setTextSelection({ from: 0, to: 15 })
|
||||||
|
editor.commands.setHorizontalRule()
|
||||||
|
|
||||||
|
expect(editor.getHTML()).to.eq('<hr><p>Example Text</p>')
|
||||||
|
|
||||||
|
editor.commands.setContent('<p>Example Text</p><p>Example Text</p>')
|
||||||
|
|
||||||
|
// From the end of the first textblock to the start of the second textblock.
|
||||||
|
editor.commands.setTextSelection({ from: 13, to: 15 })
|
||||||
|
editor.commands.setHorizontalRule()
|
||||||
|
|
||||||
|
expect(editor.getHTML()).to.eq(
|
||||||
|
'<p>Example Text</p><hr><p>Example Text</p>',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
@ -63,4 +63,26 @@ context('/src/Nodes/HorizontalRule/Vue/', () => {
|
|||||||
.should('exist')
|
.should('exist')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should replace selection correctly', () => {
|
||||||
|
cy.get('.tiptap').then(([{ editor }]) => {
|
||||||
|
editor.commands.setContent('<p>Example Text</p><p>Example Text</p>')
|
||||||
|
|
||||||
|
// From the start of the document to the start of the second textblock.
|
||||||
|
editor.commands.setTextSelection({ from: 0, to: 15 })
|
||||||
|
editor.commands.setHorizontalRule()
|
||||||
|
|
||||||
|
expect(editor.getHTML()).to.eq('<hr><p>Example Text</p>')
|
||||||
|
|
||||||
|
editor.commands.setContent('<p>Example Text</p><p>Example Text</p>')
|
||||||
|
|
||||||
|
// From the end of the first textblock to the start of the second textblock.
|
||||||
|
editor.commands.setTextSelection({ from: 13, to: 15 })
|
||||||
|
editor.commands.setHorizontalRule()
|
||||||
|
|
||||||
|
expect(editor.getHTML()).to.eq(
|
||||||
|
'<p>Example Text</p><hr><p>Example Text</p>',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
import { mergeAttributes, Node, nodeInputRule } from '@tiptap/core'
|
import {
|
||||||
|
isNodeSelection, mergeAttributes, Node, nodeInputRule,
|
||||||
|
} from '@tiptap/core'
|
||||||
import { NodeSelection, TextSelection } from '@tiptap/pm/state'
|
import { NodeSelection, TextSelection } from '@tiptap/pm/state'
|
||||||
|
|
||||||
export interface HorizontalRuleOptions {
|
export interface HorizontalRuleOptions {
|
||||||
@ -49,12 +51,25 @@ export const HorizontalRule = Node.create<HorizontalRuleOptions>({
|
|||||||
return {
|
return {
|
||||||
setHorizontalRule:
|
setHorizontalRule:
|
||||||
() => ({ chain, state }) => {
|
() => ({ chain, state }) => {
|
||||||
const { $to: $originTo } = state.selection
|
const { selection } = state
|
||||||
|
const { $from: $originFrom, $to: $originTo } = selection
|
||||||
|
|
||||||
const currentChain = chain()
|
const currentChain = chain()
|
||||||
|
|
||||||
if ($originTo.parentOffset === 0) {
|
if ($originFrom.parentOffset === 0) {
|
||||||
currentChain.insertContentAt(Math.max($originTo.pos - 2, 0), { type: this.name })
|
currentChain.insertContentAt(
|
||||||
|
{
|
||||||
|
from: Math.max($originFrom.pos - 1, 0),
|
||||||
|
to: $originTo.pos,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: this.name,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
} else if (isNodeSelection(selection)) {
|
||||||
|
currentChain.insertContentAt($originTo.pos, {
|
||||||
|
type: this.name,
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
currentChain.insertContent({ type: this.name })
|
currentChain.insertContent({ type: this.name })
|
||||||
}
|
}
|
||||||
|
65
tests/cypress/integration/extensions/horizontalRule.spec.ts
Normal file
65
tests/cypress/integration/extensions/horizontalRule.spec.ts
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
import { Editor } from '@tiptap/core'
|
||||||
|
import Document from '@tiptap/extension-document'
|
||||||
|
import HorizontalRule from '@tiptap/extension-horizontal-rule'
|
||||||
|
import Image from '@tiptap/extension-image'
|
||||||
|
import Paragraph from '@tiptap/extension-paragraph'
|
||||||
|
import Text from '@tiptap/extension-text'
|
||||||
|
|
||||||
|
describe('extension-horizontal-rule', () => {
|
||||||
|
const editorElClass = 'tiptap'
|
||||||
|
let editor: Editor | null = null
|
||||||
|
|
||||||
|
const createEditorEl = () => {
|
||||||
|
const editorEl = document.createElement('div')
|
||||||
|
|
||||||
|
editorEl.classList.add(editorElClass)
|
||||||
|
document.body.appendChild(editorEl)
|
||||||
|
|
||||||
|
return editorEl
|
||||||
|
}
|
||||||
|
|
||||||
|
const getEditorEl = () => document.querySelector(`.${editorElClass}`)
|
||||||
|
|
||||||
|
it('should be inserted after block leaf nodes correctly', () => {
|
||||||
|
editor = new Editor({
|
||||||
|
element: createEditorEl(),
|
||||||
|
extensions: [
|
||||||
|
Document,
|
||||||
|
Text,
|
||||||
|
Paragraph,
|
||||||
|
HorizontalRule,
|
||||||
|
Image,
|
||||||
|
],
|
||||||
|
content: {
|
||||||
|
type: 'doc',
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
type: 'image',
|
||||||
|
attrs: {
|
||||||
|
src: 'https://source.unsplash.com/8xznAGy4HcY/800x400',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'paragraph',
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
type: 'text',
|
||||||
|
text: 'Example Text',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
editor.commands.setTextSelection(2)
|
||||||
|
editor.commands.setHorizontalRule()
|
||||||
|
|
||||||
|
expect(editor.getHTML()).to.match(
|
||||||
|
/<img(.*?)><hr><p>Example Text<\/p>/,
|
||||||
|
)
|
||||||
|
|
||||||
|
editor?.destroy()
|
||||||
|
getEditorEl()?.remove()
|
||||||
|
})
|
||||||
|
})
|
Loading…
Reference in New Issue
Block a user