diff --git a/lib/index.js b/lib/index.js index 04b8c24..cea163a 100644 --- a/lib/index.js +++ b/lib/index.js @@ -58,38 +58,47 @@ tags.filter = function(subtags) { }); }; -tags.search = function(description, all) { - var i, l, test, push, results = []; +tags.search = function(query, all) { + var test; - push = function(record) { - if (record.Subtag) { - results.push(new Subtag(record.Subtag, record.Type)); - } else if (all) { - results.push(new Tag(record.Tag)); - } - }; - - if ('string' === typeof description) { - description = description.toLowerCase(); + if ('function' === typeof query.test) { + test = function(description) { + return query.test(description); + }; - test = function(record) { - if (-1 !== record.Description.join(', ').toLowerCase().indexOf(description)) { - push(record); - } + // If the query is all lowercase, make a case-insensitive match. + } else if (query.toLowerCase() === query) { + test = function(description) { + return -1 !== description.toLowerCase().indexOf(query); }; - } else if ('function' === typeof description.test) { - test = function(record) { - if (description.test(record.Description.join(', '))) { - push(record); - } + } else { + test = function(description) { + return -1 !== description.indexOf(query); }; } - for (i = 0, l = registry.length; i < l; i++) { - test(registry[i]); - } + return registry.filter(function(record) { + if (!record.Subtag && !all) { + return false; + } - return results; + return record.Description.some(test); + + // Sort by matched description string length. + // This is a quick way to push precise matches towards the top. + }).sort(function(a, b) { + return Math.min.apply(Math, a.Description.filter(test).map(function(description) { + return description.length; + })) > Math.min.apply(Math, b.Description.filter(test).map(function(description) { + return description.length; + })); + }).map(function(record) { + if (record.Subtag) { + return new Subtag(record.Subtag, record.Type); + } + + return new Tag(record.Tag); + }); }; tags.languages = function(macrolanguage) {