d77248ac7e
Change-Id: Iad7d0f1955e5731ee9cebb8828a45bf3c297417b
266 lines
8.3 KiB
JavaScript
266 lines
8.3 KiB
JavaScript
var gSelectedIndex = -1;
|
|
var gSelectedID = -1;
|
|
var gMatches = new Array();
|
|
var gLastText = "";
|
|
var ROW_COUNT = 20;
|
|
var gInitialized = false;
|
|
var DEFAULT_TEXT = "search developer docs";
|
|
|
|
function set_row_selected(row, selected)
|
|
{
|
|
var c1 = row.cells[0];
|
|
// var c2 = row.cells[1];
|
|
if (selected) {
|
|
c1.className = "jd-autocomplete jd-selected";
|
|
// c2.className = "jd-autocomplete jd-selected jd-linktype";
|
|
} else {
|
|
c1.className = "jd-autocomplete";
|
|
// c2.className = "jd-autocomplete jd-linktype";
|
|
}
|
|
}
|
|
|
|
function set_row_values(toroot, row, match)
|
|
{
|
|
var link = row.cells[0].childNodes[0];
|
|
link.innerHTML = match.__hilabel || match.label;
|
|
link.href = toroot + match.link
|
|
// row.cells[1].innerHTML = match.type;
|
|
}
|
|
|
|
function sync_selection_table(toroot)
|
|
{
|
|
var filtered = document.getElementById("search_filtered");
|
|
var r; //TR DOM object
|
|
var i; //TR iterator
|
|
gSelectedID = -1;
|
|
|
|
filtered.onmouseover = function() {
|
|
if(gSelectedIndex >= 0) {
|
|
set_row_selected(this.rows[gSelectedIndex], false);
|
|
gSelectedIndex = -1;
|
|
}
|
|
}
|
|
|
|
//initialize the table; draw it for the first time (but not visible).
|
|
if (!gInitialized) {
|
|
for (i=0; i<ROW_COUNT; i++) {
|
|
var r = filtered.insertRow(-1);
|
|
var c1 = r.insertCell(-1);
|
|
// var c2 = r.insertCell(-1);
|
|
c1.className = "jd-autocomplete";
|
|
// c2.className = "jd-autocomplete jd-linktype";
|
|
var link = document.createElement("a");
|
|
c1.onmousedown = function() {
|
|
window.location = this.firstChild.getAttribute("href");
|
|
}
|
|
c1.onmouseover = function() {
|
|
this.className = this.className + " jd-selected";
|
|
}
|
|
c1.onmouseout = function() {
|
|
this.className = "jd-autocomplete";
|
|
}
|
|
c1.appendChild(link);
|
|
}
|
|
/* var r = filtered.insertRow(-1);
|
|
var c1 = r.insertCell(-1);
|
|
c1.className = "jd-autocomplete jd-linktype";
|
|
c1.colSpan = 2; */
|
|
gInitialized = true;
|
|
}
|
|
|
|
//if we have results, make the table visible and initialize result info
|
|
if (gMatches.length > 0) {
|
|
document.getElementById("search_filtered_div").className = "showing";
|
|
var N = gMatches.length < ROW_COUNT ? gMatches.length : ROW_COUNT;
|
|
for (i=0; i<N; i++) {
|
|
r = filtered.rows[i];
|
|
r.className = "show-row";
|
|
set_row_values(toroot, r, gMatches[i]);
|
|
set_row_selected(r, i == gSelectedIndex);
|
|
if (i == gSelectedIndex) {
|
|
gSelectedID = gMatches[i].id;
|
|
}
|
|
}
|
|
//start hiding rows that are no longer matches
|
|
for (; i<ROW_COUNT; i++) {
|
|
r = filtered.rows[i];
|
|
r.className = "no-display";
|
|
}
|
|
//if there are more results we're not showing, so say so.
|
|
/* if (gMatches.length > ROW_COUNT) {
|
|
r = filtered.rows[ROW_COUNT];
|
|
r.className = "show-row";
|
|
c1 = r.cells[0];
|
|
c1.innerHTML = "plus " + (gMatches.length-ROW_COUNT) + " more";
|
|
} else {
|
|
filtered.rows[ROW_COUNT].className = "hide-row";
|
|
}*/
|
|
//if we have no results, hide the table
|
|
} else {
|
|
document.getElementById("search_filtered_div").className = "no-display";
|
|
}
|
|
}
|
|
|
|
function search_changed(e, kd, toroot)
|
|
{
|
|
var search = document.getElementById("search_autocomplete");
|
|
var text = search.value.replace(/(^ +)|( +$)/g, '');
|
|
|
|
// 13 = enter
|
|
if (e.keyCode == 13) {
|
|
document.getElementById("search_filtered_div").className = "no-display";
|
|
if (kd && gSelectedIndex >= 0) {
|
|
window.location = toroot + gMatches[gSelectedIndex].link;
|
|
return false;
|
|
} else if (gSelectedIndex < 0) {
|
|
return true;
|
|
}
|
|
}
|
|
// 38 -- arrow up
|
|
else if (kd && (e.keyCode == 38)) {
|
|
if (gSelectedIndex >= 0) {
|
|
gSelectedIndex--;
|
|
}
|
|
sync_selection_table(toroot);
|
|
return false;
|
|
}
|
|
// 40 -- arrow down
|
|
else if (kd && (e.keyCode == 40)) {
|
|
if (gSelectedIndex < gMatches.length-1
|
|
&& gSelectedIndex < ROW_COUNT-1) {
|
|
gSelectedIndex++;
|
|
}
|
|
sync_selection_table(toroot);
|
|
return false;
|
|
}
|
|
else if (!kd) {
|
|
gMatches = new Array();
|
|
matchedCount = 0;
|
|
gSelectedIndex = -1;
|
|
for (var i=0; i<DATA.length; i++) {
|
|
var s = DATA[i];
|
|
if (text.length != 0 &&
|
|
s.label.toLowerCase().indexOf(text.toLowerCase()) != -1) {
|
|
gMatches[matchedCount] = s;
|
|
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) {
|
|
if(obj.value == DEFAULT_TEXT){
|
|
obj.value = "";
|
|
obj.style.color="#000000";
|
|
}
|
|
} else {
|
|
if(obj.value == ""){
|
|
obj.value = DEFAULT_TEXT;
|
|
obj.style.color="#aaaaaa";
|
|
}
|
|
document.getElementById("search_filtered_div").className = "no-display";
|
|
}
|
|
}
|
|
|
|
function submit_search() {
|
|
var query = document.getElementById('search_autocomplete').value;
|
|
document.location = toRoot + 'search.html#q=' + query + '&t=0';
|
|
return false;
|
|
}
|