Merge "Revert "Revert "Debounce autocomplete queries by default"""
This commit is contained in:
@@ -105,6 +105,7 @@ limitations under the License.
|
|||||||
<gr-autocomplete
|
<gr-autocomplete
|
||||||
id="parentInput"
|
id="parentInput"
|
||||||
query="[[_query]]"
|
query="[[_query]]"
|
||||||
|
no-debounce
|
||||||
text="{{_inputText}}"
|
text="{{_inputText}}"
|
||||||
on-tap="_handleEnterChangeNumberTap"
|
on-tap="_handleEnterChangeNumberTap"
|
||||||
on-commit="_handleBaseSelected"
|
on-commit="_handleBaseSelected"
|
||||||
|
|||||||
@@ -166,7 +166,8 @@ limitations under the License.
|
|||||||
|
|
||||||
test('input text change triggers function', () => {
|
test('input text change triggers function', () => {
|
||||||
sandbox.spy(element, '_getRecentChanges');
|
sandbox.spy(element, '_getRecentChanges');
|
||||||
element._inputText = '1';
|
element.$.parentInput.noDebounce = true;
|
||||||
|
element.$.parentInput.text = '1';
|
||||||
assert.isTrue(element._getRecentChanges.calledOnce);
|
assert.isTrue(element._getRecentChanges.calledOnce);
|
||||||
element._inputText = '12';
|
element._inputText = '12';
|
||||||
assert.isTrue(element._getRecentChanges.calledTwice);
|
assert.isTrue(element._getRecentChanges.calledTwice);
|
||||||
|
|||||||
@@ -48,7 +48,6 @@ limitations under the License.
|
|||||||
id="searchInput"
|
id="searchInput"
|
||||||
text="{{_inputVal}}"
|
text="{{_inputVal}}"
|
||||||
query="[[query]]"
|
query="[[query]]"
|
||||||
debounce-wait="200"
|
|
||||||
on-commit="_handleInputCommit"
|
on-commit="_handleInputCommit"
|
||||||
allow-non-suggested-values
|
allow-non-suggested-values
|
||||||
multi
|
multi
|
||||||
|
|||||||
@@ -61,12 +61,14 @@ suite('gr-edit-controls tests', () => {
|
|||||||
|
|
||||||
suite('edit button CUJ', () => {
|
suite('edit button CUJ', () => {
|
||||||
let navStubs;
|
let navStubs;
|
||||||
|
let openAutoCcmplete;
|
||||||
|
|
||||||
setup(() => {
|
setup(() => {
|
||||||
navStubs = [
|
navStubs = [
|
||||||
sandbox.stub(Gerrit.Nav, 'getEditUrlForDiff'),
|
sandbox.stub(Gerrit.Nav, 'getEditUrlForDiff'),
|
||||||
sandbox.stub(Gerrit.Nav, 'navigateToRelativeUrl'),
|
sandbox.stub(Gerrit.Nav, 'navigateToRelativeUrl'),
|
||||||
];
|
];
|
||||||
|
openAutoCcmplete = element.$.openDialog.querySelector('gr-autocomplete');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('_isValidPath', () => {
|
test('_isValidPath', () => {
|
||||||
@@ -84,8 +86,8 @@ suite('gr-edit-controls tests', () => {
|
|||||||
assert.isTrue(element._hideAllDialogs.called);
|
assert.isTrue(element._hideAllDialogs.called);
|
||||||
assert.isTrue(element.$.openDialog.disabled);
|
assert.isTrue(element.$.openDialog.disabled);
|
||||||
assert.isFalse(queryStub.called);
|
assert.isFalse(queryStub.called);
|
||||||
element.$.openDialog.querySelector('gr-autocomplete').text =
|
openAutoCcmplete.noDebounce = true;
|
||||||
'src/test.cpp';
|
openAutoCcmplete.text = 'src/test.cpp';
|
||||||
assert.isTrue(queryStub.called);
|
assert.isTrue(queryStub.called);
|
||||||
assert.isFalse(element.$.openDialog.disabled);
|
assert.isFalse(element.$.openDialog.disabled);
|
||||||
MockInteractions.tap(element.$.openDialog.$$('gr-button[primary]'));
|
MockInteractions.tap(element.$.openDialog.$$('gr-button[primary]'));
|
||||||
@@ -100,8 +102,8 @@ suite('gr-edit-controls tests', () => {
|
|||||||
MockInteractions.tap(element.$$('#open'));
|
MockInteractions.tap(element.$$('#open'));
|
||||||
return showDialogSpy.lastCall.returnValue.then(() => {
|
return showDialogSpy.lastCall.returnValue.then(() => {
|
||||||
assert.isTrue(element.$.openDialog.disabled);
|
assert.isTrue(element.$.openDialog.disabled);
|
||||||
element.$.openDialog.querySelector('gr-autocomplete').text =
|
openAutoCcmplete.noDebounce = true;
|
||||||
'src/test.cpp';
|
openAutoCcmplete.text = 'src/test.cpp';
|
||||||
assert.isFalse(element.$.openDialog.disabled);
|
assert.isFalse(element.$.openDialog.disabled);
|
||||||
MockInteractions.tap(element.$.openDialog.$$('gr-button'));
|
MockInteractions.tap(element.$.openDialog.$$('gr-button'));
|
||||||
for (const stub of navStubs) { assert.isFalse(stub.called); }
|
for (const stub of navStubs) { assert.isFalse(stub.called); }
|
||||||
@@ -114,10 +116,13 @@ suite('gr-edit-controls tests', () => {
|
|||||||
suite('delete button CUJ', () => {
|
suite('delete button CUJ', () => {
|
||||||
let navStub;
|
let navStub;
|
||||||
let deleteStub;
|
let deleteStub;
|
||||||
|
let deleteAutocomplete;
|
||||||
|
|
||||||
setup(() => {
|
setup(() => {
|
||||||
navStub = sandbox.stub(Gerrit.Nav, 'navigateToChange');
|
navStub = sandbox.stub(Gerrit.Nav, 'navigateToChange');
|
||||||
deleteStub = sandbox.stub(element.$.restAPI, 'deleteFileInChangeEdit');
|
deleteStub = sandbox.stub(element.$.restAPI, 'deleteFileInChangeEdit');
|
||||||
|
deleteAutocomplete =
|
||||||
|
element.$.deleteDialog.querySelector('gr-autocomplete');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('delete', () => {
|
test('delete', () => {
|
||||||
@@ -126,8 +131,8 @@ suite('gr-edit-controls tests', () => {
|
|||||||
return showDialogSpy.lastCall.returnValue.then(() => {
|
return showDialogSpy.lastCall.returnValue.then(() => {
|
||||||
assert.isTrue(element.$.deleteDialog.disabled);
|
assert.isTrue(element.$.deleteDialog.disabled);
|
||||||
assert.isFalse(queryStub.called);
|
assert.isFalse(queryStub.called);
|
||||||
element.$.deleteDialog.querySelector('gr-autocomplete').text =
|
deleteAutocomplete.noDebounce = true;
|
||||||
'src/test.cpp';
|
deleteAutocomplete.text = 'src/test.cpp';
|
||||||
assert.isTrue(queryStub.called);
|
assert.isTrue(queryStub.called);
|
||||||
assert.isFalse(element.$.deleteDialog.disabled);
|
assert.isFalse(element.$.deleteDialog.disabled);
|
||||||
MockInteractions.tap(element.$.deleteDialog.$$('gr-button[primary]'));
|
MockInteractions.tap(element.$.deleteDialog.$$('gr-button[primary]'));
|
||||||
@@ -149,8 +154,8 @@ suite('gr-edit-controls tests', () => {
|
|||||||
return showDialogSpy.lastCall.returnValue.then(() => {
|
return showDialogSpy.lastCall.returnValue.then(() => {
|
||||||
assert.isTrue(element.$.deleteDialog.disabled);
|
assert.isTrue(element.$.deleteDialog.disabled);
|
||||||
assert.isFalse(queryStub.called);
|
assert.isFalse(queryStub.called);
|
||||||
element.$.deleteDialog.querySelector('gr-autocomplete').text =
|
deleteAutocomplete.noDebounce = true;
|
||||||
'src/test.cpp';
|
deleteAutocomplete.text = 'src/test.cpp';
|
||||||
assert.isTrue(queryStub.called);
|
assert.isTrue(queryStub.called);
|
||||||
assert.isFalse(element.$.deleteDialog.disabled);
|
assert.isFalse(element.$.deleteDialog.disabled);
|
||||||
MockInteractions.tap(element.$.deleteDialog.$$('gr-button[primary]'));
|
MockInteractions.tap(element.$.deleteDialog.$$('gr-button[primary]'));
|
||||||
@@ -183,10 +188,13 @@ suite('gr-edit-controls tests', () => {
|
|||||||
suite('rename button CUJ', () => {
|
suite('rename button CUJ', () => {
|
||||||
let navStub;
|
let navStub;
|
||||||
let renameStub;
|
let renameStub;
|
||||||
|
let renameAutocomplete;
|
||||||
|
|
||||||
setup(() => {
|
setup(() => {
|
||||||
navStub = sandbox.stub(Gerrit.Nav, 'navigateToChange');
|
navStub = sandbox.stub(Gerrit.Nav, 'navigateToChange');
|
||||||
renameStub = sandbox.stub(element.$.restAPI, 'renameFileInChangeEdit');
|
renameStub = sandbox.stub(element.$.restAPI, 'renameFileInChangeEdit');
|
||||||
|
renameAutocomplete =
|
||||||
|
element.$.renameDialog.querySelector('gr-autocomplete');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('rename', () => {
|
test('rename', () => {
|
||||||
@@ -195,8 +203,8 @@ suite('gr-edit-controls tests', () => {
|
|||||||
return showDialogSpy.lastCall.returnValue.then(() => {
|
return showDialogSpy.lastCall.returnValue.then(() => {
|
||||||
assert.isTrue(element.$.renameDialog.disabled);
|
assert.isTrue(element.$.renameDialog.disabled);
|
||||||
assert.isFalse(queryStub.called);
|
assert.isFalse(queryStub.called);
|
||||||
element.$.renameDialog.querySelector('gr-autocomplete').text =
|
renameAutocomplete.noDebounce = true;
|
||||||
'src/test.cpp';
|
renameAutocomplete.text = 'src/test.cpp';
|
||||||
assert.isTrue(queryStub.called);
|
assert.isTrue(queryStub.called);
|
||||||
assert.isTrue(element.$.renameDialog.disabled);
|
assert.isTrue(element.$.renameDialog.disabled);
|
||||||
|
|
||||||
@@ -223,8 +231,8 @@ suite('gr-edit-controls tests', () => {
|
|||||||
return showDialogSpy.lastCall.returnValue.then(() => {
|
return showDialogSpy.lastCall.returnValue.then(() => {
|
||||||
assert.isTrue(element.$.renameDialog.disabled);
|
assert.isTrue(element.$.renameDialog.disabled);
|
||||||
assert.isFalse(queryStub.called);
|
assert.isFalse(queryStub.called);
|
||||||
element.$.renameDialog.querySelector('gr-autocomplete').text =
|
renameAutocomplete.noDebounce = true;
|
||||||
'src/test.cpp';
|
renameAutocomplete.text = 'src/test.cpp';
|
||||||
assert.isTrue(queryStub.called);
|
assert.isTrue(queryStub.called);
|
||||||
assert.isTrue(element.$.renameDialog.disabled);
|
assert.isTrue(element.$.renameDialog.disabled);
|
||||||
|
|
||||||
|
|||||||
@@ -96,7 +96,6 @@ limitations under the License.
|
|||||||
<th>
|
<th>
|
||||||
<gr-autocomplete
|
<gr-autocomplete
|
||||||
id="newProject"
|
id="newProject"
|
||||||
debounce-wait="200"
|
|
||||||
query="[[_query]]"
|
query="[[_query]]"
|
||||||
threshold="1"
|
threshold="1"
|
||||||
placeholder="Project"></gr-autocomplete>
|
placeholder="Project"></gr-autocomplete>
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const TOKENIZE_REGEX = /(?:[^\s"]+|"[^"]*")+/g;
|
const TOKENIZE_REGEX = /(?:[^\s"]+|"[^"]*")+/g;
|
||||||
|
const DEBOUNCE_WAIT_MS = 200;
|
||||||
|
|
||||||
Polymer({
|
Polymer({
|
||||||
is: 'gr-autocomplete',
|
is: 'gr-autocomplete',
|
||||||
@@ -132,12 +133,11 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The number of milliseconds to use as the debounce wait time. If null,
|
* When true, querying for suggestions is not debounced w/r/t keypresses
|
||||||
* no debouncing is used.
|
|
||||||
*/
|
*/
|
||||||
debounceWait: {
|
noDebounce: {
|
||||||
type: Number,
|
type: Boolean,
|
||||||
value: null,
|
value: false,
|
||||||
},
|
},
|
||||||
|
|
||||||
/** @type {?} */
|
/** @type {?} */
|
||||||
@@ -167,7 +167,7 @@
|
|||||||
|
|
||||||
observers: [
|
observers: [
|
||||||
'_maybeOpenDropdown(_suggestions, _focused)',
|
'_maybeOpenDropdown(_suggestions, _focused)',
|
||||||
'_updateSuggestions(text, threshold, debounceWait)',
|
'_updateSuggestions(text, threshold, noDebounce)',
|
||||||
],
|
],
|
||||||
|
|
||||||
attached() {
|
attached() {
|
||||||
@@ -176,6 +176,7 @@
|
|||||||
|
|
||||||
detached() {
|
detached() {
|
||||||
this.unlisten(document.body, 'tap', '_handleBodyTap');
|
this.unlisten(document.body, 'tap', '_handleBodyTap');
|
||||||
|
this.cancelDebouncer('update-suggestions');
|
||||||
},
|
},
|
||||||
|
|
||||||
get focusStart() {
|
get focusStart() {
|
||||||
@@ -219,7 +220,7 @@
|
|||||||
|
|
||||||
_onInputFocus() {
|
_onInputFocus() {
|
||||||
this._focused = true;
|
this._focused = true;
|
||||||
this._updateSuggestions(this.text, this.threshold, this.debounceWait);
|
this._updateSuggestions(this.text, this.threshold, this.noDebounce);
|
||||||
this.$.input.classList.remove('warnUncommitted');
|
this.$.input.classList.remove('warnUncommitted');
|
||||||
// Needed so that --paper-input-container-input updated style is applied.
|
// Needed so that --paper-input-container-input updated style is applied.
|
||||||
this.updateStyles();
|
this.updateStyles();
|
||||||
@@ -232,7 +233,7 @@
|
|||||||
this.updateStyles();
|
this.updateStyles();
|
||||||
},
|
},
|
||||||
|
|
||||||
_updateSuggestions(text, threshold, debounceWait) {
|
_updateSuggestions(text, threshold, noDebounce) {
|
||||||
if (this._disableSuggestions) { return; }
|
if (this._disableSuggestions) { return; }
|
||||||
if (text === undefined || text.length < threshold) {
|
if (text === undefined || text.length < threshold) {
|
||||||
this._suggestions = [];
|
this._suggestions = [];
|
||||||
@@ -257,10 +258,10 @@
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
if (debounceWait) {
|
if (noDebounce) {
|
||||||
this.debounce('update-suggestions', update, debounceWait);
|
|
||||||
} else {
|
|
||||||
update();
|
update();
|
||||||
|
} else {
|
||||||
|
this.debounce('update-suggestions', update, DEBOUNCE_WAIT_MS);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ limitations under the License.
|
|||||||
|
|
||||||
<test-fixture id="basic">
|
<test-fixture id="basic">
|
||||||
<template>
|
<template>
|
||||||
<gr-autocomplete></gr-autocomplete>
|
<gr-autocomplete no-debounce></gr-autocomplete>
|
||||||
</template>
|
</template>
|
||||||
</test-fixture>
|
</test-fixture>
|
||||||
|
|
||||||
@@ -236,7 +236,7 @@ limitations under the License.
|
|||||||
assert.isTrue(queryStub.called);
|
assert.isTrue(queryStub.called);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('debounceWait debounces the query', () => {
|
test('noDebounce=false debounces the query', () => {
|
||||||
const queryStub = sandbox.spy(() => {
|
const queryStub = sandbox.spy(() => {
|
||||||
return Promise.resolve([]);
|
return Promise.resolve([]);
|
||||||
});
|
});
|
||||||
@@ -244,11 +244,11 @@ limitations under the License.
|
|||||||
const debounceStub = sandbox.stub(element, 'debounce',
|
const debounceStub = sandbox.stub(element, 'debounce',
|
||||||
(name, cb) => { callback = cb; });
|
(name, cb) => { callback = cb; });
|
||||||
element.query = queryStub;
|
element.query = queryStub;
|
||||||
element.debounceWait = 100;
|
element.noDebounce = false;
|
||||||
element.text = 'a';
|
element.text = 'a';
|
||||||
assert.isFalse(queryStub.called);
|
assert.isFalse(queryStub.called);
|
||||||
assert.isTrue(debounceStub.called);
|
assert.isTrue(debounceStub.called);
|
||||||
assert.equal(debounceStub.lastCall.args[2], 100);
|
assert.equal(debounceStub.lastCall.args[2], 200);
|
||||||
assert.isFunction(callback);
|
assert.isFunction(callback);
|
||||||
callback();
|
callback();
|
||||||
assert.isTrue(queryStub.called);
|
assert.isTrue(queryStub.called);
|
||||||
|
|||||||
Reference in New Issue
Block a user