elm-rte-toolkit icon indicating copy to clipboard operation
elm-rte-toolkit copied to clipboard

Cannot type after a link on Chrome

Open matsjoyce opened this issue 4 years ago • 2 comments

Steps to reproduce:

  • Go to https://mweiss.github.io/elm-rte-toolkit/#/examples/basic using Chrome
  • Turn the text that is present into a link
  • Place the caret after the link
  • Typing at that position is impossible

Cause: Chrome adds the text after the link, which is ignored by the editor. See https://bugs.chromium.org/p/chromium/issues/detail?id=1115085#c3 for details

Possible fix:

  • Rendering links without the href does fix the issue (but will also stop them being rendered as links). Unfortunately, removing the href cannot be done though decorations, so it will have to be done though the linkToHtmlNode which will then affect the Html.toHtml function.
  • Add a new command for typing after a link. However, it is hard to determine which nodes render to an a, since the only place the a element is used is in the linkToHtmlNode function.
  • Modify the JS that handles the mutation list to move the changes into the link. This can be complicated if the link contains nested markup. Going down that route results is a monstrosity like this:
     characterDataMutations(mutationsList) {
        if (!mutationsList) {
            return null;
        }
    
        let mutations = [], allCharacterData = true, self = this;
        mutationsList.forEach(function (mutation, i) {
            if (mutation.type === "childList"
                && mutation.addedNodes.length === 1 // Added a single text node
                && mutation.addedNodes[0].nodeType === Node.TEXT_NODE
                && mutation.previousSibling // Previous node is a link
                && mutation.previousSibling.nodeType === Node.ELEMENT_NODE
                && mutation.previousSibling.nodeName === "A"
            ) {
                var n = mutation.previousSibling;
                while (n.nodeType !== Node.TEXT_NODE) {
                    n = n.childNodes[n.childNodes.length - 1];
                }
                n.nodeValue += mutation.addedNodes[0].nodeValue;
                mutationsList[i + 1] = {target: n, type: "characterData"};
                mutation.addedNodes[0].remove();
                return;
            }
            if (mutation.type !== "characterData") {
                allCharacterData = false;
                return;
            }
            mutations.push({
                path: getSelectionPath(mutation.target, self, 0),
                text: mutation.target.nodeValue
            });
        });
        return allCharacterData ? mutations : null;
    }
    
    

This problem does not occur on Firefox.

matsjoyce avatar Dec 16 '20 20:12 matsjoyce

Thanks for reporting this! I'm wary of adding special cases to the js code for browser specific bugs (although Android and mac have a few) since that can get out of hand really fast. Perhaps adding a new command is the way to go, or even waiting for Chrome to fix itself.

mweiss avatar Dec 20 '20 20:12 mweiss

Judging from the issue I linked, Chrome considers this to be the desired behaviour. I suppose the best way of fixing this is to add a new command and a new field to marks, so that the command can determine if the mark is a link?

matsjoyce avatar Dec 28 '20 12:12 matsjoyce