Slate: "Cannot resolve a Slate point from DOM point" for non-editable text rendered inside of Element

Created on 10 Jan 2020  ยท  5Comments  ยท  Source: ianstormtaylor/slate

Do you want to request a _feature_ or report a _bug_?

Bug

What's the current behavior?

When selecting (supposed to be) non-editable text that is rendered inside of an element, I am seeing an error "Cannot resolve a Slate point from DOM point". My usecase is to have a prefix that isn't editable, but explains the purpose of the block.

Slate: 0.57.1
Browser: Chrome 79.0.3945.117
OS: MacOS 10.15.2 (19C57)

Large GIF (996x358)

Edit React Slate

VM469:1691 Uncaught Error: Cannot resolve a Slate point from DOM point: [object Text],7
    at Object.toSlatePoint (eval at Dr (eval.js:61), <anonymous>:1691:13)
    at Object.toSlateRange (eval at Dr (eval.js:61), <anonymous>:1736:30)
    at HTMLDocument.eval (eval at Dr (eval.js:61), <anonymous>:800:43)
    at later (eval at Dr (eval.js:61), <anonymous>:27:23)
toSlatePoint @ VM469:1691
toSlateRange @ VM469:1736
eval @ VM469:800
later @ VM474:27
setTimeout (async)
later @ VM474:23
setTimeout (async)
later @ VM474:23
setTimeout (async)
later @ VM474:23
setTimeout (async)
debounced @ VM474:38

What's the expected behavior?

To see no error, and have Slate ignore the non-editable text.

discussion

Most helpful comment

This is kind of strange, but I think a hack solution is to use both a CSS style and an HTML attribute.

โœ… For example, this works to render elements:

<div {...attributes}>
  <div
    style={{ userSelect: "none" }}
    contentEditable={false}
  >
    Non-editable
  </div>
  <p>{children}</p>
</div>

๐Ÿ›‘ But oddly, this doesn't work:

<div {...attributes}>
  <div
    contentEditable={false}
  >
    Non-editable
  </div>
  <p>{children}</p>
</div>

๐Ÿ›‘ Nor does this:

<div {...attributes}>
  <div
    style={{ userSelect: "none" }}
  >
    Non-editable
  </div>
  <p>{children}</p>
</div>

I added these examples to the example code sandbox above.

I say this is a "hack solution" because ideally all you would need is contentEditable={false} to avoid this problem. An example usecase for this: you might want to let users select this non-editable text, and userSelect: none CSS prevents that.

NOTE: This does not seem to stop the error from happening when doubleclicking into a child, and selecting all of the text. It seems to sometimes stop it, but not always. This specifically stops the error from happening when selecting or clicking on the non-interactive text specfically.

All 5 comments

This is kind of strange, but I think a hack solution is to use both a CSS style and an HTML attribute.

โœ… For example, this works to render elements:

<div {...attributes}>
  <div
    style={{ userSelect: "none" }}
    contentEditable={false}
  >
    Non-editable
  </div>
  <p>{children}</p>
</div>

๐Ÿ›‘ But oddly, this doesn't work:

<div {...attributes}>
  <div
    contentEditable={false}
  >
    Non-editable
  </div>
  <p>{children}</p>
</div>

๐Ÿ›‘ Nor does this:

<div {...attributes}>
  <div
    style={{ userSelect: "none" }}
  >
    Non-editable
  </div>
  <p>{children}</p>
</div>

I added these examples to the example code sandbox above.

I say this is a "hack solution" because ideally all you would need is contentEditable={false} to avoid this problem. An example usecase for this: you might want to let users select this non-editable text, and userSelect: none CSS prevents that.

NOTE: This does not seem to stop the error from happening when doubleclicking into a child, and selecting all of the text. It seems to sometimes stop it, but not always. This specifically stops the error from happening when selecting or clicking on the non-interactive text specfically.

I am experiencing this problem as well, @charlex thanks for the hack solution for the time being :-)

This has been a long standing behavior of slate. It assumes that elements on the DOM that are children of the editor are either

  1. represented in some way in the in the slate value or
  2. contentEditable=false and userSelect: none.

contentEditable=false does not work by itself because this is the state void nodes have.

Thank you so much @charlex for the workaround!
I've struggled so long with this issue (with slate 0.58.3)! :cold_sweat:

BTW, I find the "Checklist" example (https://github.com/ianstormtaylor/slate/blob/master/site/examples/check-lists.js) misleading on that matter: it works with the <input> element but crashes in the same way as described here with a <select> one. So bad for such a tiny change...

i am encountering similar issues, only while running end to end tests using a headless puppeteer environment, @charlex does this sound similar to what you have there?
I am unable to fix this though, having a hard time figuring out what is wrong

 Cannot resolve a Slate node from DOM node: [object HTMLSpanElement]

      at Object.toSlateNode (http:/localhost:3000/static/js/2.f3428cd3.chunk.js:2:203920)
      at http:/localhost:3000/static/js/2.f3428cd3.chunk.js:2:221289
      at Object.Ve (http:/localhost:3000/static/js/2.f3428cd3.chunk.js:2:1666433)
      at $e (http:/localhost:3000/static/js/2.f3428cd3.chunk.js:2:1666587)
      at http:/localhost:3000/static/js/2.f3428cd3.chunk.js:2:1684794
      at jr (http:/localhost:3000/static/js/2.f3428cd3.chunk.js:2:1684888)
      at kr (http:/localhost:3000/static/js/2.f3428cd3.chunk.js:2:1685303)
      at http:/localhost:3000/static/js/2.f3428cd3.chunk.js:2:1690956
      at De (http:/localhost:3000/static/js/2.f3428cd3.chunk.js:2:1766815)
      at http:/localhost:3000/static/js/2.f3428cd3.chunk.js:2:1686764

Was this page helpful?
0 / 5 - 0 ratings

Related issues

AlexeiAndreev picture AlexeiAndreev  ยท  3Comments

ezakto picture ezakto  ยท  3Comments

ianstormtaylor picture ianstormtaylor  ยท  3Comments

ianstormtaylor picture ianstormtaylor  ยท  3Comments

chriserickson picture chriserickson  ยท  3Comments