Home | History | Annotate | Download | only in assets
      1 var gSelectedIndex = -1;
      2 var gSelectedID = -1;
      3 var gMatches = new Array();
      4 var gLastText = "";
      5 var ROW_COUNT = 20;
      6 var gInitialized = false;
      7 var DEFAULT_TEXT = "search developer docs";
      8 
      9 function set_row_selected(row, selected)
     10 {
     11     var c1 = row.cells[0];
     12   //  var c2 = row.cells[1];
     13     if (selected) {
     14         c1.className = "jd-autocomplete jd-selected";
     15   //      c2.className = "jd-autocomplete jd-selected jd-linktype";
     16     } else {
     17         c1.className = "jd-autocomplete";
     18   //      c2.className = "jd-autocomplete jd-linktype";
     19     }
     20 }
     21 
     22 function set_row_values(toroot, row, match)
     23 {
     24     var link = row.cells[0].childNodes[0];
     25     link.innerHTML = match.__hilabel || match.label;
     26     link.href = toroot + match.link
     27   //  row.cells[1].innerHTML = match.type;
     28 }
     29 
     30 function sync_selection_table(toroot)
     31 {
     32     var filtered = document.getElementById("search_filtered");
     33     var r; //TR DOM object
     34     var i; //TR iterator
     35     gSelectedID = -1;
     36 
     37     filtered.onmouseover = function() { 
     38         if(gSelectedIndex >= 0) {
     39           set_row_selected(this.rows[gSelectedIndex], false);
     40           gSelectedIndex = -1;
     41         }
     42     }
     43 
     44     //initialize the table; draw it for the first time (but not visible).
     45     if (!gInitialized) {
     46         for (i=0; i<ROW_COUNT; i++) {
     47             var r = filtered.insertRow(-1);
     48             var c1 = r.insertCell(-1);
     49         //    var c2 = r.insertCell(-1);
     50             c1.className = "jd-autocomplete";
     51          //   c2.className = "jd-autocomplete jd-linktype";
     52             var link = document.createElement("a");
     53             c1.onmousedown = function() {
     54                 window.location = this.firstChild.getAttribute("href");
     55             }
     56             c1.onmouseover = function() {
     57                 this.className = this.className + " jd-selected";
     58             }
     59             c1.onmouseout = function() {
     60                 this.className = "jd-autocomplete";
     61             }
     62             c1.appendChild(link);
     63         }
     64   /*      var r = filtered.insertRow(-1);
     65         var c1 = r.insertCell(-1);
     66         c1.className = "jd-autocomplete jd-linktype";
     67         c1.colSpan = 2; */
     68         gInitialized = true;
     69     }
     70 
     71     //if we have results, make the table visible and initialize result info
     72     if (gMatches.length > 0) {
     73         document.getElementById("search_filtered_div").className = "showing";
     74         var N = gMatches.length < ROW_COUNT ? gMatches.length : ROW_COUNT;
     75         for (i=0; i<N; i++) {
     76             r = filtered.rows[i];
     77             r.className = "show-row";
     78             set_row_values(toroot, r, gMatches[i]);
     79             set_row_selected(r, i == gSelectedIndex);
     80             if (i == gSelectedIndex) {
     81                 gSelectedID = gMatches[i].id;
     82             }
     83         }
     84         //start hiding rows that are no longer matches
     85         for (; i<ROW_COUNT; i++) {
     86             r = filtered.rows[i];
     87             r.className = "no-display";
     88         }
     89         //if there are more results we're not showing, so say so.
     90 /*      if (gMatches.length > ROW_COUNT) {
     91             r = filtered.rows[ROW_COUNT];
     92             r.className = "show-row";
     93             c1 = r.cells[0];
     94             c1.innerHTML = "plus " + (gMatches.length-ROW_COUNT) + " more"; 
     95         } else {
     96             filtered.rows[ROW_COUNT].className = "hide-row";
     97         }*/
     98     //if we have no results, hide the table
     99     } else {
    100         document.getElementById("search_filtered_div").className = "no-display";
    101     }
    102 }
    103 
    104 function search_changed(e, kd, toroot)
    105 {
    106     var search = document.getElementById("search_autocomplete");
    107     var text = search.value.replace(/(^ +)|( +$)/g, '');
    108 
    109     // 13 = enter
    110     if (e.keyCode == 13) {
    111         document.getElementById("search_filtered_div").className = "no-display";
    112         if (kd && gSelectedIndex >= 0) {
    113             window.location = toroot + gMatches[gSelectedIndex].link;
    114             return false;
    115         } else if (gSelectedIndex < 0) {
    116             return true;
    117         }
    118     }
    119     // 38 -- arrow up
    120     else if (kd && (e.keyCode == 38)) {
    121         if (gSelectedIndex >= 0) {
    122             gSelectedIndex--;
    123         }
    124         sync_selection_table(toroot);
    125         return false;
    126     }
    127     // 40 -- arrow down
    128     else if (kd && (e.keyCode == 40)) {
    129         if (gSelectedIndex < gMatches.length-1
    130                         && gSelectedIndex < ROW_COUNT-1) {
    131             gSelectedIndex++;
    132         }
    133         sync_selection_table(toroot);
    134         return false;
    135     }
    136     else if (!kd) {
    137         gMatches = new Array();
    138         matchedCount = 0;
    139         gSelectedIndex = -1;
    140         for (var i=0; i<DATA.length; i++) {
    141             var s = DATA[i];
    142             if (text.length != 0 &&
    143                   s.label.toLowerCase().indexOf(text.toLowerCase()) != -1) {
    144                 gMatches[matchedCount] = s;
    145                 matchedCount++;
    146             }
    147         }
    148         rank_autocomplete_results(text);
    149         for (var i=0; i<gMatches.length; i++) {
    150             var s = gMatches[i];
    151             if (gSelectedID == s.id) {
    152                 gSelectedIndex = i;
    153             }
    154         }
    155         highlight_autocomplete_result_labels(text);
    156         sync_selection_table(toroot);
    157         return true; // allow the event to bubble up to the search api
    158     }
    159 }
    160 
    161 function rank_autocomplete_results(query) {
    162     query = query || '';
    163     if (!gMatches || !gMatches.length)
    164       return;
    165 
    166     // helper function that gets the last occurence index of the given regex
    167     // in the given string, or -1 if not found
    168     var _lastSearch = function(s, re) {
    169       if (s == '')
    170         return -1;
    171       var l = -1;
    172       var tmp;
    173       while ((tmp = s.search(re)) >= 0) {
    174         if (l < 0) l = 0;
    175         l += tmp;
    176         s = s.substr(tmp + 1);
    177       }
    178       return l;
    179     };
    180 
    181     // helper function that counts the occurrences of a given character in
    182     // a given string
    183     var _countChar = function(s, c) {
    184       var n = 0;
    185       for (var i=0; i<s.length; i++)
    186         if (s.charAt(i) == c) ++n;
    187       return n;
    188     };
    189 
    190     var queryLower = query.toLowerCase();
    191     var queryAlnum = (queryLower.match(/\w+/) || [''])[0];
    192     var partPrefixAlnumRE = new RegExp('\\b' + queryAlnum);
    193     var partExactAlnumRE = new RegExp('\\b' + queryAlnum + '\\b');
    194 
    195     var _resultScoreFn = function(result) {
    196         // scores are calculated based on exact and prefix matches,
    197         // and then number of path separators (dots) from the last
    198         // match (i.e. favoring classes and deep package names)
    199         var score = 1.0;
    200         var labelLower = result.label.toLowerCase();
    201         var t;
    202         t = _lastSearch(labelLower, partExactAlnumRE);
    203         if (t >= 0) {
    204             // exact part match
    205             var partsAfter = _countChar(labelLower.substr(t + 1), '.');
    206             score *= 200 / (partsAfter + 1);
    207         } else {
    208             t = _lastSearch(labelLower, partPrefixAlnumRE);
    209             if (t >= 0) {
    210                 // part prefix match
    211                 var partsAfter = _countChar(labelLower.substr(t + 1), '.');
    212                 score *= 20 / (partsAfter + 1);
    213             }
    214         }
    215 
    216         return score;
    217     };
    218 
    219     for (var i=0; i<gMatches.length; i++) {
    220         gMatches[i].__resultScore = _resultScoreFn(gMatches[i]);
    221     }
    222 
    223     gMatches.sort(function(a,b){
    224         var n = b.__resultScore - a.__resultScore;
    225         if (n == 0) // lexicographical sort if scores are the same
    226             n = (a.label < b.label) ? -1 : 1;
    227         return n;
    228     });
    229 }
    230 
    231 function highlight_autocomplete_result_labels(query) {
    232     query = query || '';
    233     if (!gMatches || !gMatches.length)
    234       return;
    235 
    236     var queryLower = query.toLowerCase();
    237     var queryAlnumDot = (queryLower.match(/[\w\.]+/) || [''])[0];
    238     var queryRE = new RegExp(
    239         '(' + queryAlnumDot.replace(/\./g, '\\.') + ')', 'ig');
    240     for (var i=0; i<gMatches.length; i++) {
    241         gMatches[i].__hilabel = gMatches[i].label.replace(
    242             queryRE, '<b>$1</b>');
    243     }
    244 }
    245 
    246 function search_focus_changed(obj, focused)
    247 {
    248     if (focused) {
    249         if(obj.value == DEFAULT_TEXT){
    250             obj.value = "";
    251             obj.style.color="#000000";
    252         }
    253     } else {
    254         if(obj.value == ""){
    255           obj.value = DEFAULT_TEXT;
    256           obj.style.color="#aaaaaa";
    257         }
    258         document.getElementById("search_filtered_div").className = "no-display";
    259     }
    260 }
    261 
    262 function submit_search() {
    263   var query = document.getElementById('search_autocomplete').value;
    264   document.location = toRoot + 'search.html#q=' + query + '&t=0';
    265   return false;
    266 }
    267