mirror of
https://github.com/discourse/discourse.git
synced 2025-01-16 05:42:41 +08:00
UX: avoid triggering the autocomplete mid-word (#30042)
With the previous logic, autocompletes were being opened mid-word, which was annoying and didn't properly work – selecting an option would generate an invalid format, mixing existing with new. This PR makes a simple change: only ever trigger an autocomplete on word ends, and close them when arrow-navigating out of the word-end boundary. ref /t/-/143169
This commit is contained in:
parent
dacb5d5d33
commit
b4f0a8748d
|
@ -478,7 +478,11 @@ export default function (options) {
|
||||||
}
|
}
|
||||||
|
|
||||||
prevTerm = term;
|
prevTerm = term;
|
||||||
if (term.length !== 0 && term.trim().length === 0) {
|
if (
|
||||||
|
(term.length !== 0 && term.trim().length === 0) ||
|
||||||
|
// close unless the caret is at the end of a word, like #line|<-
|
||||||
|
options.textHandler.value[options.textHandler.getCaretPosition()]?.trim()
|
||||||
|
) {
|
||||||
closeAutocomplete();
|
closeAutocomplete();
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { triggerKeyEvent } from "@ember/test-helpers";
|
||||||
import { setupTest } from "ember-qunit";
|
import { setupTest } from "ember-qunit";
|
||||||
import { compile } from "handlebars";
|
import { compile } from "handlebars";
|
||||||
import $ from "jquery";
|
import $ from "jquery";
|
||||||
|
@ -169,4 +170,45 @@ module("Unit | Utility | autocomplete", function (hooks) {
|
||||||
|
|
||||||
assert.strictEqual(element.value, "@t");
|
assert.strictEqual(element.value, "@t");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("Autocomplete does not trigger with right-left arrow keys", async function (assert) {
|
||||||
|
const element = textArea();
|
||||||
|
|
||||||
|
$(element).autocomplete({
|
||||||
|
key: ":",
|
||||||
|
template,
|
||||||
|
transformComplete: (e) => e.slice(1),
|
||||||
|
dataSource: () => [":smile:"],
|
||||||
|
});
|
||||||
|
|
||||||
|
await simulateKeys(element, ":smi\t");
|
||||||
|
|
||||||
|
assert.dom(element).hasValue(":smile: ");
|
||||||
|
|
||||||
|
await triggerArrowKey(element, "ArrowLeft");
|
||||||
|
await triggerArrowKey(element, "ArrowLeft");
|
||||||
|
await triggerArrowKey(element, "ArrowLeft");
|
||||||
|
await triggerArrowKey(element, "ArrowRight");
|
||||||
|
|
||||||
|
assert.strictEqual(element.selectionStart, 6);
|
||||||
|
|
||||||
|
// This is passing, but it's a false positive
|
||||||
|
// triggerArrowKey isn't triggering the event the autocomplete listens to
|
||||||
|
assert.dom("#ac-testing").doesNotExist();
|
||||||
|
|
||||||
|
await triggerArrowKey(element, "ArrowRight");
|
||||||
|
await simulateKey(element, "\b");
|
||||||
|
|
||||||
|
assert.dom(element).hasValue(":smile ");
|
||||||
|
assert.dom("#ac-testing").exists();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
async function triggerArrowKey(element, key) {
|
||||||
|
await triggerKeyEvent(element, "keydown", key, { code: key });
|
||||||
|
await triggerKeyEvent(element, "keyup", key, { code: key });
|
||||||
|
|
||||||
|
const pos = element.selectionStart;
|
||||||
|
const direction = key === "ArrowLeft" ? -1 : 1;
|
||||||
|
element.setSelectionRange(pos + 1 * direction, pos + 1 * direction);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user