Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Commit

Permalink
make it able to deal with inserting in middle of blank lines
Browse files Browse the repository at this point in the history
  • Loading branch information
Alun Turner committed May 11, 2023
1 parent f61d399 commit 15a2cf5
Showing 1 changed file with 22 additions and 20 deletions.
42 changes: 22 additions & 20 deletions src/components/views/rooms/wysiwyg_composer/hooks/useSuggestion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,26 +157,28 @@ export function processMention(
const { node } = suggestionData;

// create an <a> element with the required attributes to allow us to interpret the mention as being a pill
const link = document.createElement("a");
const linkText = document.createTextNode(displayName);
link.setAttribute("href", href);
link.setAttribute("contenteditable", "false");
Object.entries(attributes).forEach(([attr, value]) => isNotUndefined(value) && link.setAttribute(attr, value));
link.appendChild(linkText);

// create a text node that will follow the inserted link (as we may be inserting into the middle of a node)
const endNode = document.createTextNode(` ${node.textContent?.slice(suggestionData.endOffset) ?? ""}`);

// now amend the current node text content to be only the text from start up to the suggestion startOffset
// (default to a zwsp if we'd have no preceding text to allow cursor positioning before a lone pill)
node.textContent = node.textContent?.slice(0, suggestionData.startOffset) || "\u200b";

// then append the newly created link and the ending text node containing the space that follows the link
node.parentNode?.appendChild(link);
node.parentNode?.appendChild(endNode);

// move the selection to after the space that follows the link
document.getSelection()?.setBaseAndExtent(endNode, 1, endNode, 1);
const linkElement = document.createElement("a");
const linkTextNode = document.createTextNode(displayName);
linkElement.setAttribute("href", href);
linkElement.setAttribute("contenteditable", "false");
Object.entries(attributes).forEach(
([attr, value]) => isNotUndefined(value) && linkElement.setAttribute(attr, value),
);
linkElement.appendChild(linkTextNode);

// create text nodes to go before and after the link
const leadingTextNode = document.createTextNode(node.textContent?.slice(0, suggestionData.startOffset) || "\u200b");
const trailingTextNode = document.createTextNode(` ${node.textContent?.slice(suggestionData.endOffset) ?? ""}`);

// now add the leading node, link element and trailing node before removing the node we are replacing
const parentNode = node.parentNode;
parentNode.insertBefore(leadingTextNode, node);
parentNode.insertBefore(linkElement, node);
parentNode.insertBefore(trailingTextNode, node);
parentNode.removeChild(node);

// move the selection to the trailing text node
document.getSelection()?.setBaseAndExtent(trailingTextNode, 1, trailingTextNode, 1);

// set the text content to be the innerHTML of the current editor ref and clear the suggestion state
setText();
Expand Down

0 comments on commit 15a2cf5

Please sign in to comment.