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:
- Type anything in first line
- Then type
/names
in the second line, followed byn
(a shortcut for "nick") - 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?
- TRIGGER anything TRIGGER
- TRIGGER TRIGGER anything
- 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/