typeahead: Rewrite query_matches_source_attrs to be obviously correct.

This restructures this fairly complicated function to a much cleaner
implementation, with fewer unnecessary variables and a cleaner flow.
While we're at it, we document the function.
This commit is contained in:
Tim Abbott 2018-03-01 14:35:38 -08:00
parent 245d65eb9e
commit 5edbcb87fd

View File

@ -49,31 +49,34 @@ function query_matches_language(query, lang) {
return lang.indexOf(query) !== -1; return lang.indexOf(query) !== -1;
} }
// This function match query with source's attributes. // This function attempts to match a query with source's attributes.
// * query is the user-entered search query
// * Source is the object we're matching from, e.g. a user object
// * match_attrs are the values associated with the target object that
// the entered string might be trying to match, e.g. for a user
// account, there might be 2 attrs: their full name and their email.
// * split_char is the separator for this syntax (e.g. ' ').
function query_matches_source_attrs(query, source, match_attrs, split_char) { function query_matches_source_attrs(query, source, match_attrs, split_char) {
var match_for_all_attrs; // If query doesn't contain a separator, we just want an exact
var i; // match where query is a substring of one of the target characers.
var j; return _.any(match_attrs, function (attr) {
if (query.indexOf(split_char) > 0) { var source_str = source[attr].toLowerCase();
var queries = query.split(split_char); if (query.indexOf(split_char) > 0) {
for (i = 0; i < queries.length - 1; i += 1) { // If there's a whitespace character in the query, then we
match_for_all_attrs = false; // require a perfect prefix match (e.g. for 'ab cd ef',
for (j = 0; j < match_attrs.length; j += 1) { // query needs to be e.g. 'ab c', not 'cd ef' or 'b cd
match_for_all_attrs = match_for_all_attrs || // ef', etc.).
(source[match_attrs[j]].toLowerCase().split(split_char)[i] === var queries = query.split(split_char);
queries[i]); var i;
} for (i = 0; i < queries.length - 1; i += 1) {
if (!match_for_all_attrs) { if (source_str.split(split_char)[i] !== queries[i]) {
return false; return false;
}
} }
return true;
} }
query = queries[i]; return source_str.indexOf(query) !== -1;
} });
for (j = 0, match_for_all_attrs = false; j < match_attrs.length; j += 1) {
match_for_all_attrs = match_for_all_attrs ||
(source[match_attrs[j]].toLowerCase().indexOf(query) !== -1);
}
return match_for_all_attrs;
} }
function query_matches_person(query, person) { function query_matches_person(query, person) {