-
Notifications
You must be signed in to change notification settings - Fork 3.3k
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
Fix delete behaviour when selection ends in void element #3990
Conversation
- Include void node in range - Add delete-void-at-end test - Add delete-void-and-newline-at-end test
@@ -1265,6 +1265,13 @@ export const Editor = { | |||
at: end, | |||
match: n => Editor.isBlock(editor, n), | |||
}) | |||
|
|||
// If last element is a void node, unhang range by including void node in range | |||
if (Editor.isVoid(editor, endBlock[0])) { |
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 am not sure this the best solution. Should we just simply not unhang the range in Transforms.delete
if the selection end is inside a void node? I think maybe we should handle this in Transforms.delete
vs. changing the default behavior of unhangRange
? Let's pair on it.
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 thought there were some path issues before, but I didn't realize that they're handled further down in Transforms.delete
. I've moved the end void node handling to Transforms.delete
so that it now skips unhangRange
. If you think there are still changes that could be made I'm happy to pair. Thanks for the feedback!
- remove end void node handling from Editor.unhangRange
@@ -1274,7 +1275,7 @@ export const Editor = { | |||
at: before, | |||
match: Text.isText, | |||
reverse: true, | |||
voids, | |||
voids: true, |
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 think we might want to leave this as a variable and perhaps change how Transforms.delete
is called in slate-react instead.
const [, end] = Range.edges(at) | ||
const endBlock = Editor.above(editor, { | ||
at: end, | ||
match: n => Editor.isBlock(editor, n), | ||
}) | ||
|
||
if (endBlock && !Editor.isVoid(editor, endBlock[0])) { | ||
at = Editor.unhangRange(editor, at, { voids }) | ||
} |
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 think this might result in another set of bugs that we don't really intend to introduce. What if the endBlock
is a void
but it's not at the end of the document? Then, the void
node would be deleted because the range is not "unuhung". Are there test cases for hanging ranges with voids in the middle of a document? If not, we should likely add a test case(s). And, maybe we consider doing something like the below:
const [, end] = Range.edges(at) | |
const endBlock = Editor.above(editor, { | |
at: end, | |
match: n => Editor.isBlock(editor, n), | |
}) | |
if (endBlock && !Editor.isVoid(editor, endBlock[0])) { | |
at = Editor.unhangRange(editor, at, { voids }) | |
} | |
const [, end] = Range.edges(at) | |
const endDoc = Editor.end(editor, []); | |
if (!Point.equals(end, endDoc)) { | |
at = Editor.unhangRange(editor, at, { voids }) | |
} |
Need to think about this behavior a bit more. The above might not be exactly what we want. We should pair.
Potentially related to this. In next, if the last element is a void element, then you click away, and refocus, the void element gets mouse focus and you can't edit or do anything until you use the arrow keys to navigate away from the void element. |
@lukesmurray what is "next" in reference to? Also, will take a look into this + finish up this fix this weekend, thanks for the comment. |
|
@BrentFarese, I looked into the default voids behavior in The current changes in this PR still fixes all of the issues, so I would appreciate a final review + merge! |
I encountered similar but a little different issues. here is the case: |
/rebase |
There's a slight change in behavior, but we accept it. Also there was a regression in how slate handles void nodes in 0.63, but then it was fixed somewhere between 0.63 and 0.66. See ianstormtaylor/slate#3990
Is this adding or improving a feature or fixing a bug?
Fixing a bug
What's the new behavior?
Using
Cmd+A
->Delete
properly deletes the selection when the last element in the editor is a void element or a void element followed by a newline.Intuitive cursor position after delete (Addressing [#3868])
This fix allows void nodes to be deleted correctly and places the cursor on a newline after deletion.How does this change work?
Previously, when using
Cmd+A
->Delete
, selections ending with a void element had their endpoint at offset: 0 (before the void element), causingEditor.unhangRange
to trigger and omit the last elements when executing delete.Now,
Transforms.delete
checks that the last element is not a void element before callingEditor.unhangRange
. If it is a void element,Editor.unhangRange
is skipped, allowing the selection to be deleted properly.Additionally, voids is passed as true to
Editor.nodes
withinEditor.unhangRange
so that void elements will be iterated through while unhanging. This resolves the issue of buggy deletion on void elements followed by a newline and does not affect selections without void elements.Two new tests were added to address these changes. The output of the test delete-void-and-newline-at-end has an extra
<block/>
than would be expected; this is another small bug that occurs when deleting selections ending in a newline. However, that is an issue that should be addressed in a separate PR.Have you checked that...?
yarn test
.yarn lint
. (Fix errors withyarn fix
.)yarn start
.)Does this fix any issues or need any specific reviewers?
Fixes two sub-issues mentioned in: [#3456]
Fixes: [#4005]
Fixes adjacent issue: [#3868]