ianstormtaylor / slate

A completely customizable framework for building rich text editors. (Currently in beta.)
http://slatejs.org
MIT License
29.69k stars 3.24k forks source link

select some text and readOnly element, and press the delete Slate crash #5435

Open jrs64 opened 1 year ago

jrs64 commented 1 year ago

Description When you select some text and readOnly element, then press the delete key, Slate crashes and displays the following error message:

Failed to execute 'setEnd' on 'Range': There is no child at offset 200.

Recording

https://github.com/ianstormtaylor/slate/assets/44115045/9de2eb7c-083f-44f0-8808-bf35d73bf501

Sandbox https://www.slatejs.org/examples/inlines

Steps To reproduce the behavior:

  1. Select some text and readonly element
  2. Press delete

Expectation Slate should not crash, and delete selector text

Environment

RavenColEvol commented 1 year ago

I would like to take this up.

RavenColEvol commented 1 year ago

@jrs64 what behaviour do we want to achieve over here? do you want the read only component deleted in this case or it should be untouched?

jrs64 commented 1 year ago

@jrs64 what behaviour do we want to achieve over here? do you want the read only component deleted in this case or it should be untouched?

The ideal behavior would be to delete the element, or at least ensure that the page does not crash

RavenColEvol commented 1 year ago

@jrs64 got it thanks I'll work on this and will let you know.

philicious commented 10 months ago

I stumbled over the same error. in my scenario I have a readonly element that sits on top of every editor element and user can click on but its not part of the text.

it can happen that user selects text backwards to the beginning of the element and happens to accidentally move mouse a bit up at the beginning of element and then hits delete and gets a crash.

so I would like the editor to ignore selection of the contentEditable={false} element.

for the time being, I'll try "fixing" the bad selection of the user by hooking set_selection op and verifying there are no readOnly elements in the selection.

philicious commented 10 months ago

@jrs64 I seem to have been able to fix this easily by adding data-slate-void to the readOnly element.

I guess at best one would want to properly define all the void elements and handle their rendering individually so that attribute gets added automatically. (see https://docs.slatejs.org/api/nodes/editor#schema-specific-instance-methods-to-override and https://docs.slatejs.org/api/nodes/element#rendering-void-elements

however in cases where you want to render a void as part of an editable element, it seems to work fine adding that attribute manually.

RavenColEvol commented 10 months ago

Hey I'm unable to work on this issue, if anyone interested can please take this up.

scotthowie-optimove commented 7 months ago

Hey, adding data-slate-void manually didn't work for me. Are there any more workarounds for this issue?

philicious commented 7 months ago

@ScottHowieOptimove hm. still works for me on "slate-react": "^0.101.0". just to be more clear what I did:

const renderElement = ({ attributes, children, element }: RenderElementProps): React.ReactElement => {
switch (element.type) {
...
          return (
            <Container {...attributes}>
              {/* mark manually as void-element to make it behave properly, eg non-selectable */}
              <Box contentEditable={false} data-slate-void>
                 // here are my elements that are not editable but caused crash when part of selection + delete
              </Box>
              {children} 
            </Container>
          )
}
scotthowie-optimove commented 7 months ago

@philicious thanks for the reply. Maybe it's because I'm using an older version of slate. Will try updating. Thanks again!