webscopeio/react-textarea-autocomplete

Some triggers wipe entire text

Closed this issue · 2 comments

Please check https://codepen.io/lukaszmn/pen/poPeQrQ

The relevant part is here:

         "/names": {
          dataProvider: token => {
            return [
              { name: "k", char: "kevin" },
              { name: "n", char: "nick" },
            ].filter(x => x.name == token.slice(5) || token.length === 5);
          },

To reproduce:

  1. Type anything in first line
  2. Then type /names in the second line, followed by n (a shortcut for "nick")
  3. Press ENTER - the first line is gone (and undo history is lost as well)

If you try with "kevin", it works well. That's because RTA always looks for the phrase from the beginning of textarea to the current position and it uses the following Regex:

      var startOfTokenPosition = textToModify.search(
      /**
       * It's important to escape the currentTrigger char for chars like [, (,...
       */
      new RegExp("".concat(escapeRegex(currentTrigger), "[^".concat(escapeRegex(currentTrigger)).concat(trigger[currentTrigger].allowWhitespace ? "" : "\\s", "]"), "*$"))); // we add space after emoji is selected if a caret position is next

which becomes something like /names[^/names]*$. If the author meant to find "/names" which is not followed by "/names", then [] operator is nor correct - it only finds any of the letters, so /names cannot be followed by any of the letters: a, e, m, n, s. That's why /namesk works and /namesn fails. If the regex fails to find, the text from the first line until the cursor position is replaced.

After some testing of the new Regex, I don't confirm it works well for all cases. Please help me by explaining the rationale for that Regex. Should it apply to which of these cases?

  1. TRIGGER anything TRIGGER
  2. TRIGGER TRIGGER anything
  3. TRIGGER anything TRIGGER anything

Should the second TRIGGER be caught in all of these cases? If so, can't we just use lastIndexOf?

I fixed the regex, now it matches the last trigger. All tests pass, including the new one, and the behavior can be checked with this regex tester: https://regex101.com/r/DZ78UV/1/