Skip to content

Commit

Permalink
fix: replace regex and add test coverage
Browse files Browse the repository at this point in the history
Fixes regression from #220
Closes #224
  • Loading branch information
jukben committed Oct 13, 2021
1 parent 182ed80 commit d58d3d9
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 14 deletions.
24 changes: 15 additions & 9 deletions cypress/integration/textarea.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,12 @@ describe("React Textarea Autocomplete", () => {
.should("have.value", "This is test🙄");
});

it("should respect already written tokens", () => {
cy.get(".rta__textarea")
.type("This is test -f{enter}and -s{downarrow}{enter}")
.should("have.value", "This is test -first and -second ");
});

it("special character like [, ( should be also possible to use as trigger char", () => {
cy.get(".rta__textarea")
.type("This is test [{enter}")
Expand Down Expand Up @@ -99,7 +105,7 @@ describe("React Textarea Autocomplete", () => {
.then(() => {
const endLeft = Cypress.$(".rta__autocomplete").css("left");
cy.get(".rta__autocomplete").should("to.have.css", {
left: startLeft
left: startLeft,
});

expect(startLeft).to.be.equal(endLeft);
Expand Down Expand Up @@ -136,10 +142,10 @@ describe("React Textarea Autocomplete", () => {

it("onItemHighlighted should return correct item and trigger", () => {
cy.get(".rta__textarea").type(":ro{uparrow}{uparrow}");
cy.window().then(async win => {
cy.window().then(async (win) => {
const shouldSelectItem = {
currentTrigger: ":",
item: { name: "rofl", char: "🤣" }
item: { name: "rofl", char: "🤣" },
};

expect(win.__lastHighlightedItem).to.deep.equal(shouldSelectItem);
Expand All @@ -148,10 +154,10 @@ describe("React Textarea Autocomplete", () => {

it("onItemSelected should return correct item and trigger", () => {
cy.get(".rta__textarea").type(":ro{uparrow}{uparrow}{enter}");
cy.window().then(async win => {
cy.window().then(async (win) => {
const shouldSelectItem = {
currentTrigger: ":",
item: { name: "rofl", char: "🤣" }
item: { name: "rofl", char: "🤣" },
};

expect(win.__lastSelectedItem).to.deep.equal(shouldSelectItem);
Expand Down Expand Up @@ -266,7 +272,7 @@ describe("React Textarea Autocomplete", () => {
cy.get(".rta__textarea").type(
`${repeat("{backspace}", 13)} again {downarrow}{enter}`,
{
force: true
force: true,
}
);
cy.get(".rta__textarea").should("have.value", "This is test /");
Expand Down Expand Up @@ -366,7 +372,7 @@ describe("React Textarea Autocomplete", () => {
.get("li:nth-child(1)")
.click();
cy.get(".rta__textarea").type(`${repeat("\n", 5)} test :a`, {
force: true
force: true,
});
cy.get(".rta__autocomplete").should(
"have.class",
Expand Down Expand Up @@ -395,13 +401,13 @@ describe("React Textarea Autocomplete", () => {
});

it("event is successfully blocked", () => {
cy.window().then(async win => {
cy.window().then(async (win) => {
const spy = cy.spy(win.console, "log");

await cy
.get(".rta__textarea")
.type(":ro{uparrow}{uparrow}{enter}")
.then(e => {
.then((e) => {
// the last console.log call should not be `pressed "enter"` because that event is blocked because it's happening in autocomplete.
expect(spy.lastCall.args).to.eql([`pressed "o"`]);
});
Expand Down
16 changes: 15 additions & 1 deletion example/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,21 @@ class App extends React.Component {
text: `${trigger}${item.name}`,
caretPosition: "end"
})
}
},
"-": {
dataProvider: token => {
return [
{ name: "f", char: "-first" },
{ name: "s", char: "-second" }
];
},
component: Item,
output: {
start: this._outputCaretStart,
end: this._outputCaretEnd,
next: this._outputCaretNext
}[optionsCaret]
},
}}
/>
{!showSecondTextarea ? null : (
Expand Down
9 changes: 5 additions & 4 deletions src/Textarea.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ class ReactTextareaAutocomplete extends React.Component<

_onSelect = (item: Object | string) => {
const { selectionEnd, currentTrigger, value: textareaValue } = this.state;
const { trigger, onItemSelected } = this.props;
const { onItemSelected } = this.props;

if (!currentTrigger) return;

Expand Down Expand Up @@ -437,14 +437,15 @@ class ReactTextareaAutocomplete extends React.Component<

/**
* It's important to escape the currentTrigger char for chars like [, (,...
* This is a ridiculous dark magic, basically we found position of the last current token (from current trigger) and then we replace the text from that position (calculating the offset)
*/
const escapedCurrentTrigger = escapeRegex(currentTrigger);
const escapedCurrentTriggerWithWhitespace = escapedCurrentTrigger + (trigger[currentTrigger].allowWhitespace ? "" : "\\s");
const triggerOffset = textToModify.length - textToModify.lastIndexOf(currentTrigger);
const startOfTokenPosition = textToModify.search(
new RegExp(
`${escapedCurrentTrigger}((?!${escapedCurrentTriggerWithWhitespace}).)*$`
`(?!${escapedCurrentTrigger})$`
)
);
) - triggerOffset;

// we add space after emoji is selected if a caret position is next
const newTokenString =
Expand Down

0 comments on commit d58d3d9

Please sign in to comment.