Clear suggestions on autocomplete input change
The gr-autocomplete component re-evaluates suggestions on input changes
via an observer.
Since evaluating suggestions is typically asynchronous (and debounced)
there is a window of time between the keystroke that triggers the
re-evaluation and the time that the new suggestions populate the
`_suggestions` array (potentially replacing any old suggestions).
If a modestly fast typer has typed an input resulting in suggestions,
but then, in quick succession, typed additional text (invalidating the
suggestions and triggering a request for new ones) followed by a
"commit" keystroke (such as [Enter] or [Tab]), then the autocomplete may
incorrectly commit to one of the invalidated suggestions. Doing so would
revert the input value to the text that triggered the old suggestion,
effectively erasing the newly typed characters.
With this change, the suggestion list is eagerly emptied whenever new
input is typed. This ensures that the `_suggestions` array is empty
during the window that new suggestions are inbound.
Bug: Issue 8655
Change-Id: I85bb519985903af719ef287860c04cc97b6cbca8
(cherry picked from commit 8f3fa75325)
This commit is contained in:
committed by
Paladox none
parent
bd48870511
commit
e787f97a7b
@@ -291,6 +291,12 @@
|
||||
// For any normal keypress, return focus to the input to allow for
|
||||
// unbroken user input.
|
||||
this.$.input.inputElement.focus();
|
||||
|
||||
// Since this has been a normal keypress, the suggestions will have
|
||||
// been based on a previous input. Clear them. This prevents an
|
||||
// outdated suggestion from being used if the input keystroke is
|
||||
// immediately followed by a commit keystroke. @see Issue 8655
|
||||
this._suggestions = [];
|
||||
}
|
||||
this.fire('input-keydown', {keyCode: e.keyCode, input: this.$.input});
|
||||
},
|
||||
|
||||
@@ -350,6 +350,21 @@ limitations under the License.
|
||||
assert.isTrue(commitStub.calledOnce);
|
||||
});
|
||||
|
||||
test('issue 8655', () => {
|
||||
function makeSuggestion(s) { return {name: s, text: s, value: s}; }
|
||||
const keydownSpy = sandbox.spy(element, '_handleKeydown');
|
||||
element.setText('file:');
|
||||
element._suggestions =
|
||||
[makeSuggestion('file:'), makeSuggestion('-file:')];
|
||||
MockInteractions.pressAndReleaseKeyOn(element.$.input, 88, null, 'x');
|
||||
// Must set the value, because the MockInteraction does not.
|
||||
element.$.input.value = 'file:x';
|
||||
assert.isTrue(keydownSpy.calledOnce);
|
||||
MockInteractions.pressAndReleaseKeyOn(element.$.input, 13, null, 'enter');
|
||||
assert.isTrue(keydownSpy.calledTwice);
|
||||
assert.equal(element.text, 'file:x');
|
||||
});
|
||||
|
||||
suite('focus', () => {
|
||||
let commitSpy;
|
||||
let focusSpy;
|
||||
|
||||
Reference in New Issue
Block a user