Skip to content
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 crash when a void node deletes itself on click #4616

Merged

Conversation

jameshfisher
Copy link
Contributor

Description

Here's a reproduction of the bug that this fixes. Here's what's happening:

  1. A Slate node n is rendered to a DOM element el with an onClick event that deletes n from the Slate document.
  2. el is clicked, the onClick handler runs, and the node n is deleted.
  3. The click event then propagates to this top-level Component.onClick handler, which wants to implement "if the user clicked on a void node, select it".
  4. This Component.onClick wants to know whether we clicked on a void node, so it consults a reverse mapping from DOM elements back to Slate nodes, looking up the clicked DOM element el.
  5. But there is no longer a valid Slate node corresponding to el, because its custom onClick handler has run already, which deleted its own Slate node (and in general, could have arbitrarily changed the Slate document).

This PR fixes the issue by adding some checks that the node is still at that path, before selecting that node.

This PR also adds an 'image delete' feature to the examples. My immediate motivation is to demonstrate the bug that this fixes. But this is also a very common editor feature, and I think it's valuable to show how to achieve it.

Issue
Fixes: #4240

Example

slate-delete-void.mp4

Checks

  • The new code matches the existing patterns and styles.
  • The tests pass with yarn test.
  • The linter passes with yarn lint. (Fix errors with yarn fix.)
  • The relevant examples still work. (Run examples with yarn start.)
  • You've added a changeset if changing functionality. (Add one with yarn changeset add.)

My immediate motivation is to demonstrate the bug that this fixes. But
this is also a very common editor feature, and I think it's valuable
to show how to achieve it.
@changeset-bot
Copy link

changeset-bot bot commented Oct 21, 2021

🦋 Changeset detected

Latest commit: a7cbe9b

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
slate-react Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@jameshfisher
Copy link
Contributor Author

Note: I think an alternative fix could use Editor.pathRef. Create a reference to each void path at render time, then look up the pathRef in the onClick. But I think this would require some kind of scanning through the document at every render, to make a map of Path -> PathRef, which sounds complex and inefficient.

@jameshfisher
Copy link
Contributor Author

(An alternative "fix" would be to remove the feature that selects void nodes when they're clicked. It's not clear to me that this is actually useful, and devs can always add this behavior themselves.)

Copy link
Collaborator

@dylans dylans left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is the simpler option (compared to the other possible options you proposed), so let's go with this and see if it works sufficiently.

@dylans dylans merged commit 77d9f60 into ianstormtaylor:main Oct 24, 2021
@github-actions github-actions bot mentioned this pull request Oct 24, 2021
@jameshfisher jameshfisher deleted the fix-crash-on-self-deleting-void-node branch October 24, 2021 14:58
jameshfisher added a commit to jameshfisher/slate that referenced this pull request Oct 25, 2021
Sorry, I broke this test in ianstormtaylor#4616
by adding a second image to the example!
dylans pushed a commit that referenced this pull request Oct 25, 2021
Sorry, I broke this test in #4616
by adding a second image to the example!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

"Cannot find a descendant at path [0,1] in node" when i try remove inline void element by click on it
2 participants