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

Mentioning at the beginning of a line and before other text causes a JavaScript error #1843

Open
PibeG opened this issue Aug 31, 2022 · 3 comments · May be fixed by #2752
Open

Mentioning at the beginning of a line and before other text causes a JavaScript error #1843

PibeG opened this issue Aug 31, 2022 · 3 comments · May be fixed by #2752
Labels
bug Something isn't working plugin:mention

Comments

@PibeG
Copy link

PibeG commented Aug 31, 2022

Description

Same as with the issue #1232, trying to create a mention at the beginning of a line and before other text.

Steps

  1. Go to Mention plugin page
  2. Type a Space before "💬 Mention" or at the start of any of the paragraphs, move the caret to the beginning of the line and type '@'.
  3. The Mention combobox does not display, but the mention input is created and the caret is inside of it.
  4. Press 'Enter' or 'Tab'
  5. The following error occurs
Cannot find a descendant at path [0,0,0] in node: {"children":[{"type":"h2","children":[{"text":""},{"text":"@"},{"text":" 💬 Mention"}]},{"type":"p","children":[{"text":"This example shows how you might implement a simple @-mentions feature that lets users autocomplete mentioning a user by their username. Which, in this case means Star Wars characters. The mentions are rendered as void inline elements inside the document."}]},{"type":"p","children":[{"text":"Try mentioning characters, like "},{"type":"mention","children":[{"text":""}],"value":"R2-D2"},{"text":" or "},{"type":"mention","children":[{"text":""}],"value":"Mace Windu"},{"text":""}]}],"operations":[{"type":"set_selection","properties":{"anchor":{"path":[0,1,0],"offset":0},"focus":{"path":[0,1,0],"offset":0}},"newProperties":{"anchor":{"path":[0,0,0],"offset":0},"focus":{"path":[0,0,0],"offset":0}}},{"type":"insert_text","path":[0,1,0],"offset":0,"text":"@"},{"type":"move_node","path":[0,1,0],"newPath":[0,2]},{"type":"remove_node","path":[0,1],"node":{"type":"mention_input","children":[],"trigger":"@"}}],"selection":{"anchor":{"path":[0,0,0],"offset":0},"focus":{"path":[0,0,0],"offset":0}},"marks":null,"id":"main","prevSelection":{"anchor":{"path":[0,1,0],"offset":0},"focus":{"path":[0,1,0],"offset":0}},"currentKeyboardEvent":null,"key":0.7095012255939719,"plugins":[{"key":"react","type":"react","options":{},"inject":{},"editor":{}},{"key":"history","type":"history","options":{},"inject":{},"editor":{}},{"key":"event-editor","handlers":{},"type":"event-editor","options":{},"inject":{},"editor":{}},{"key":"inline-void","type":"inline-void","options":{},"inject":{},"editor":{}},{"key":"insertData","type":"insertData","options":{},"inject":{},"editor":{}},{"key":"selection","handlers":{},"type":"selection","options":{},"inject":{},"editor":{}},{"key":"deserializeHtml","editor":{"insertData":{"format":"text/html"}},"type":"deserializeHtml","options":{},"inject":{}},{"key":"deserializeAst","editor":{"insertData":{"format":"application/x-slate-fragment"}},"type":"deserializeAst","options":{},"inject":{}},{"key":"blockquote","isElement":true,"deserializeHtml":{"rules":[{"validNodeName":"BLOCKQUOTE"}]},"handlers":{},"options":{"hotkey":"mod+shift+."},"type":"blockquote","inject":{},"editor":{}},{"component":null,"key":"code_block","inject":{"pluginsByKey":{"deserializeHtml":{"editor":{"insertData":{}}}}},"isElement":true,"deserializeHtml":{"rules":[{"validNodeName":"PRE"},{"validNodeName":"P","validStyle":{"fontFamily":"Consolas"}}]},"handlers":{},"options":{"hotkey":["mod+opt+8","mod+shift+8"],"syntax":true,"syntaxPopularFirst":false},"plugins":[{"key":"code_line","isElement":true,"type":"code_line","options":{},"inject":{},"editor":{}},{"key":"code_syntax","isLeaf":true,"type":"code_syntax","options":{},"inject":{},"editor":{}}],"type":"code_block","editor":{}},{"key":"code_line","isElement":true,"type":"code_line","options":{},"inject":{},"editor":{}},{"key":"code_syntax","isLeaf":true,"type":"code_syntax","options":{},"inject":{},"editor":{}},{"key":"heading","plugins":[{"key":"h1","isElement":true,"deserializeHtml":{"rules":[{"validNodeName":"H1"}]},"handlers":{},"options":{"hotkey":["mod+opt+1","mod+shift+1"]},"type":"h1","inject":{},"editor":{}},{"key":"h2","isElement":true,"deserializeHtml":{"rules":[{"validNodeName":"H2"}]},"handlers":{},"options":{"hotkey":["mod+opt+2","mod+shift+2"]},"type":"h2","inject":{},"editor":{}},{"key":"h3","isElement":true,"deserializeHtml":{"rules":[{"validNodeName":"H3"}]},"handlers":{},"options":{"hotkey":["mod+opt+3","mod+shift+3"]},"type":"h3","inject":{},"editor":{}},{"key":"h4","isElement":true,"deserializeHtml":{"rules":[{"validNodeName":"H4"}]},"handlers":{},"options":{},"type":"h4","inject":{},"editor":{}},{"key":"h5","isElement":true,"deserializeHtml":{"rules":[{"validNodeName":"H5"}]},"handlers":{},"options":{},"type":"h5","inject":{},"editor":{}},{"key":"h6","isElement":true,"deserializeHtml":{"rules":[{"validNodeName":"H6"}]},"handlers":{},"options":{},"type":"h6","inject":{},"editor":{}}],"options":{"levels":6},"type":"heading","inject":{},"editor":{}},{"key":"h1","isElement":true,"deserializeHtml":{"rules":[{"validNodeName":"H1"}]},"handlers":{},"options":{"hotkey":["mod+opt+1","mod+shift+1"]},"type":"h1","inject":{},"editor":{}},{"key":"h2","isElement":true,"deserializeHtml":{"rules":[{"validNodeName":"H2"}]},"handlers":{},"options":{"hotkey":["mod+opt+2","mod+shift+2"]},"type":"h2","inject":{},"editor":{}},{"key":"h3","isElement":true,"deserializeHtml":{"rules":[{"validNodeName":"H3"}]},"handlers":{},"options":{"hotkey":["mod+opt+3","mod+shift+3"]},"type":"h3","inject":{},"editor":{}},{"key":"h4","isElement":true,"deserializeHtml":{"rules":[{"validNodeName":"H4"}]},"handlers":{},"options":{},"type":"h4","inject":{},"editor":{}},{"key":"h5","isElement":true,"deserializeHtml":{"rules":[{"validNodeName":"H5"}]},"handlers":{},"options":{},"type":"h5","inject":{},"editor":{}},{"key":"h6","isElement":true,"deserializeHtml":{"rules":[{"validNodeName":"H6"}]},"handlers":{},"options":{},"type":"h6","inject":{},"editor":{}},{"key":"p","isElement":true,"handlers":{},"options":{"hotkey":["mod+opt+0","mod+shift+0"]},"deserializeHtml":{"rules":[{"validNodeName":"P"}]},"type":"p","inject":{},"editor":{}},{"key":"bold","isLeaf":true,"deserializeHtml":{"rules":[{"validNodeName":["STRONG","B"]},{"validStyle":{"fontWeight":["600","700","bold"]}}]},"handlers":{},"options":{"hotkey":"mod+b"},"type":"bold","inject":{},"editor":{}},{"key":"code","isLeaf":true,"deserializeHtml":{"rules":[{"validNodeName":["CODE"]},{"validStyle":{"wordWrap":"break-word"}},{"validStyle":{"fontFamily":"Consolas"}}]},"handlers":{},"options":{"hotkey":"mod+e"},"type":"code","inject":{},"editor":{}},{"key":"italic","isLeaf":true,"handlers":{},"options":{"hotkey":"mod+i"},"deserializeHtml":{"rules":[{"validNodeName":["EM","I"]},{"validStyle":{"fontStyle":"italic"}}]},"type":"italic","inject":{},"editor":{}},{"key":"strikethrough","isLeaf":true,"handlers":{},"options":{"hotkey":"mod+shift+x"},"deserializeHtml":{"rules":[{"validNodeName":["S","DEL","STRIKE"]},{"validStyle":{"textDecoration":"line-through"}}]},"type":"strikethrough","inject":{},"editor":{}},{"key":"subscript","isLeaf":true,"handlers":{},"options":{"hotkey":"mod+,","clear":"superscript"},"deserializeHtml":{"rules":[{"validNodeName":["SUB"]},{"validStyle":{"verticalAlign":"sub"}}]},"type":"subscript","inject":{},"editor":{}},{"key":"superscript","isLeaf":true,"handlers":{},"options":{"hotkey":"mod+.","clear":"subscript"},"deserializeHtml":{"rules":[{"validNodeName":["SUP"]},{"validStyle":{"verticalAlign":"super"}}]},"type":"superscript","inject":{},"editor":{}},{"key":"underline","isLeaf":true,"handlers":{},"options":{"hotkey":"mod+u"},"deserializeHtml":{"rules":[{"validNodeName":["U"]},{"validStyle":{"textDecoration":["underline"]}}]},"type":"underline","inject":{},"editor":{}},{"key":"combobox","handlers":{},"type":"combobox","options":{},"inject":{},"editor":{}},{"key":"mention","options":{"id":"mention","trigger":"@"},"isElement":true,"isInline":true,"isVoid":true,"handlers":{},"plugins":[{"key":"mention_input","isElement":true,"isInline":true,"type":"mention_input","options":{},"inject":{},"editor":{}}],"type":"mention","inject":{},"editor":{}},{"key":"mention_input","isElement":true,"isInline":true,"type":"mention_input","options":{},"inject":{},"editor":{}},{"key":"#","options":{"id":"#","trigger":"#","inputCreation":{"key":"creationId","value":"main"}},"isElement":true,"isInline":true,"isVoid":true,"handlers":{},"plugins":[{"key":"mention_input","isElement":true,"isInline":true,"type":"mention_input","options":{},"inject":{},"editor":{}}],"type":"#","inject":{},"editor":{}},{"key":"/","options":{"id":"/","trigger":"/"},"isElement":true,"isInline":true,"isVoid":true,"handlers":{},"plugins":[{"key":"mention_input","isElement":true,"isInline":true,"type":"mention_input","options":{},"inject":{},"editor":{}}],"type":"/","inject":{},"editor":{}}],"pluginsByKey":{"react":{"key":"react","type":"react","options":{},"inject":{},"editor":{}},"history":{"key":"history","type":"history","options":{},"inject":{},"editor":{}},"event-editor":{"key":"event-editor","handlers":{},"type":"event-editor","options":{},"inject":{},"editor":{}},"inline-void":{"key":"inline-void","type":"inline-void","options":{},"inject":{},"editor":{}},"insertData":{"key":"insertData","type":"insertData","options":{},"inject":{},"editor":{}},"selection":{"key":"selection","handlers":{},"type":"selection","options":{},"inject":{},"editor":{}},"deserializeHtml":{"key":"deserializeHtml","editor":{"insertData":{"format":"text/html"}},"type":"deserializeHtml","options":{},"inject":{}},"deserializeAst":{"key":"deserializeAst","editor":{"insertData":{"format":"application/x-slate-fragment"}},"type":"deserializeAst","options":{},"inject":{}},"blockquote":{"key":"blockquote","isElement":true,"deserializeHtml":{"rules":[{"validNodeName":"BLOCKQUOTE"}]},"handlers":{},"options":{"hotkey":"mod+shift+."},"type":"blockquote","inject":{},"editor":{}},"code_block":{"component":null,"key":"code_block","inject":{"pluginsByKey":{"deserializeHtml":{"editor":{"insertData":{}}}}},"isElement":true,"deserializeHtml":{"rules":[{"validNodeName":"PRE"},{"validNodeName":"P","validStyle":{"fontFamily":"Consolas"}}]},"handlers":{},"options":{"hotkey":["mod+opt+8","mod+shift+8"],"syntax":true,"syntaxPopularFirst":false},"plugins":[{"key":"code_line","isElement":true,"type":"code_line","options":{},"inject":{},"editor":{}},{"key":"code_syntax","isLeaf":true,"type":"code_syntax","options":{},"inject":{},"editor":{}}],"type":"code_block","editor":{}},"code_line":{"key":"code_line","isElement":true,"type":"code_line","options":{},"inject":{},"editor":{}},"code_syntax":{"key":"code_syntax","isLeaf":true,"type":"code_syntax","options":{},"inject":{},"editor":{}},"heading":{"key":"heading","plugins":[{"key":"h1","isElement":true,"deserializeHtml":{"rules":[{"validNodeName":"H1"}]},"handlers":{},"options":{"hotkey":["mod+opt+1","mod+shift+1"]},"type":"h1","inject":{},"editor":{}},{"key":"h2","isElement":true,"deserializeHtml":{"rules":[{"validNodeName":"H2"}]},"handlers":{},"options":{"hotkey":["mod+opt+2","mod+shift+2"]},"type":"h2","inject":{},"editor":{}},{"key":"h3","isElement":true,"deserializeHtml":{"rules":[{"validNodeName":"H3"}]},"handlers":{},"options":{"hotkey":["mod+opt+3","mod+shift+3"]},"type":"h3","inject":{},"editor":{}},{"key":"h4","isElement":true,"deserializeHtml":{"rules":[{"validNodeName":"H4"}]},"handlers":{},"options":{},"type":"h4","inject":{},"editor":{}},{"key":"h5","isElement":true,"deserializeHtml":{"rules":[{"validNodeName":"H5"}]},"handlers":{},"options":{},"type":"h5","inject":{},"editor":{}},{"key":"h6","isElement":true,"deserializeHtml":{"rules":[{"validNodeName":"H6"}]},"handlers":{},"options":{},"type":"h6","inject":{},"editor":{}}],"options":{"levels":6},"type":"heading","inject":{},"editor":{}},"h1":{"key":"h1","isElement":true,"deserializeHtml":{"rules":[{"validNodeName":"H1"}]},"handlers":{},"options":{"hotkey":["mod+opt+1","mod+shift+1"]},"type":"h1","inject":{},"editor":{}},"h2":{"key":"h2","isElement":true,"deserializeHtml":{"rules":[{"validNodeName":"H2"}]},"handlers":{},"options":{"hotkey":["mod+opt+2","mod+shift+2"]},"type":"h2","inject":{},"editor":{}},"h3":{"key":"h3","isElement":true,"deserializeHtml":{"rules":[{"validNodeName":"H3"}]},"handlers":{},"options":{"hotkey":["mod+opt+3","mod+shift+3"]},"type":"h3","inject":{},"editor":{}},"h4":{"key":"h4","isElement":true,"deserializeHtml":{"rules":[{"validNodeName":"H4"}]},"handlers":{},"options":{},"type":"h4","inject":{},"editor":{}},"h5":{"key":"h5","isElement":true,"deserializeHtml":{"rules":[{"validNodeName":"H5"}]},"handlers":{},"options":{},"type":"h5","inject":{},"editor":{}},"h6":{"key":"h6","isElement":true,"deserializeHtml":{"rules":[{"validNodeName":"H6"}]},"handlers":{},"options":{},"type":"h6","inject":{},"editor":{}},"p":{"key":"p","isElement":true,"handlers":{},"options":{"hotkey":["mod+opt+0","mod+shift+0"]},"deserializeHtml":{"rules":[{"validNodeName":"P"}]},"type":"p","inject":{},"editor":{}},"bold":{"key":"bold","isLeaf":true,"deserializeHtml":{"rules":[{"validNodeName":["STRONG","B"]},{"validStyle":{"fontWeight":["600","700","bold"]}}]},"handlers":{},"options":{"hotkey":"mod+b"},"type":"bold","inject":{},"editor":{}},"code":{"key":"code","isLeaf":true,"deserializeHtml":{"rules":[{"validNodeName":["CODE"]},{"validStyle":{"wordWrap":"break-word"}},{"validStyle":{"fontFamily":"Consolas"}}]},"handlers":{},"options":{"hotkey":"mod+e"},"type":"code","inject":{},"editor":{}},"italic":{"key":"italic","isLeaf":true,"handlers":{},"options":{"hotkey":"mod+i"},"deserializeHtml":{"rules":[{"validNodeName":["EM","I"]},{"validStyle":{"fontStyle":"italic"}}]},"type":"italic","inject":{},"editor":{}},"strikethrough":{"key":"strikethrough","isLeaf":true,"handlers":{},"options":{"hotkey":"mod+shift+x"},"deserializeHtml":{"rules":[{"validNodeName":["S","DEL","STRIKE"]},{"validStyle":{"textDecoration":"line-through"}}]},"type":"strikethrough","inject":{},"editor":{}},"subscript":{"key":"subscript","isLeaf":true,"handlers":{},"options":{"hotkey":"mod+,","clear":"superscript"},"deserializeHtml":{"rules":[{"validNodeName":["SUB"]},{"validStyle":{"verticalAlign":"sub"}}]},"type":"subscript","inject":{},"editor":{}},"superscript":{"key":"superscript","isLeaf":true,"handlers":{},"options":{"hotkey":"mod+.","clear":"subscript"},"deserializeHtml":{"rules":[{"validNodeName":["SUP"]},{"validStyle":{"verticalAlign":"super"}}]},"type":"superscript","inject":{},"editor":{}},"underline":{"key":"underline","isLeaf":true,"handlers":{},"options":{"hotkey":"mod+u"},"deserializeHtml":{"rules":[{"validNodeName":["U"]},{"validStyle":{"textDecoration":["underline"]}}]},"type":"underline","inject":{},"editor":{}},"combobox":{"key":"combobox","handlers":{},"type":"combobox","options":{},"inject":{},"editor":{}},"mention":{"key":"mention","options":{"id":"mention","trigger":"@"},"isElement":true,"isInline":true,"isVoid":true,"handlers":{},"plugins":[{"key":"mention_input","isElement":true,"isInline":true,"type":"mention_input","options":{},"inject":{},"editor":{}}],"type":"mention","inject":{},"editor":{}},"mention_input":{"key":"mention_input","isElement":true,"isInline":true,"type":"mention_input","options":{},"inject":{},"editor":{}},"#":{"key":"#","options":{"id":"#","trigger":"#","inputCreation":{"key":"creationId","value":"main"}},"isElement":true,"isInline":true,"isVoid":true,"handlers":{},"plugins":[{"key":"mention_input","isElement":true,"isInline":true,"type":"mention_input","options":{},"inject":{},"editor":{}}],"type":"#","inject":{},"editor":{}},"/":{"key":"/","options":{"id":"/","trigger":"/"},"isElement":true,"isInline":true,"isVoid":true,"handlers":{},"plugins":[{"key":"mention_input","isElement":true,"isInline":true,"type":"mention_input","options":{},"inject":{},"editor":{}}],"type":"/","inject":{},"editor":{}}},"history":{"undos":[[{"type":"insert_text","path":[0,0],"offset":0,"text":" "},{"type":"set_selection","properties":{"anchor":{"path":[0,0],"offset":1},"focus":{"path":[0,0],"offset":1}},"newProperties":{"anchor":{"path":[0,0],"offset":0},"focus":{"path":[0,0],"offset":0}}}],[{"type":"insert_node","path":[0,0],"node":{"type":"mention_input","children":[{"text":""}],"trigger":"@"}},{"type":"set_selection","properties":{"anchor":{"path":[0,1],"offset":0},"focus":{"path":[0,1],"offset":0}},"newProperties":{"anchor":{"path":[0,0,0],"offset":0},"focus":{"path":[0,0,0],"offset":0}}},{"type":"insert_node","path":[0,0],"node":{"text":""}},{"type":"set_selection","properties":{"anchor":{"path":[0,1,0],"offset":0},"focus":{"path":[0,1,0],"offset":0}},"newProperties":{"anchor":{"path":[0,0,0],"offset":0},"focus":{"path":[0,0,0],"offset":0}}},{"type":"insert_text","path":[0,1,0],"offset":0,"text":"@"},{"type":"move_node","path":[0,1,0],"newPath":[0,2]},{"type":"remove_node","path":[0,1],"node":{"type":"mention_input","children":[],"trigger":"@"}}]],"redos":[]}}


Environment

  • browser: chrome, safari

Funding

  • You can sponsor this specific effort via a Polar.sh pledge below
  • We receive the pledge once the issue is completed & verified
Fund with Polar
@PibeG PibeG added the bug Something isn't working label Aug 31, 2022
@O4epegb
Copy link
Collaborator

O4epegb commented Nov 18, 2022

Also encountered this issue, but unfortunately I don't understand how to fix it.

Combobox itself is not visible too in that situation, I think the root of it is getRangeBoundingClientRect function, it calls toDOMRange which calls slate.ReactEditor.toDOMRange and this function throws, so getDefaultBoundingClientRect is used instead and combobox is rendered somewhere outside of viewport. And then if you blindly press enter editor throws again, basically with the same error as toDOMRange, but this time the error is not handled

@PibeG
Copy link
Author

PibeG commented Mar 16, 2023

Further investigation leads me to think that it's because when creating the mention_input node the selection moves to [0,0,0] (inside of the inline), then to have leaf nodes on each side of the inline element an empty leaf node is inserted, pushing the mention input to [0,1,0] (selection remains inside of the mention_input), and finally the selection is set again to the previous selection [0,0,0] (before inserting the empty leaf). But as the error prompts, this path doesn't exist.

Same for when there is already an inline and the trigger is typed right next to it (and there is already a space after). It creates the mention_input, then a leaf node, then the selection is set to where the mention_input was originally created.

@JannesMeyer
Copy link

I also investigated this and came to the same conclusion as @PibeG. Slate inserts an empty text node before the mention input to fulfil this normalization constraint:

  1. Inline nodes cannot be the first or last child of a parent block, nor can it be next to another inline node in the children array. If this is the case, an empty text node will be added to correct this to be in compliance with the constraint.

Source: https://docs.slatejs.org/concepts/11-normalizing

@JannesMeyer JannesMeyer linked a pull request Nov 19, 2023 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working plugin:mention
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants