Merge "Add optional commit event firing to gr-autocomplete"
diff --git a/polygerrit-ui/app/elements/core/gr-search-bar/gr-search-bar.html b/polygerrit-ui/app/elements/core/gr-search-bar/gr-search-bar.html
index 2b05d99..957b2ce 100644
--- a/polygerrit-ui/app/elements/core/gr-search-bar/gr-search-bar.html
+++ b/polygerrit-ui/app/elements/core/gr-search-bar/gr-search-bar.html
@@ -53,7 +53,8 @@
           on-commit="_handleInputCommit"
           allowNonSuggestedValues
           multi
-          borderless></gr-autocomplete>
+          borderless
+          tab-complete-without-commit></gr-autocomplete>
       <gr-button id="searchButton">Search</gr-button>
       <gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
     </form>
diff --git a/polygerrit-ui/app/elements/shared/gr-autocomplete/gr-autocomplete.js b/polygerrit-ui/app/elements/shared/gr-autocomplete/gr-autocomplete.js
index 60c7f25..4f3cd34 100644
--- a/polygerrit-ui/app/elements/shared/gr-autocomplete/gr-autocomplete.js
+++ b/polygerrit-ui/app/elements/shared/gr-autocomplete/gr-autocomplete.js
@@ -78,6 +78,15 @@
         value: false,
       },
 
+      /**
+       * When true, tab key autocompletes but does not fire the commit event.
+       * See Issue 4556.
+       */
+      tabCompleteWithoutCommit: {
+        type: Boolean,
+        value: false,
+      },
+
       value: Object,
 
       /**
@@ -185,7 +194,7 @@
         case 9: // Tab
           if (this._suggestions.length > 0) {
             e.preventDefault();
-            this._commit();
+            this._commit(this.tabCompleteWithoutCommit);
             this._suggestions = [];
           }
           break;
@@ -231,7 +240,14 @@
       this._commit();
     },
 
-    _commit: function() {
+    /**
+     * Commits the suggestion, optionally firing the commit event.
+     *
+     * @param {Boolean} silent Allows for silent committing of an autocomplete
+     *     suggestion in order to handle cases like tab-to-complete without
+     *     firing the commit event.
+     */
+    _commit: function(silent) {
       // Allow values that are not in suggestion list iff suggestions are empty.
       if (this._suggestions.length > 0) {
         this._updateValue(this._suggestions, this._index);
@@ -252,7 +268,9 @@
         }
       }
 
-      this.fire('commit', {value: value});
+      if (!silent) {
+        this.fire('commit', {value: value});
+      }
     },
   });
 })();
diff --git a/polygerrit-ui/app/elements/shared/gr-autocomplete/gr-autocomplete_test.html b/polygerrit-ui/app/elements/shared/gr-autocomplete/gr-autocomplete_test.html
index ccc578c..ba1cbd2 100644
--- a/polygerrit-ui/app/elements/shared/gr-autocomplete/gr-autocomplete_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-autocomplete/gr-autocomplete_test.html
@@ -252,5 +252,18 @@
       assert.isTrue(commitStub.called);
       commitStub.restore();
     });
+
+    test('tabCompleteWithoutCommit flag functions', function() {
+      var commitHandler = sinon.spy();
+      element.addEventListener('commit', commitHandler);
+      element._suggestions = ['tunnel snakes rule!'];
+      element.tabCompleteWithoutCommit = true;
+      MockInteractions.pressAndReleaseKeyOn(element.$.input, 9); // tab
+      assert.isFalse(commitHandler.called);
+      element.tabCompleteWithoutCommit = false;
+      element._suggestions = ['tunnel snakes rule!'];
+      MockInteractions.pressAndReleaseKeyOn(element.$.input, 9); // tab
+      assert.isTrue(commitHandler.called);
+    });
   });
 </script>