-
-
Notifications
You must be signed in to change notification settings - Fork 626
fix: setSelection not using MultipleNodeSelection
#2125
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
…n` when spanning multiple blocks.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
@blocknote/ariakit
@blocknote/code-block
@blocknote/core
@blocknote/mantine
@blocknote/react
@blocknote/server-util
@blocknote/shadcn
@blocknote/xl-ai
@blocknote/xl-docx-exporter
@blocknote/xl-email-exporter
@blocknote/xl-multi-column
@blocknote/xl-odt-exporter
@blocknote/xl-pdf-exporter
commit: |
| ); | ||
| const $startBlockBeforePos = | ||
| tr.selection instanceof MultipleNodeSelection | ||
| ? tr.selection.$anchor |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
anchor can be different than from, depending on direction, so we need to decide whether we are using $from or $anchor
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good improvement to make
| tr.setSelection( | ||
| CellSelection.create( | ||
| tr.doc, | ||
| firstCellBeforePos, | ||
| lastCellAfterPos - | ||
| tr.doc.resolve(lastCellAfterPos).nodeBefore!.nodeSize, | ||
| ), | ||
| ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should it be a cell selection or a node selection over the table 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer having less special cases for things like tables & columns, so if we can simplify it. Let's do that instead
| if (blockInfo.blockNoteType === "columnList") { | ||
| const firstColumnBeforePos = blockInfo.bnBlock.beforePos + 1; | ||
| const firstBlockBeforePos = firstColumnBeforePos + 1; | ||
| const lastColumnAfterPos = blockInfo.bnBlock.afterPos - 1; | ||
| const lastBlockAfterPos = lastColumnAfterPos - 1; | ||
|
|
||
| tr.setSelection( | ||
| MultipleNodeSelection.create( | ||
| tr.doc, | ||
| firstBlockBeforePos, | ||
| lastBlockAfterPos - | ||
| tr.doc.resolve(lastBlockAfterPos).nodeBefore!.nodeSize, | ||
| ), | ||
| ); | ||
| } | ||
|
|
||
| // Case for when block is a `column`. | ||
| if (blockInfo.blockNoteType === "column") { | ||
| const firstBlockBeforePos = blockInfo.bnBlock.beforePos + 1; | ||
| const lastBlockAfterPos = blockInfo.bnBlock.afterPos - 1; | ||
|
|
||
| // Run recursively as the column may only have one block. | ||
| setSelection( | ||
| tr, | ||
| tr.doc.resolve(firstBlockBeforePos).nodeAfter!.attrs.id, | ||
| tr.doc.resolve(lastBlockAfterPos).nodeBefore!.attrs.id, | ||
| ); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of always searching for the correct position, can we use helpers to get this so we don't have to write out this logic every time.
In this case specifically though, I think we should be using the getNearestBlock APIs so we don't have to care about the specific strcutures. If we ever change this for columns it will be a hell of a refactor & I'd rather things not be special cased everywhere
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hold for refactor
Summary
This PR rewrites
setSelectionto useMultipleNodeSelectionwhen spanning multiple blocks. When the start and end blocks are the same, the entire block content is selected, i.e.:TextSelectionspanning it is used.CellSelectionspanning all cells is used.NodeSelectionspanning theblockContentnode is used.Rationale
Currently,
setSelectionuses aTextSelectionwhen spanning multiple nodes. This can cause issues when the start/end blocks do not have content, as it's not possible to find aTextSelectionthat spans them.Changes
setSelectiongetSelectionfromJSONtoMultipleNodeSelectionmoveBlocksto work with aMultipleNodeSelection."Mod-a"keyboard handler which callssetSelectionon the whole document. The default"Mod-a"shortcut attempts to create aTextSelection, which has the aforementioned issues.Impact
Should not be a breaking change as the BlockNote API is unchanged.
Testing
We already have tests for
getSelection/setSelection. When implementing the changes, I ran them against the tests to ensure they were correct.Screenshots/Video
N/A
Checklist
Additional Notes