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

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

Closed
hcharley opened this issue Jan 10, 2020 · 19 comments · Fixed by #5388
Closed

Comments

@hcharley
Copy link

hcharley commented Jan 10, 2020

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.

@hcharley hcharley changed the title Cannot resolve a Slate point from DOM point "Cannot resolve a Slate point from DOM point" for non-editable text rendered inside of Element Jan 10, 2020
@hcharley
Copy link
Author

hcharley commented Jan 11, 2020

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.

@lionel-lints
Copy link
Contributor

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

@cameracker
Copy link
Collaborator

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.

@joffreyvillard
Copy link

joffreyvillard commented Jul 3, 2020

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

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...

@vamshikilari
Copy link

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

@gorpher
Copy link

gorpher commented Jan 16, 2021

it's useful.

@juliankrispel
Copy link
Collaborator

I find this happens if you're rendering (and then interacting) with an element that doesn't have slate's data attributes, which get passed in renderLeaf or renderNode btw.

for example:

renderLeaf={props => <span>{props.children}</span>}

will cause this problem. To fix it you do this:

renderLeaf={props => <span {...props.attributes}>{props.children}</span>}

There are occasions when you want to render content that you don't want to be part of slates content, but appear alongside it. In this case you just add `contentEditable={false} to that element. For example

renderLeaf={props => <span {...props.attributes}><i contentEditable={false}>👍</i>{props.children}</span>}

If an element will have contentEditable set to false, slate will not try to get the selected range when you click on it, hence the error will not occur. Hope that helps others.

Probably would be good to throw a better error cc @ianstormtaylor

@hcharley
Copy link
Author

@juliankrispel thank you for providing that context.

@DraGonM
Copy link

DraGonM commented Jun 23, 2021

If someone like me getting this error when using some interactive non-slate-elements inside slate-element (it was td in my case), even with contentEditable={false} and userSelect: "none", you must check that your nearest slate-element not wrapped in styled-components (maybe it also the case for some other wrappers)

Because toSlateNode method was trying to find the nearest slate-element to the clicked non-slate-element, it was searching weakmap ELEMENT_TO_NODE by <td class="your random styled class" ...>, but in ELEMENT_TO_NODE this element was actually StyledComponent wrapper.
image
image

I don't get this error anymore, after I removed styled-wrapper and started using style prop for td slate-element, I hope it helps someone.

@deepaksisodiya
Copy link

deepaksisodiya commented Jul 7, 2021

@juliankrispel Thank you for providing the solution. contentEditable={false} work for me

@jamestowers
Copy link

jamestowers commented Jul 23, 2021

I have found that wrapping children in a span and adding attributes to the span as opposed to the Styled Component solves @DraGonM 's issue above:

// bad
<XLargeText as="h2" {...attributes}> // Styled Component
  {children}
</XLargeText>

// good
<XLargeText as="h2"> // Styled Component
  <span {...attributes}>{children}</span>
</XLargeText>

@Darginec05
Copy link

If you have empty initial state remove autoFocus prop in <Editable /> component

@dark-swordsman
Copy link

I ran into this problem when rendering nothing in the slate component, since the introduction tutorial starts off with nothing in the useState([]). So I guess it tries to render an empty array, but has nothing to put the values into at the start.

To solve this, I set this as the default value:

  const [value, setValue] = useState<Descendant[]>([
    {
      type: "paragraph",
      children: [{ text: "" }],
    },
  ]);

@duarteEdu
Copy link

Thank you @dark-swordsman.

I solved this problem using your solution.

@nipunahh
Copy link

I ran into this problem when rendering nothing in the slate component, since the introduction tutorial starts off with nothing in the useState([]). So I guess it tries to render an empty array, but has nothing to put the values into at the start.

To solve this, I set this as the default value:

  const [value, setValue] = useState<Descendant[]>([
    {
      type: "paragraph",
      children: [{ text: "" }],
    },
  ]);

Exactly- I was just passing in [] into the value prop. This fixes it

@Nefcanto
Copy link

@dark-swordsman that solved my problem too. However, it would be much better if slate would give us a very clear message about empty content. And I think it should be able to handle empty content as well.

@bekogeko
Copy link

@dark-swordsman that solved my problem too. However, it would be much better if slate would give us a very clear message about empty content. And I think it should be able to handle empty content as well.

i think this issue becomes enchantment at this point.
it looks like solution works for everybody 👍 😊

@fgatti675
Copy link

I keep on bumping into this error, I have absolutely no idea why, or when it happens as it seems completely random.
And it's driving me completely crazy

@jm-maniego
Copy link

jm-maniego commented Sep 9, 2023

In my case, I've added a draggable item, which required the ref of the element. but apparently attributes wants the ref too

from

  <div  ref={draggable.innerRef} {...attributes}>

to

  <div
      ref={el => {
        attributes.ref(el);
        draggable.innerRef(el); 
      }}
      {...attributes}>

(but I have another issue, so it's still broken :D)

zoe-icu pushed a commit to apitable/apitable that referenced this issue Jan 2, 2024
# Human says


close vikadata/vikadata#10236

ianstormtaylor/slate#3421



![image](https://github.com/vikadata/vikadata/assets/12862508/89131763-0156-4628-adff-a5cdb24839e5)

As a human, what have you done for this pull request?
Why? What? How?
<!-- 如果这个Pull Request有对应的Issue,你可以复制Issue的相关信息。 -->
<!-- 
# Why?
> 对应哪个issue?
> 为什么要这个pull request?
> 背景故事或原因是怎样的?
> 你理解的业务需求是怎样的? 
-->

<!-- 
# What?
> 这是一个什么Pull Request?
> 描述一下是什么?
> 对哪些人有好处? 
-->

<!-- 
# How?
> 大概描述下,如何具体实现的这个Pull Request? 
-->


# AI says

<!-- AI auto review added here -->
<!-- This is an auto-generated comment: release notes by OSS CodeRabbit
-->
### Summary by CodeRabbit

- Style: Code formatting and style adjustments were made to the
`MagicVariableElement` component for improved readability and
consistency.
- Chore: Variable assignments and conditional statements were modified
in the `MagicVariableElement` component without affecting the logic or
functionality of the code.
<!-- end of auto-generated comment: release notes by OSS CodeRabbit -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.