Revamp tab behavior in gr-autocomplete

Removes tab handling from gr-autocomplete when no special props are
applied, as this was causing issues with tab navigation in the reply
dialog.

Renames the tabCompleteWithoutCommit prop to just tabComplete, retains
the same behavior.

Bug: Issue 6645
Change-Id: I831f1e6df1f653c60509a762c31a11979799d055
This commit is contained in:
Kasper Nilsson
2017-07-05 16:31:01 -07:00
parent 0b55a0ca1f
commit d7d94dee02
3 changed files with 42 additions and 35 deletions

View File

@@ -56,7 +56,7 @@ limitations under the License.
multi
borderless
threshold="[[_threshold]]"
tab-complete-without-commit></gr-autocomplete>
tab-complete></gr-autocomplete>
<gr-button id="searchButton">Search</gr-button>
<gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
</form>

View File

@@ -87,9 +87,10 @@
/**
* When true, tab key autocompletes but does not fire the commit event.
* See Issue 4556.
* When false, tab key not caught, and focus is removed from the element.
* See Issue 4556, Issue 6645.
*/
tabCompleteWithoutCommit: {
tabComplete: {
type: Boolean,
value: false,
},
@@ -162,7 +163,7 @@
_handleItemSelect(e) {
let silent = false;
if (e.detail.trigger === 'tab' && this.tabCompleteWithoutCommit) {
if (e.detail.trigger === 'tab' && this.tabComplete) {
silent = true;
}
this._selected = e.detail.selected;
@@ -244,9 +245,11 @@
this._cancel();
break;
case 9: // Tab
if (this._suggestions.length > 0) {
if (this._suggestions.length > 0 && this.tabComplete) {
e.preventDefault();
this._handleInputCommit(this.tabCompleteWithoutCommit);
this._handleInputCommit(true);
} else {
this._focused = false;
}
break;
case 13: // Enter
@@ -269,9 +272,9 @@
}
},
_handleInputCommit(opt_tabCompleteWithoutCommit) {
_handleInputCommit(opt_tabComplete) {
this._selected = this.$.suggestions.getCursorTarget();
this._commit(opt_tabCompleteWithoutCommit);
this._commit(opt_tabComplete);
},
_updateValue(suggestion, suggestions) {

View File

@@ -257,28 +257,27 @@ limitations under the License.
});
});
test('tab key completes only when suggestions exist', () => {
const commitStub = sandbox.stub(element, '_commit');
element._suggestions = [];
MockInteractions.pressAndReleaseKeyOn(element.$.input, 9, null, 'tab');
assert.isFalse(commitStub.called);
element._suggestions = ['tunnel snakes rule!'];
MockInteractions.pressAndReleaseKeyOn(element.$.input, 9, null, 'tab');
assert.isTrue(commitStub.called);
assert.isTrue(element._focused);
});
test('tabCompleteWithoutCommit flag functions', () => {
test('tabComplete flag functions', () => {
// commitHandler checks for the commit event, whereas commitSpy checks for
// the _commit function of the element.
const commitHandler = sandbox.spy();
element.addEventListener('commit', commitHandler);
const commitSpy = sandbox.spy(element, '_commit');
element._focused = true;
element._suggestions = ['tunnel snakes rule!'];
element.tabCompleteWithoutCommit = true;
element.tabComplete = false;
MockInteractions.pressAndReleaseKeyOn(element.$.input, 9, null, 'tab');
assert.isFalse(commitHandler.called);
element.tabCompleteWithoutCommit = false;
element._suggestions = ['tunnel snakes rule!'];
assert.isFalse(commitSpy.called);
assert.isFalse(element._focused);
element.tabComplete = true;
element._focused = true;
MockInteractions.pressAndReleaseKeyOn(element.$.input, 9, null, 'tab');
assert.isTrue(commitHandler.called);
assert.isFalse(commitHandler.called);
assert.isTrue(commitSpy.called);
assert.isTrue(element._focused);
});
test('_focused flag properly triggered', done => {
@@ -320,24 +319,29 @@ limitations under the License.
test('tab in input does not call focus', () => {
element._suggestions = ['sugar bombs'];
focusSpy = sandbox.spy(element, 'focus');
MockInteractions.pressAndReleaseKeyOn(element.$.input, 9, null, 'tab');
flushAsynchronousOperations();
assert.isFalse(commitSpy.called);
assert.isFalse(focusSpy.called);
assert.equal(element._suggestions.length, 1);
element.tabComplete = true;
element._suggestions = ['tunnel snakes drool'];
MockInteractions.pressAndReleaseKeyOn(element.$.input, 9, null, 'tab');
flushAsynchronousOperations();
assert.isTrue(commitSpy.called);
assert.isFalse(focusSpy.called);
assert.equal(element._suggestions.length, 0);
element.tabCompleteWithoutCommit = true;
element._suggestions = ['tunnel snakes drool'];
MockInteractions.pressAndReleaseKeyOn(element.$.input, 9, null, 'tab');
assert.isFalse(focusSpy.called);
});
test('tab on suggestion, tabCompleteWithoutCommit = false', () => {
test('tab on suggestion, tabComplete = false', () => {
element._suggestions = [{name: 'sugar bombs'}];
element._focused = true;
// When tabCompleteWithoutCommit is false, do not focus.
element.tabCompleteWithoutCommit = false;
// When tabComplete is false, do not focus.
element.tabComplete = false;
focusSpy = sandbox.spy(element, 'focus');
Polymer.dom.flush();
assert.isFalse(element.$.suggestions.hidden);
@@ -350,11 +354,11 @@ limitations under the License.
assert.isFalse(focusSpy.called);
});
test('tab on suggestion, tabCompleteWithoutCommit = true', () => {
test('tab on suggestion, tabComplete = true', () => {
element._suggestions = [{name: 'sugar bombs'}];
element._focused = true;
// When tabCompleteWithoutCommit is true, focus.
element.tabCompleteWithoutCommit = true;
// When tabComplete is true, focus.
element.tabComplete = true;
focusSpy = sandbox.spy(element, 'focus');
Polymer.dom.flush();
assert.isFalse(element.$.suggestions.hidden);