Closed fEyebrow closed 1 year ago
I suppose you're selecting from the start of the paragraph to the start of the next paragraph? Because if you actually select only the text in the first paragraph than block-level commands will only affect that paragraph.
how do I fix this, this point can feel confusing to the user. When I select from the start of the paragraph to the start of the next paragraph, the next paragraph will not be affected.
I'm thinking of determining if the selection contains the start of the next paragraph before applying the ordered list, and if so, subtracting “to” by 1. However, I don't know how to determine whether the selected "to" only appears at the beginning of the next paragraph.
this is my solution:
const selection = state.tr.selection
if (selection.$to.textOffset === 0 && selection.$to.nodeAfter && dispatch) {
dispatch(state.tr.setSelection(TextSelection.create(
tr.doc,
selection.from,
selection.to - 1)))
}
I apply the above code before the ordered list. the result is right. Is there any problem I haven't considered? @marijnh
Different WYSIWYG editors seem to behave differently in this case. Google Docs and CKEditor consider the block that has the end of the selection right at its start to not be part of the selection for block-command purposes. LibreOffice and Lexical do include it. Both seem reasonable, but since ProseMirror has been using the second approach so far, we can't change existing commands having someone's code break.
The proper approach to do this differently would be to define custom commands for things you want to work this way (such as list and block-type related commands) and have them act on a different selection. Your code looks like it is constantly normalizing the selection, which could get annoying in some circumstances. (Also, you'll definitely want an exception for cursor selections at the start of a block.)
I just showed the core code, which is a bit confusing. Here is the complete code: I created a custom command based on the Tiptap API.
import { Extension } from '@tiptap/core'
import { TextSelection } from 'prosemirror-state'
declare module '@tiptap/core' {
interface Commands<ReturnType> {
correct: {
correctBoundary: () => ReturnType
}
}
}
const CustomExtension = Extension.create({
name: 'corret',
addCommands() {
return {
correctBoundary: () => ({ state, dispatch, tr }) => {
const selection = state.tr.selection
if (selection.$to.textOffset === 0 && selection.$to.nodeAfter && dispatch) {
dispatch(state.tr.setSelection(TextSelection.create(
tr.doc,
selection.from,
selection.to - 1)))
}
return false
},
}
},
})
export default CustomExtension
Here are the use cases:
editor?.chain().correctBoundary().focus().toggleOrderedList().run()
When I selected the entire paragraph and applied the ordered list, the next paragraph was also affected.:
How to avoid this? Sometimes the editor's behavior is right, the next paragraph was not affected.