Commit 42092024 authored by Roman Nurik's avatar Roman Nurik
Browse files

Enable query highlighting and result ranking for search autocomplete on d.a.c....

Enable query highlighting and result ranking for search autocomplete on d.a.c. Also make it case-insensitive.

Change-Id: Ifa52bb48c7b03c9aa7ad03cfe3e0049024f71a8d
parent d9ec1f1c
......@@ -519,7 +519,7 @@ div.indent {
padding-right: 6px;
padding-top: 1px;
padding-bottom: 1px;
font-size: .8em;
font-size: 0.81em;
border: none;
margin: 0;
line-height: 1.05em;
......
......@@ -2,7 +2,7 @@ var gSelectedIndex = -1;
var gSelectedID = -1;
var gMatches = new Array();
var gLastText = "";
var ROW_COUNT = 30;
var ROW_COUNT = 20;
var gInitialized = false;
var DEFAULT_TEXT = "search developer docs";
......@@ -22,7 +22,7 @@ function set_row_selected(row, selected)
function set_row_values(toroot, row, match)
{
var link = row.cells[0].childNodes[0];
link.innerHTML = match.label;
link.innerHTML = match.__hilabel || match.label;
link.href = toroot + match.link
// row.cells[1].innerHTML = match.type;
}
......@@ -104,7 +104,7 @@ function sync_selection_table(toroot)
function search_changed(e, kd, toroot)
{
var search = document.getElementById("search_autocomplete");
var text = search.value;
var text = search.value.replace(/(^ +)|( +$)/g, '');
// 13 = enter
if (e.keyCode == 13) {
......@@ -137,21 +137,112 @@ function search_changed(e, kd, toroot)
gMatches = new Array();
matchedCount = 0;
gSelectedIndex = -1;
for (i=0; i<DATA.length; i++) {
for (var i=0; i<DATA.length; i++) {
var s = DATA[i];
if (text.length != 0 && s.label.indexOf(text) != -1) {
if (text.length != 0 &&
s.label.toLowerCase().indexOf(text.toLowerCase()) != -1) {
gMatches[matchedCount] = s;
if (gSelectedID == s.id) {
gSelectedIndex = matchedCount;
}
matchedCount++;
}
}
rank_autocomplete_results(text);
for (var i=0; i<gMatches.length; i++) {
var s = gMatches[i];
if (gSelectedID == s.id) {
gSelectedIndex = i;
}
}
highlight_autocomplete_result_labels(text);
sync_selection_table(toroot);
return true; // allow the event to bubble up to the search api
}
}
function rank_autocomplete_results(query) {
query = query || '';
if (!gMatches || !gMatches.length)
return;
// helper function that gets the last occurence index of the given regex
// in the given string, or -1 if not found
var _lastSearch = function(s, re) {
if (s == '')
return -1;
var l = -1;
var tmp;
while ((tmp = s.search(re)) >= 0) {
if (l < 0) l = 0;
l += tmp;
s = s.substr(tmp + 1);
}
return l;
};
// helper function that counts the occurrences of a given character in
// a given string
var _countChar = function(s, c) {
var n = 0;
for (var i=0; i<s.length; i++)
if (s.charAt(i) == c) ++n;
return n;
};
var queryLower = query.toLowerCase();
var queryAlnum = (queryLower.match(/\w+/) || [''])[0];
var partPrefixAlnumRE = new RegExp('\\b' + queryAlnum);
var partExactAlnumRE = new RegExp('\\b' + queryAlnum + '\\b');
var _resultScoreFn = function(result) {
// scores are calculated based on exact and prefix matches,
// and then number of path separators (dots) from the last
// match (i.e. favoring classes and deep package names)
var score = 1.0;
var labelLower = result.label.toLowerCase();
var t;
t = _lastSearch(labelLower, partExactAlnumRE);
if (t >= 0) {
// exact part match
var partsAfter = _countChar(labelLower.substr(t + 1), '.');
score *= 200 / (partsAfter + 1);
} else {
t = _lastSearch(labelLower, partPrefixAlnumRE);
if (t >= 0) {
// part prefix match
var partsAfter = _countChar(labelLower.substr(t + 1), '.');
score *= 20 / (partsAfter + 1);
}
}
return score;
};
for (var i=0; i<gMatches.length; i++) {
gMatches[i].__resultScore = _resultScoreFn(gMatches[i]);
}
gMatches.sort(function(a,b){
var n = b.__resultScore - a.__resultScore;
if (n == 0) // lexicographical sort if scores are the same
n = (a.label < b.label) ? -1 : 1;
return n;
});
}
function highlight_autocomplete_result_labels(query) {
query = query || '';
if (!gMatches || !gMatches.length)
return;
var queryLower = query.toLowerCase();
var queryAlnumDot = (queryLower.match(/[\w\.]+/) || [''])[0];
var queryRE = new RegExp(
'(' + queryAlnumDot.replace(/\./g, '\\.') + ')', 'ig');
for (var i=0; i<gMatches.length; i++) {
gMatches[i].__hilabel = gMatches[i].label.replace(
queryRE, '<b>$1</b>');
}
}
function search_focus_changed(obj, focused)
{
if (focused) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment