Annotation of embedaddon/confuse/doc/html/search/search.js, revision 1.1.1.1

1.1       misho       1: /*
                      2:  @licstart  The following is the entire license notice for the
                      3:  JavaScript code in this file.
                      4: 
                      5:  Copyright (C) 1997-2017 by Dimitri van Heesch
                      6: 
                      7:  This program is free software; you can redistribute it and/or modify
                      8:  it under the terms of the GNU General Public License as published by
                      9:  the Free Software Foundation; either version 2 of the License, or
                     10:  (at your option) any later version.
                     11: 
                     12:  This program is distributed in the hope that it will be useful,
                     13:  but WITHOUT ANY WARRANTY; without even the implied warranty of
                     14:  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     15:  GNU General Public License for more details.
                     16: 
                     17:  You should have received a copy of the GNU General Public License along
                     18:  with this program; if not, write to the Free Software Foundation, Inc.,
                     19:  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
                     20: 
                     21:  @licend  The above is the entire license notice
                     22:  for the JavaScript code in this file
                     23:  */
                     24: function convertToId(search)
                     25: {
                     26:   var result = '';
                     27:   for (i=0;i<search.length;i++)
                     28:   {
                     29:     var c = search.charAt(i);
                     30:     var cn = c.charCodeAt(0);
                     31:     if (c.match(/[a-z0-9\u0080-\uFFFF]/))
                     32:     {
                     33:       result+=c;
                     34:     }
                     35:     else if (cn<16)
                     36:     {
                     37:       result+="_0"+cn.toString(16);
                     38:     }
                     39:     else
                     40:     {
                     41:       result+="_"+cn.toString(16);
                     42:     }
                     43:   }
                     44:   return result;
                     45: }
                     46: 
                     47: function getXPos(item)
                     48: {
                     49:   var x = 0;
                     50:   if (item.offsetWidth)
                     51:   {
                     52:     while (item && item!=document.body)
                     53:     {
                     54:       x   += item.offsetLeft;
                     55:       item = item.offsetParent;
                     56:     }
                     57:   }
                     58:   return x;
                     59: }
                     60: 
                     61: function getYPos(item)
                     62: {
                     63:   var y = 0;
                     64:   if (item.offsetWidth)
                     65:   {
                     66:      while (item && item!=document.body)
                     67:      {
                     68:        y   += item.offsetTop;
                     69:        item = item.offsetParent;
                     70:      }
                     71:   }
                     72:   return y;
                     73: }
                     74: 
                     75: /* A class handling everything associated with the search panel.
                     76: 
                     77:    Parameters:
                     78:    name - The name of the global variable that will be
                     79:           storing this instance.  Is needed to be able to set timeouts.
                     80:    resultPath - path to use for external files
                     81: */
                     82: function SearchBox(name, resultsPath, inFrame, label)
                     83: {
                     84:   if (!name || !resultsPath) {  alert("Missing parameters to SearchBox."); }
                     85: 
                     86:   // ---------- Instance variables
                     87:   this.name                  = name;
                     88:   this.resultsPath           = resultsPath;
                     89:   this.keyTimeout            = 0;
                     90:   this.keyTimeoutLength      = 500;
                     91:   this.closeSelectionTimeout = 300;
                     92:   this.lastSearchValue       = "";
                     93:   this.lastResultsPage       = "";
                     94:   this.hideTimeout           = 0;
                     95:   this.searchIndex           = 0;
                     96:   this.searchActive          = false;
                     97:   this.insideFrame           = inFrame;
                     98:   this.searchLabel           = label;
                     99: 
                    100:   // ----------- DOM Elements
                    101: 
                    102:   this.DOMSearchField = function()
                    103:   {  return document.getElementById("MSearchField");  }
                    104: 
                    105:   this.DOMSearchSelect = function()
                    106:   {  return document.getElementById("MSearchSelect");  }
                    107: 
                    108:   this.DOMSearchSelectWindow = function()
                    109:   {  return document.getElementById("MSearchSelectWindow");  }
                    110: 
                    111:   this.DOMPopupSearchResults = function()
                    112:   {  return document.getElementById("MSearchResults");  }
                    113: 
                    114:   this.DOMPopupSearchResultsWindow = function()
                    115:   {  return document.getElementById("MSearchResultsWindow");  }
                    116: 
                    117:   this.DOMSearchClose = function()
                    118:   {  return document.getElementById("MSearchClose"); }
                    119: 
                    120:   this.DOMSearchBox = function()
                    121:   {  return document.getElementById("MSearchBox");  }
                    122: 
                    123:   // ------------ Event Handlers
                    124: 
                    125:   // Called when focus is added or removed from the search field.
                    126:   this.OnSearchFieldFocus = function(isActive)
                    127:   {
                    128:     this.Activate(isActive);
                    129:   }
                    130: 
                    131:   this.OnSearchSelectShow = function()
                    132:   {
                    133:     var searchSelectWindow = this.DOMSearchSelectWindow();
                    134:     var searchField        = this.DOMSearchSelect();
                    135: 
                    136:     if (this.insideFrame)
                    137:     {
                    138:       var left = getXPos(searchField);
                    139:       var top  = getYPos(searchField);
                    140:       left += searchField.offsetWidth + 6;
                    141:       top += searchField.offsetHeight;
                    142: 
                    143:       // show search selection popup
                    144:       searchSelectWindow.style.display='block';
                    145:       left -= searchSelectWindow.offsetWidth;
                    146:       searchSelectWindow.style.left =  left + 'px';
                    147:       searchSelectWindow.style.top  =  top  + 'px';
                    148:     }
                    149:     else
                    150:     {
                    151:       var left = getXPos(searchField);
                    152:       var top  = getYPos(searchField);
                    153:       top += searchField.offsetHeight;
                    154: 
                    155:       // show search selection popup
                    156:       searchSelectWindow.style.display='block';
                    157:       searchSelectWindow.style.left =  left + 'px';
                    158:       searchSelectWindow.style.top  =  top  + 'px';
                    159:     }
                    160: 
                    161:     // stop selection hide timer
                    162:     if (this.hideTimeout)
                    163:     {
                    164:       clearTimeout(this.hideTimeout);
                    165:       this.hideTimeout=0;
                    166:     }
                    167:     return false; // to avoid "image drag" default event
                    168:   }
                    169: 
                    170:   this.OnSearchSelectHide = function()
                    171:   {
                    172:     this.hideTimeout = setTimeout(this.name +".CloseSelectionWindow()",
                    173:                                   this.closeSelectionTimeout);
                    174:   }
                    175: 
                    176:   // Called when the content of the search field is changed.
                    177:   this.OnSearchFieldChange = function(evt)
                    178:   {
                    179:     if (this.keyTimeout) // kill running timer
                    180:     {
                    181:       clearTimeout(this.keyTimeout);
                    182:       this.keyTimeout = 0;
                    183:     }
                    184: 
                    185:     var e  = (evt) ? evt : window.event; // for IE
                    186:     if (e.keyCode==40 || e.keyCode==13)
                    187:     {
                    188:       if (e.shiftKey==1)
                    189:       {
                    190:         this.OnSearchSelectShow();
                    191:         var win=this.DOMSearchSelectWindow();
                    192:         for (i=0;i<win.childNodes.length;i++)
                    193:         {
                    194:           var child = win.childNodes[i]; // get span within a
                    195:           if (child.className=='SelectItem')
                    196:           {
                    197:             child.focus();
                    198:             return;
                    199:           }
                    200:         }
                    201:         return;
                    202:       }
                    203:       else if (window.frames.MSearchResults.searchResults)
                    204:       {
                    205:         var elem = window.frames.MSearchResults.searchResults.NavNext(0);
                    206:         if (elem) elem.focus();
                    207:       }
                    208:     }
                    209:     else if (e.keyCode==27) // Escape out of the search field
                    210:     {
                    211:       this.DOMSearchField().blur();
                    212:       this.DOMPopupSearchResultsWindow().style.display = 'none';
                    213:       this.DOMSearchClose().style.display = 'none';
                    214:       this.lastSearchValue = '';
                    215:       this.Activate(false);
                    216:       return;
                    217:     }
                    218: 
                    219:     // strip whitespaces
                    220:     var searchValue = this.DOMSearchField().value.replace(/ +/g, "");
                    221: 
                    222:     if (searchValue != this.lastSearchValue) // search value has changed
                    223:     {
                    224:       if (searchValue != "") // non-empty search
                    225:       {
                    226:         // set timer for search update
                    227:         this.keyTimeout = setTimeout(this.name + '.Search()',
                    228:                                      this.keyTimeoutLength);
                    229:       }
                    230:       else // empty search field
                    231:       {
                    232:         this.DOMPopupSearchResultsWindow().style.display = 'none';
                    233:         this.DOMSearchClose().style.display = 'none';
                    234:         this.lastSearchValue = '';
                    235:       }
                    236:     }
                    237:   }
                    238: 
                    239:   this.SelectItemCount = function(id)
                    240:   {
                    241:     var count=0;
                    242:     var win=this.DOMSearchSelectWindow();
                    243:     for (i=0;i<win.childNodes.length;i++)
                    244:     {
                    245:       var child = win.childNodes[i]; // get span within a
                    246:       if (child.className=='SelectItem')
                    247:       {
                    248:         count++;
                    249:       }
                    250:     }
                    251:     return count;
                    252:   }
                    253: 
                    254:   this.SelectItemSet = function(id)
                    255:   {
                    256:     var i,j=0;
                    257:     var win=this.DOMSearchSelectWindow();
                    258:     for (i=0;i<win.childNodes.length;i++)
                    259:     {
                    260:       var child = win.childNodes[i]; // get span within a
                    261:       if (child.className=='SelectItem')
                    262:       {
                    263:         var node = child.firstChild;
                    264:         if (j==id)
                    265:         {
                    266:           node.innerHTML='&#8226;';
                    267:         }
                    268:         else
                    269:         {
                    270:           node.innerHTML='&#160;';
                    271:         }
                    272:         j++;
                    273:       }
                    274:     }
                    275:   }
                    276: 
                    277:   // Called when an search filter selection is made.
                    278:   // set item with index id as the active item
                    279:   this.OnSelectItem = function(id)
                    280:   {
                    281:     this.searchIndex = id;
                    282:     this.SelectItemSet(id);
                    283:     var searchValue = this.DOMSearchField().value.replace(/ +/g, "");
                    284:     if (searchValue!="" && this.searchActive) // something was found -> do a search
                    285:     {
                    286:       this.Search();
                    287:     }
                    288:   }
                    289: 
                    290:   this.OnSearchSelectKey = function(evt)
                    291:   {
                    292:     var e = (evt) ? evt : window.event; // for IE
                    293:     if (e.keyCode==40 && this.searchIndex<this.SelectItemCount()) // Down
                    294:     {
                    295:       this.searchIndex++;
                    296:       this.OnSelectItem(this.searchIndex);
                    297:     }
                    298:     else if (e.keyCode==38 && this.searchIndex>0) // Up
                    299:     {
                    300:       this.searchIndex--;
                    301:       this.OnSelectItem(this.searchIndex);
                    302:     }
                    303:     else if (e.keyCode==13 || e.keyCode==27)
                    304:     {
                    305:       this.OnSelectItem(this.searchIndex);
                    306:       this.CloseSelectionWindow();
                    307:       this.DOMSearchField().focus();
                    308:     }
                    309:     return false;
                    310:   }
                    311: 
                    312:   // --------- Actions
                    313: 
                    314:   // Closes the results window.
                    315:   this.CloseResultsWindow = function()
                    316:   {
                    317:     this.DOMPopupSearchResultsWindow().style.display = 'none';
                    318:     this.DOMSearchClose().style.display = 'none';
                    319:     this.Activate(false);
                    320:   }
                    321: 
                    322:   this.CloseSelectionWindow = function()
                    323:   {
                    324:     this.DOMSearchSelectWindow().style.display = 'none';
                    325:   }
                    326: 
                    327:   // Performs a search.
                    328:   this.Search = function()
                    329:   {
                    330:     this.keyTimeout = 0;
                    331: 
                    332:     // strip leading whitespace
                    333:     var searchValue = this.DOMSearchField().value.replace(/^ +/, "");
                    334: 
                    335:     var code = searchValue.toLowerCase().charCodeAt(0);
                    336:     var idxChar = searchValue.substr(0, 1).toLowerCase();
                    337:     if ( 0xD800 <= code && code <= 0xDBFF && searchValue > 1) // surrogate pair
                    338:     {
                    339:       idxChar = searchValue.substr(0, 2);
                    340:     }
                    341: 
                    342:     var resultsPage;
                    343:     var resultsPageWithSearch;
                    344:     var hasResultsPage;
                    345: 
                    346:     var idx = indexSectionsWithContent[this.searchIndex].indexOf(idxChar);
                    347:     if (idx!=-1)
                    348:     {
                    349:        var hexCode=idx.toString(16);
                    350:        resultsPage = this.resultsPath + '/' + indexSectionNames[this.searchIndex] + '_' + hexCode + '.html';
                    351:        resultsPageWithSearch = resultsPage+'?'+escape(searchValue);
                    352:        hasResultsPage = true;
                    353:     }
                    354:     else // nothing available for this search term
                    355:     {
                    356:        resultsPage = this.resultsPath + '/nomatches.html';
                    357:        resultsPageWithSearch = resultsPage;
                    358:        hasResultsPage = false;
                    359:     }
                    360: 
                    361:     window.frames.MSearchResults.location = resultsPageWithSearch;
                    362:     var domPopupSearchResultsWindow = this.DOMPopupSearchResultsWindow();
                    363: 
                    364:     if (domPopupSearchResultsWindow.style.display!='block')
                    365:     {
                    366:        var domSearchBox = this.DOMSearchBox();
                    367:        this.DOMSearchClose().style.display = 'inline';
                    368:        if (this.insideFrame)
                    369:        {
                    370:          var domPopupSearchResults = this.DOMPopupSearchResults();
                    371:          domPopupSearchResultsWindow.style.position = 'relative';
                    372:          domPopupSearchResultsWindow.style.display  = 'block';
                    373:          var width = document.body.clientWidth - 8; // the -8 is for IE :-(
                    374:          domPopupSearchResultsWindow.style.width    = width + 'px';
                    375:          domPopupSearchResults.style.width          = width + 'px';
                    376:        }
                    377:        else
                    378:        {
                    379:          var domPopupSearchResults = this.DOMPopupSearchResults();
                    380:          var left = getXPos(domSearchBox) + 150; // domSearchBox.offsetWidth;
                    381:          var top  = getYPos(domSearchBox) + 20;  // domSearchBox.offsetHeight + 1;
                    382:          domPopupSearchResultsWindow.style.display = 'block';
                    383:          left -= domPopupSearchResults.offsetWidth;
                    384:          domPopupSearchResultsWindow.style.top     = top  + 'px';
                    385:          domPopupSearchResultsWindow.style.left    = left + 'px';
                    386:        }
                    387:     }
                    388: 
                    389:     this.lastSearchValue = searchValue;
                    390:     this.lastResultsPage = resultsPage;
                    391:   }
                    392: 
                    393:   // -------- Activation Functions
                    394: 
                    395:   // Activates or deactivates the search panel, resetting things to
                    396:   // their default values if necessary.
                    397:   this.Activate = function(isActive)
                    398:   {
                    399:     if (isActive || // open it
                    400:         this.DOMPopupSearchResultsWindow().style.display == 'block'
                    401:        )
                    402:     {
                    403:       this.DOMSearchBox().className = 'MSearchBoxActive';
                    404: 
                    405:       var searchField = this.DOMSearchField();
                    406: 
                    407:       if (searchField.value == this.searchLabel) // clear "Search" term upon entry
                    408:       {
                    409:         searchField.value = '';
                    410:         this.searchActive = true;
                    411:       }
                    412:     }
                    413:     else if (!isActive) // directly remove the panel
                    414:     {
                    415:       this.DOMSearchBox().className = 'MSearchBoxInactive';
                    416:       this.DOMSearchField().value   = this.searchLabel;
                    417:       this.searchActive             = false;
                    418:       this.lastSearchValue          = ''
                    419:       this.lastResultsPage          = '';
                    420:     }
                    421:   }
                    422: }
                    423: 
                    424: // -----------------------------------------------------------------------
                    425: 
                    426: // The class that handles everything on the search results page.
                    427: function SearchResults(name)
                    428: {
                    429:     // The number of matches from the last run of <Search()>.
                    430:     this.lastMatchCount = 0;
                    431:     this.lastKey = 0;
                    432:     this.repeatOn = false;
                    433: 
                    434:     // Toggles the visibility of the passed element ID.
                    435:     this.FindChildElement = function(id)
                    436:     {
                    437:       var parentElement = document.getElementById(id);
                    438:       var element = parentElement.firstChild;
                    439: 
                    440:       while (element && element!=parentElement)
                    441:       {
                    442:         if (element.nodeName == 'DIV' && element.className == 'SRChildren')
                    443:         {
                    444:           return element;
                    445:         }
                    446: 
                    447:         if (element.nodeName == 'DIV' && element.hasChildNodes())
                    448:         {
                    449:            element = element.firstChild;
                    450:         }
                    451:         else if (element.nextSibling)
                    452:         {
                    453:            element = element.nextSibling;
                    454:         }
                    455:         else
                    456:         {
                    457:           do
                    458:           {
                    459:             element = element.parentNode;
                    460:           }
                    461:           while (element && element!=parentElement && !element.nextSibling);
                    462: 
                    463:           if (element && element!=parentElement)
                    464:           {
                    465:             element = element.nextSibling;
                    466:           }
                    467:         }
                    468:       }
                    469:     }
                    470: 
                    471:     this.Toggle = function(id)
                    472:     {
                    473:       var element = this.FindChildElement(id);
                    474:       if (element)
                    475:       {
                    476:         if (element.style.display == 'block')
                    477:         {
                    478:           element.style.display = 'none';
                    479:         }
                    480:         else
                    481:         {
                    482:           element.style.display = 'block';
                    483:         }
                    484:       }
                    485:     }
                    486: 
                    487:     // Searches for the passed string.  If there is no parameter,
                    488:     // it takes it from the URL query.
                    489:     //
                    490:     // Always returns true, since other documents may try to call it
                    491:     // and that may or may not be possible.
                    492:     this.Search = function(search)
                    493:     {
                    494:       if (!search) // get search word from URL
                    495:       {
                    496:         search = window.location.search;
                    497:         search = search.substring(1);  // Remove the leading '?'
                    498:         search = unescape(search);
                    499:       }
                    500: 
                    501:       search = search.replace(/^ +/, ""); // strip leading spaces
                    502:       search = search.replace(/ +$/, ""); // strip trailing spaces
                    503:       search = search.toLowerCase();
                    504:       search = convertToId(search);
                    505: 
                    506:       var resultRows = document.getElementsByTagName("div");
                    507:       var matches = 0;
                    508: 
                    509:       var i = 0;
                    510:       while (i < resultRows.length)
                    511:       {
                    512:         var row = resultRows.item(i);
                    513:         if (row.className == "SRResult")
                    514:         {
                    515:           var rowMatchName = row.id.toLowerCase();
                    516:           rowMatchName = rowMatchName.replace(/^sr\d*_/, ''); // strip 'sr123_'
                    517: 
                    518:           if (search.length<=rowMatchName.length &&
                    519:              rowMatchName.substr(0, search.length)==search)
                    520:           {
                    521:             row.style.display = 'block';
                    522:             matches++;
                    523:           }
                    524:           else
                    525:           {
                    526:             row.style.display = 'none';
                    527:           }
                    528:         }
                    529:         i++;
                    530:       }
                    531:       document.getElementById("Searching").style.display='none';
                    532:       if (matches == 0) // no results
                    533:       {
                    534:         document.getElementById("NoMatches").style.display='block';
                    535:       }
                    536:       else // at least one result
                    537:       {
                    538:         document.getElementById("NoMatches").style.display='none';
                    539:       }
                    540:       this.lastMatchCount = matches;
                    541:       return true;
                    542:     }
                    543: 
                    544:     // return the first item with index index or higher that is visible
                    545:     this.NavNext = function(index)
                    546:     {
                    547:       var focusItem;
                    548:       while (1)
                    549:       {
                    550:         var focusName = 'Item'+index;
                    551:         focusItem = document.getElementById(focusName);
                    552:         if (focusItem && focusItem.parentNode.parentNode.style.display=='block')
                    553:         {
                    554:           break;
                    555:         }
                    556:         else if (!focusItem) // last element
                    557:         {
                    558:           break;
                    559:         }
                    560:         focusItem=null;
                    561:         index++;
                    562:       }
                    563:       return focusItem;
                    564:     }
                    565: 
                    566:     this.NavPrev = function(index)
                    567:     {
                    568:       var focusItem;
                    569:       while (1)
                    570:       {
                    571:         var focusName = 'Item'+index;
                    572:         focusItem = document.getElementById(focusName);
                    573:         if (focusItem && focusItem.parentNode.parentNode.style.display=='block')
                    574:         {
                    575:           break;
                    576:         }
                    577:         else if (!focusItem) // last element
                    578:         {
                    579:           break;
                    580:         }
                    581:         focusItem=null;
                    582:         index--;
                    583:       }
                    584:       return focusItem;
                    585:     }
                    586: 
                    587:     this.ProcessKeys = function(e)
                    588:     {
                    589:       if (e.type == "keydown")
                    590:       {
                    591:         this.repeatOn = false;
                    592:         this.lastKey = e.keyCode;
                    593:       }
                    594:       else if (e.type == "keypress")
                    595:       {
                    596:         if (!this.repeatOn)
                    597:         {
                    598:           if (this.lastKey) this.repeatOn = true;
                    599:           return false; // ignore first keypress after keydown
                    600:         }
                    601:       }
                    602:       else if (e.type == "keyup")
                    603:       {
                    604:         this.lastKey = 0;
                    605:         this.repeatOn = false;
                    606:       }
                    607:       return this.lastKey!=0;
                    608:     }
                    609: 
                    610:     this.Nav = function(evt,itemIndex)
                    611:     {
                    612:       var e  = (evt) ? evt : window.event; // for IE
                    613:       if (e.keyCode==13) return true;
                    614:       if (!this.ProcessKeys(e)) return false;
                    615: 
                    616:       if (this.lastKey==38) // Up
                    617:       {
                    618:         var newIndex = itemIndex-1;
                    619:         var focusItem = this.NavPrev(newIndex);
                    620:         if (focusItem)
                    621:         {
                    622:           var child = this.FindChildElement(focusItem.parentNode.parentNode.id);
                    623:           if (child && child.style.display == 'block') // children visible
                    624:           {
                    625:             var n=0;
                    626:             var tmpElem;
                    627:             while (1) // search for last child
                    628:             {
                    629:               tmpElem = document.getElementById('Item'+newIndex+'_c'+n);
                    630:               if (tmpElem)
                    631:               {
                    632:                 focusItem = tmpElem;
                    633:               }
                    634:               else // found it!
                    635:               {
                    636:                 break;
                    637:               }
                    638:               n++;
                    639:             }
                    640:           }
                    641:         }
                    642:         if (focusItem)
                    643:         {
                    644:           focusItem.focus();
                    645:         }
                    646:         else // return focus to search field
                    647:         {
                    648:            parent.document.getElementById("MSearchField").focus();
                    649:         }
                    650:       }
                    651:       else if (this.lastKey==40) // Down
                    652:       {
                    653:         var newIndex = itemIndex+1;
                    654:         var focusItem;
                    655:         var item = document.getElementById('Item'+itemIndex);
                    656:         var elem = this.FindChildElement(item.parentNode.parentNode.id);
                    657:         if (elem && elem.style.display == 'block') // children visible
                    658:         {
                    659:           focusItem = document.getElementById('Item'+itemIndex+'_c0');
                    660:         }
                    661:         if (!focusItem) focusItem = this.NavNext(newIndex);
                    662:         if (focusItem)  focusItem.focus();
                    663:       }
                    664:       else if (this.lastKey==39) // Right
                    665:       {
                    666:         var item = document.getElementById('Item'+itemIndex);
                    667:         var elem = this.FindChildElement(item.parentNode.parentNode.id);
                    668:         if (elem) elem.style.display = 'block';
                    669:       }
                    670:       else if (this.lastKey==37) // Left
                    671:       {
                    672:         var item = document.getElementById('Item'+itemIndex);
                    673:         var elem = this.FindChildElement(item.parentNode.parentNode.id);
                    674:         if (elem) elem.style.display = 'none';
                    675:       }
                    676:       else if (this.lastKey==27) // Escape
                    677:       {
                    678:         parent.searchBox.CloseResultsWindow();
                    679:         parent.document.getElementById("MSearchField").focus();
                    680:       }
                    681:       else if (this.lastKey==13) // Enter
                    682:       {
                    683:         return true;
                    684:       }
                    685:       return false;
                    686:     }
                    687: 
                    688:     this.NavChild = function(evt,itemIndex,childIndex)
                    689:     {
                    690:       var e  = (evt) ? evt : window.event; // for IE
                    691:       if (e.keyCode==13) return true;
                    692:       if (!this.ProcessKeys(e)) return false;
                    693: 
                    694:       if (this.lastKey==38) // Up
                    695:       {
                    696:         if (childIndex>0)
                    697:         {
                    698:           var newIndex = childIndex-1;
                    699:           document.getElementById('Item'+itemIndex+'_c'+newIndex).focus();
                    700:         }
                    701:         else // already at first child, jump to parent
                    702:         {
                    703:           document.getElementById('Item'+itemIndex).focus();
                    704:         }
                    705:       }
                    706:       else if (this.lastKey==40) // Down
                    707:       {
                    708:         var newIndex = childIndex+1;
                    709:         var elem = document.getElementById('Item'+itemIndex+'_c'+newIndex);
                    710:         if (!elem) // last child, jump to parent next parent
                    711:         {
                    712:           elem = this.NavNext(itemIndex+1);
                    713:         }
                    714:         if (elem)
                    715:         {
                    716:           elem.focus();
                    717:         }
                    718:       }
                    719:       else if (this.lastKey==27) // Escape
                    720:       {
                    721:         parent.searchBox.CloseResultsWindow();
                    722:         parent.document.getElementById("MSearchField").focus();
                    723:       }
                    724:       else if (this.lastKey==13) // Enter
                    725:       {
                    726:         return true;
                    727:       }
                    728:       return false;
                    729:     }
                    730: }
                    731: 
                    732: function setKeyActions(elem,action)
                    733: {
                    734:   elem.setAttribute('onkeydown',action);
                    735:   elem.setAttribute('onkeypress',action);
                    736:   elem.setAttribute('onkeyup',action);
                    737: }
                    738: 
                    739: function setClassAttr(elem,attr)
                    740: {
                    741:   elem.setAttribute('class',attr);
                    742:   elem.setAttribute('className',attr);
                    743: }
                    744: 
                    745: function createResults()
                    746: {
                    747:   var results = document.getElementById("SRResults");
                    748:   for (var e=0; e<searchData.length; e++)
                    749:   {
                    750:     var id = searchData[e][0];
                    751:     var srResult = document.createElement('div');
                    752:     srResult.setAttribute('id','SR_'+id);
                    753:     setClassAttr(srResult,'SRResult');
                    754:     var srEntry = document.createElement('div');
                    755:     setClassAttr(srEntry,'SREntry');
                    756:     var srLink = document.createElement('a');
                    757:     srLink.setAttribute('id','Item'+e);
                    758:     setKeyActions(srLink,'return searchResults.Nav(event,'+e+')');
                    759:     setClassAttr(srLink,'SRSymbol');
                    760:     srLink.innerHTML = searchData[e][1][0];
                    761:     srEntry.appendChild(srLink);
                    762:     if (searchData[e][1].length==2) // single result
                    763:     {
                    764:       srLink.setAttribute('href',searchData[e][1][1][0]);
                    765:       if (searchData[e][1][1][1])
                    766:       {
                    767:        srLink.setAttribute('target','_parent');
                    768:       }
                    769:       var srScope = document.createElement('span');
                    770:       setClassAttr(srScope,'SRScope');
                    771:       srScope.innerHTML = searchData[e][1][1][2];
                    772:       srEntry.appendChild(srScope);
                    773:     }
                    774:     else // multiple results
                    775:     {
                    776:       srLink.setAttribute('href','javascript:searchResults.Toggle("SR_'+id+'")');
                    777:       var srChildren = document.createElement('div');
                    778:       setClassAttr(srChildren,'SRChildren');
                    779:       for (var c=0; c<searchData[e][1].length-1; c++)
                    780:       {
                    781:         var srChild = document.createElement('a');
                    782:         srChild.setAttribute('id','Item'+e+'_c'+c);
                    783:         setKeyActions(srChild,'return searchResults.NavChild(event,'+e+','+c+')');
                    784:         setClassAttr(srChild,'SRScope');
                    785:         srChild.setAttribute('href',searchData[e][1][c+1][0]);
                    786:         if (searchData[e][1][c+1][1])
                    787:         {
                    788:          srChild.setAttribute('target','_parent');
                    789:         }
                    790:         srChild.innerHTML = searchData[e][1][c+1][2];
                    791:         srChildren.appendChild(srChild);
                    792:       }
                    793:       srEntry.appendChild(srChildren);
                    794:     }
                    795:     srResult.appendChild(srEntry);
                    796:     results.appendChild(srResult);
                    797:   }
                    798: }
                    799: 
                    800: function init_search()
                    801: {
                    802:   var results = document.getElementById("MSearchSelectWindow");
                    803:   for (var key in indexSectionLabels)
                    804:   {
                    805:     var link = document.createElement('a');
                    806:     link.setAttribute('class','SelectItem');
                    807:     link.setAttribute('onclick','searchBox.OnSelectItem('+key+')');
                    808:     link.href='javascript:void(0)';
                    809:     link.innerHTML='<span class="SelectionMark">&#160;</span>'+indexSectionLabels[key];
                    810:     results.appendChild(link);
                    811:   }
                    812:   searchBox.OnSelectItem(0);
                    813: }
                    814: /* @license-end */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>