Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2810)

Unified Diff: dashboard/dashboard/static/fuzzy_autocomplete.html

Issue 2692243003: [dashboard] Use fuzzy autocomplete in autocomplete-box (Closed)
Patch Set: fix 2nd new presubmit Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: dashboard/dashboard/static/fuzzy_autocomplete.html
diff --git a/dashboard/dashboard/static/fuzzy_autocomplete.html b/dashboard/dashboard/static/fuzzy_autocomplete.html
new file mode 100644
index 0000000000000000000000000000000000000000..60de8905e1b3de9165cf67acdf33aafef98110fa
--- /dev/null
+++ b/dashboard/dashboard/static/fuzzy_autocomplete.html
@@ -0,0 +1,81 @@
+<!DOCTYPE html>
+<!--
+Copyright 2017 The Chromium Authors. All rights reserved.
+Use of this source code is governed by a BSD-style license that can be
+found in the LICENSE file.
+-->
+
+<script>
+'use strict';
+
+/** Support for fuzzy autocomplete suggestions. */
+var fuzzyAutocomplete = (function() {
+ var FuzzyAutocomplete = function(sourceList) {
+ this.sourceList_ = sourceList;
+ this.headItems_ = sourceList.filter(item => item.head);
+ this.items_ = sourceList.filter(item => !item.head);
+ };
+
+ FuzzyAutocomplete.prototype.search = function(target) {
+ if (target == null || target == undefined) {
+ return this.sourceList_;
+ }
+ var selector = new FuzzySelect(target, item => item.name);
+ var items = selector.filter(this.items_);
+ var groups = new Set(items.map(item => item.group));
+ var headItems = this.headItems_.filter(item => groups.has(item.name));
+ var results = [].concat(headItems).concat(items);
+
+ // We piggyback lexical sorting. We want to sort first by group name then
+ // by is/is not group header then by score and then finally by name.
+ var toKey = function(item) {
+ if (item.head) {
+ // The score doesn't matter for head items.
+ return [item.name, false, 0, item.name];
+ }
+ return [item.group || '', true, selector.score(item), item.name];
+ };
+
+ return results.map(item => [toKey(item), item]).sort().map(pair => pair[1]);
+ };
+
+ /**
+ * FuzzySelect tests items to see if they match a query.
+ * An item matches a query if all space seperated parts from the query are
+ * present in the item.
+ *
+ * The optional accessor function can be provided if the items are not plain
+ * strings. It is passed an item and should return a string for use in
+ * testing against the query.
+ */
+ var FuzzySelect = function(query, opt_accessor) {
+ this.accessor = opt_accessor || (s => s);
+ query = query.replace(new RegExp(' +'), ' ');
+ this.rs = query.split(' ').map(part => new RegExp(part));
+ };
+
+ FuzzySelect.prototype.filter = function(items) {
+ return items.filter(item => this.match(item));
+ };
+
+ FuzzySelect.prototype.match = function(item) {
+ return this.rs.every(r => r.exec(this.accessor(item)));
+ };
+
+ FuzzySelect.prototype.score = function(item) {
+ var score = 0; // Smaller is better.
+ for (var r of this.rs) {
+ var m = r.exec(this.accessor(item));
+ if (!m) return Number.POSITIVE_INFINITY;
+ score += m.index;
+ }
+ return score;
+ };
+
+ return {
+ FuzzyAutocomplete,
+ FuzzySelect,
+ };
+})();
+
+</script>
« no previous file with comments | « dashboard/dashboard/elements/autocomplete-box-test.html ('k') | dashboard/dashboard/static/fuzzy_autocomplete_test.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698