Blame templates/html/search.js

Packit 1c1d7e
/*
Packit 1c1d7e
 @licstart  The following is the entire license notice for the
Packit 1c1d7e
 JavaScript code in this file.
Packit 1c1d7e
Packit 1c1d7e
 Copyright (C) 1997-2017 by Dimitri van Heesch
Packit 1c1d7e
Packit 1c1d7e
 This program is free software; you can redistribute it and/or modify
Packit 1c1d7e
 it under the terms of the GNU General Public License as published by
Packit 1c1d7e
 the Free Software Foundation; either version 2 of the License, or
Packit 1c1d7e
 (at your option) any later version.
Packit 1c1d7e
Packit 1c1d7e
 This program is distributed in the hope that it will be useful,
Packit 1c1d7e
 but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 1c1d7e
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 1c1d7e
 GNU General Public License for more details.
Packit 1c1d7e
Packit 1c1d7e
 You should have received a copy of the GNU General Public License along
Packit 1c1d7e
 with this program; if not, write to the Free Software Foundation, Inc.,
Packit 1c1d7e
 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Packit 1c1d7e
Packit 1c1d7e
 @licend  The above is the entire license notice
Packit 1c1d7e
 for the JavaScript code in this file
Packit 1c1d7e
 */
Packit 1c1d7e
function convertToId(search)
Packit 1c1d7e
{
Packit 1c1d7e
  var result = '';
Packit 1c1d7e
  for (i=0;i
Packit 1c1d7e
  {
Packit 1c1d7e
    var c = search.charAt(i);
Packit 1c1d7e
    var cn = c.charCodeAt(0);
Packit 1c1d7e
    if (c.match(/[a-z0-9\u0080-\uFFFF]/))
Packit 1c1d7e
    {
Packit 1c1d7e
      result+=c;
Packit 1c1d7e
    }
Packit 1c1d7e
    else if (cn<16)
Packit 1c1d7e
    {
Packit 1c1d7e
      result+="_0"+cn.toString(16);
Packit 1c1d7e
    }
Packit 1c1d7e
    else
Packit 1c1d7e
    {
Packit 1c1d7e
      result+="_"+cn.toString(16);
Packit 1c1d7e
    }
Packit 1c1d7e
  }
Packit 1c1d7e
  return result;
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
function getXPos(item)
Packit 1c1d7e
{
Packit 1c1d7e
  var x = 0;
Packit 1c1d7e
  if (item.offsetWidth)
Packit 1c1d7e
  {
Packit 1c1d7e
    while (item && item!=document.body)
Packit 1c1d7e
    {
Packit 1c1d7e
      x   += item.offsetLeft;
Packit 1c1d7e
      item = item.offsetParent;
Packit 1c1d7e
    }
Packit 1c1d7e
  }
Packit 1c1d7e
  return x;
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
function getYPos(item)
Packit 1c1d7e
{
Packit 1c1d7e
  var y = 0;
Packit 1c1d7e
  if (item.offsetWidth)
Packit 1c1d7e
  {
Packit 1c1d7e
     while (item && item!=document.body)
Packit 1c1d7e
     {
Packit 1c1d7e
       y   += item.offsetTop;
Packit 1c1d7e
       item = item.offsetParent;
Packit 1c1d7e
     }
Packit 1c1d7e
  }
Packit 1c1d7e
  return y;
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
/* A class handling everything associated with the search panel.
Packit 1c1d7e
Packit 1c1d7e
   Parameters:
Packit 1c1d7e
   name - The name of the global variable that will be
Packit 1c1d7e
          storing this instance.  Is needed to be able to set timeouts.
Packit 1c1d7e
   resultPath - path to use for external files
Packit 1c1d7e
*/
Packit 1c1d7e
function SearchBox(name, resultsPath, inFrame, label)
Packit 1c1d7e
{
Packit 1c1d7e
  if (!name || !resultsPath) {  alert("Missing parameters to SearchBox."); }
Packit 1c1d7e
Packit 1c1d7e
  // ---------- Instance variables
Packit 1c1d7e
  this.name                  = name;
Packit 1c1d7e
  this.resultsPath           = resultsPath;
Packit 1c1d7e
  this.keyTimeout            = 0;
Packit 1c1d7e
  this.keyTimeoutLength      = 500;
Packit 1c1d7e
  this.closeSelectionTimeout = 300;
Packit 1c1d7e
  this.lastSearchValue       = "";
Packit 1c1d7e
  this.lastResultsPage       = "";
Packit 1c1d7e
  this.hideTimeout           = 0;
Packit 1c1d7e
  this.searchIndex           = 0;
Packit 1c1d7e
  this.searchActive          = false;
Packit 1c1d7e
  this.insideFrame           = inFrame;
Packit 1c1d7e
  this.searchLabel           = label;
Packit 1c1d7e
Packit 1c1d7e
  // ----------- DOM Elements
Packit 1c1d7e
Packit 1c1d7e
  this.DOMSearchField = function()
Packit 1c1d7e
  {  return document.getElementById("MSearchField");  }
Packit 1c1d7e
Packit 1c1d7e
  this.DOMSearchSelect = function()
Packit 1c1d7e
  {  return document.getElementById("MSearchSelect");  }
Packit 1c1d7e
Packit 1c1d7e
  this.DOMSearchSelectWindow = function()
Packit 1c1d7e
  {  return document.getElementById("MSearchSelectWindow");  }
Packit 1c1d7e
Packit 1c1d7e
  this.DOMPopupSearchResults = function()
Packit 1c1d7e
  {  return document.getElementById("MSearchResults");  }
Packit 1c1d7e
Packit 1c1d7e
  this.DOMPopupSearchResultsWindow = function()
Packit 1c1d7e
  {  return document.getElementById("MSearchResultsWindow");  }
Packit 1c1d7e
Packit 1c1d7e
  this.DOMSearchClose = function()
Packit 1c1d7e
  {  return document.getElementById("MSearchClose"); }
Packit 1c1d7e
Packit 1c1d7e
  this.DOMSearchBox = function()
Packit 1c1d7e
  {  return document.getElementById("MSearchBox");  }
Packit 1c1d7e
Packit 1c1d7e
  // ------------ Event Handlers
Packit 1c1d7e
Packit 1c1d7e
  // Called when focus is added or removed from the search field.
Packit 1c1d7e
  this.OnSearchFieldFocus = function(isActive)
Packit 1c1d7e
  {
Packit 1c1d7e
    this.Activate(isActive);
Packit 1c1d7e
  }
Packit 1c1d7e
Packit 1c1d7e
  this.OnSearchSelectShow = function()
Packit 1c1d7e
  {
Packit 1c1d7e
    var searchSelectWindow = this.DOMSearchSelectWindow();
Packit 1c1d7e
    var searchField        = this.DOMSearchSelect();
Packit 1c1d7e
Packit 1c1d7e
    if (this.insideFrame)
Packit 1c1d7e
    {
Packit 1c1d7e
      var left = getXPos(searchField);
Packit 1c1d7e
      var top  = getYPos(searchField);
Packit 1c1d7e
      left += searchField.offsetWidth + 6;
Packit 1c1d7e
      top += searchField.offsetHeight;
Packit 1c1d7e
Packit 1c1d7e
      // show search selection popup
Packit 1c1d7e
      searchSelectWindow.style.display='block';
Packit 1c1d7e
      left -= searchSelectWindow.offsetWidth;
Packit 1c1d7e
      searchSelectWindow.style.left =  left + 'px';
Packit 1c1d7e
      searchSelectWindow.style.top  =  top  + 'px';
Packit 1c1d7e
    }
Packit 1c1d7e
    else
Packit 1c1d7e
    {
Packit 1c1d7e
      var left = getXPos(searchField);
Packit 1c1d7e
      var top  = getYPos(searchField);
Packit 1c1d7e
      top += searchField.offsetHeight;
Packit 1c1d7e
Packit 1c1d7e
      // show search selection popup
Packit 1c1d7e
      searchSelectWindow.style.display='block';
Packit 1c1d7e
      searchSelectWindow.style.left =  left + 'px';
Packit 1c1d7e
      searchSelectWindow.style.top  =  top  + 'px';
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    // stop selection hide timer
Packit 1c1d7e
    if (this.hideTimeout)
Packit 1c1d7e
    {
Packit 1c1d7e
      clearTimeout(this.hideTimeout);
Packit 1c1d7e
      this.hideTimeout=0;
Packit 1c1d7e
    }
Packit 1c1d7e
    return false; // to avoid "image drag" default event
Packit 1c1d7e
  }
Packit 1c1d7e
Packit 1c1d7e
  this.OnSearchSelectHide = function()
Packit 1c1d7e
  {
Packit 1c1d7e
    this.hideTimeout = setTimeout(this.name +".CloseSelectionWindow()",
Packit 1c1d7e
                                  this.closeSelectionTimeout);
Packit 1c1d7e
  }
Packit 1c1d7e
Packit 1c1d7e
  // Called when the content of the search field is changed.
Packit 1c1d7e
  this.OnSearchFieldChange = function(evt)
Packit 1c1d7e
  {
Packit 1c1d7e
    if (this.keyTimeout) // kill running timer
Packit 1c1d7e
    {
Packit 1c1d7e
      clearTimeout(this.keyTimeout);
Packit 1c1d7e
      this.keyTimeout = 0;
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    var e  = (evt) ? evt : window.event; // for IE
Packit 1c1d7e
    if (e.keyCode==40 || e.keyCode==13)
Packit 1c1d7e
    {
Packit 1c1d7e
      if (e.shiftKey==1)
Packit 1c1d7e
      {
Packit 1c1d7e
        this.OnSearchSelectShow();
Packit 1c1d7e
        var win=this.DOMSearchSelectWindow();
Packit 1c1d7e
        for (i=0;i
Packit 1c1d7e
        {
Packit 1c1d7e
          var child = win.childNodes[i]; // get span within a
Packit 1c1d7e
          if (child.className=='SelectItem')
Packit 1c1d7e
          {
Packit 1c1d7e
            child.focus();
Packit 1c1d7e
            return;
Packit 1c1d7e
          }
Packit 1c1d7e
        }
Packit 1c1d7e
        return;
Packit 1c1d7e
      }
Packit 1c1d7e
      else if (window.frames.MSearchResults.searchResults)
Packit 1c1d7e
      {
Packit 1c1d7e
        var elem = window.frames.MSearchResults.searchResults.NavNext(0);
Packit 1c1d7e
        if (elem) elem.focus();
Packit 1c1d7e
      }
Packit 1c1d7e
    }
Packit 1c1d7e
    else if (e.keyCode==27) // Escape out of the search field
Packit 1c1d7e
    {
Packit 1c1d7e
      this.DOMSearchField().blur();
Packit 1c1d7e
      this.DOMPopupSearchResultsWindow().style.display = 'none';
Packit 1c1d7e
      this.DOMSearchClose().style.display = 'none';
Packit 1c1d7e
      this.lastSearchValue = '';
Packit 1c1d7e
      this.Activate(false);
Packit 1c1d7e
      return;
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    // strip whitespaces
Packit 1c1d7e
    var searchValue = this.DOMSearchField().value.replace(/ +/g, "");
Packit 1c1d7e
Packit 1c1d7e
    if (searchValue != this.lastSearchValue) // search value has changed
Packit 1c1d7e
    {
Packit 1c1d7e
      if (searchValue != "") // non-empty search
Packit 1c1d7e
      {
Packit 1c1d7e
        // set timer for search update
Packit 1c1d7e
        this.keyTimeout = setTimeout(this.name + '.Search()',
Packit 1c1d7e
                                     this.keyTimeoutLength);
Packit 1c1d7e
      }
Packit 1c1d7e
      else // empty search field
Packit 1c1d7e
      {
Packit 1c1d7e
        this.DOMPopupSearchResultsWindow().style.display = 'none';
Packit 1c1d7e
        this.DOMSearchClose().style.display = 'none';
Packit 1c1d7e
        this.lastSearchValue = '';
Packit 1c1d7e
      }
Packit 1c1d7e
    }
Packit 1c1d7e
  }
Packit 1c1d7e
Packit 1c1d7e
  this.SelectItemCount = function(id)
Packit 1c1d7e
  {
Packit 1c1d7e
    var count=0;
Packit 1c1d7e
    var win=this.DOMSearchSelectWindow();
Packit 1c1d7e
    for (i=0;i
Packit 1c1d7e
    {
Packit 1c1d7e
      var child = win.childNodes[i]; // get span within a
Packit 1c1d7e
      if (child.className=='SelectItem')
Packit 1c1d7e
      {
Packit 1c1d7e
        count++;
Packit 1c1d7e
      }
Packit 1c1d7e
    }
Packit 1c1d7e
    return count;
Packit 1c1d7e
  }
Packit 1c1d7e
Packit 1c1d7e
  this.SelectItemSet = function(id)
Packit 1c1d7e
  {
Packit 1c1d7e
    var i,j=0;
Packit 1c1d7e
    var win=this.DOMSearchSelectWindow();
Packit 1c1d7e
    for (i=0;i
Packit 1c1d7e
    {
Packit 1c1d7e
      var child = win.childNodes[i]; // get span within a
Packit 1c1d7e
      if (child.className=='SelectItem')
Packit 1c1d7e
      {
Packit 1c1d7e
        var node = child.firstChild;
Packit 1c1d7e
        if (j==id)
Packit 1c1d7e
        {
Packit 1c1d7e
          node.innerHTML='•';
Packit 1c1d7e
        }
Packit 1c1d7e
        else
Packit 1c1d7e
        {
Packit 1c1d7e
          node.innerHTML=' ';
Packit 1c1d7e
        }
Packit 1c1d7e
        j++;
Packit 1c1d7e
      }
Packit 1c1d7e
    }
Packit 1c1d7e
  }
Packit 1c1d7e
Packit 1c1d7e
  // Called when an search filter selection is made.
Packit 1c1d7e
  // set item with index id as the active item
Packit 1c1d7e
  this.OnSelectItem = function(id)
Packit 1c1d7e
  {
Packit 1c1d7e
    this.searchIndex = id;
Packit 1c1d7e
    this.SelectItemSet(id);
Packit 1c1d7e
    var searchValue = this.DOMSearchField().value.replace(/ +/g, "");
Packit 1c1d7e
    if (searchValue!="" && this.searchActive) // something was found -> do a search
Packit 1c1d7e
    {
Packit 1c1d7e
      this.Search();
Packit 1c1d7e
    }
Packit 1c1d7e
  }
Packit 1c1d7e
Packit 1c1d7e
  this.OnSearchSelectKey = function(evt)
Packit 1c1d7e
  {
Packit 1c1d7e
    var e = (evt) ? evt : window.event; // for IE
Packit 1c1d7e
    if (e.keyCode==40 && this.searchIndex
Packit 1c1d7e
    {
Packit 1c1d7e
      this.searchIndex++;
Packit 1c1d7e
      this.OnSelectItem(this.searchIndex);
Packit 1c1d7e
    }
Packit 1c1d7e
    else if (e.keyCode==38 && this.searchIndex>0) // Up
Packit 1c1d7e
    {
Packit 1c1d7e
      this.searchIndex--;
Packit 1c1d7e
      this.OnSelectItem(this.searchIndex);
Packit 1c1d7e
    }
Packit 1c1d7e
    else if (e.keyCode==13 || e.keyCode==27)
Packit 1c1d7e
    {
Packit 1c1d7e
      this.OnSelectItem(this.searchIndex);
Packit 1c1d7e
      this.CloseSelectionWindow();
Packit 1c1d7e
      this.DOMSearchField().focus();
Packit 1c1d7e
    }
Packit 1c1d7e
    return false;
Packit 1c1d7e
  }
Packit 1c1d7e
Packit 1c1d7e
  // --------- Actions
Packit 1c1d7e
Packit 1c1d7e
  // Closes the results window.
Packit 1c1d7e
  this.CloseResultsWindow = function()
Packit 1c1d7e
  {
Packit 1c1d7e
    this.DOMPopupSearchResultsWindow().style.display = 'none';
Packit 1c1d7e
    this.DOMSearchClose().style.display = 'none';
Packit 1c1d7e
    this.Activate(false);
Packit 1c1d7e
  }
Packit 1c1d7e
Packit 1c1d7e
  this.CloseSelectionWindow = function()
Packit 1c1d7e
  {
Packit 1c1d7e
    this.DOMSearchSelectWindow().style.display = 'none';
Packit 1c1d7e
  }
Packit 1c1d7e
Packit 1c1d7e
  // Performs a search.
Packit 1c1d7e
  this.Search = function()
Packit 1c1d7e
  {
Packit 1c1d7e
    this.keyTimeout = 0;
Packit 1c1d7e
Packit 1c1d7e
    // strip leading whitespace
Packit 1c1d7e
    var searchValue = this.DOMSearchField().value.replace(/^ +/, "");
Packit 1c1d7e
Packit 1c1d7e
    var code = searchValue.toLowerCase().charCodeAt(0);
Packit 1c1d7e
    var idxChar = searchValue.substr(0, 1).toLowerCase();
Packit 1c1d7e
    if ( 0xD800 <= code && code <= 0xDBFF && searchValue > 1) // surrogate pair
Packit 1c1d7e
    {
Packit 1c1d7e
      idxChar = searchValue.substr(0, 2);
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    var resultsPage;
Packit 1c1d7e
    var resultsPageWithSearch;
Packit 1c1d7e
    var hasResultsPage;
Packit 1c1d7e
Packit 1c1d7e
    var idx = indexSectionsWithContent[this.searchIndex].indexOf(idxChar);
Packit 1c1d7e
    if (idx!=-1)
Packit 1c1d7e
    {
Packit 1c1d7e
       var hexCode=idx.toString(16);
Packit 1c1d7e
       resultsPage = this.resultsPath + '/' + indexSectionNames[this.searchIndex] + '_' + hexCode + '.html';
Packit 1c1d7e
       resultsPageWithSearch = resultsPage+'?'+escape(searchValue);
Packit 1c1d7e
       hasResultsPage = true;
Packit 1c1d7e
    }
Packit 1c1d7e
    else // nothing available for this search term
Packit 1c1d7e
    {
Packit 1c1d7e
       resultsPage = this.resultsPath + '/nomatches.html';
Packit 1c1d7e
       resultsPageWithSearch = resultsPage;
Packit 1c1d7e
       hasResultsPage = false;
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    window.frames.MSearchResults.location = resultsPageWithSearch;
Packit 1c1d7e
    var domPopupSearchResultsWindow = this.DOMPopupSearchResultsWindow();
Packit 1c1d7e
Packit 1c1d7e
    if (domPopupSearchResultsWindow.style.display!='block')
Packit 1c1d7e
    {
Packit 1c1d7e
       var domSearchBox = this.DOMSearchBox();
Packit 1c1d7e
       this.DOMSearchClose().style.display = 'inline';
Packit 1c1d7e
       if (this.insideFrame)
Packit 1c1d7e
       {
Packit 1c1d7e
         var domPopupSearchResults = this.DOMPopupSearchResults();
Packit 1c1d7e
         domPopupSearchResultsWindow.style.position = 'relative';
Packit 1c1d7e
         domPopupSearchResultsWindow.style.display  = 'block';
Packit 1c1d7e
         var width = document.body.clientWidth - 8; // the -8 is for IE :-(
Packit 1c1d7e
         domPopupSearchResultsWindow.style.width    = width + 'px';
Packit 1c1d7e
         domPopupSearchResults.style.width          = width + 'px';
Packit 1c1d7e
       }
Packit 1c1d7e
       else
Packit 1c1d7e
       {
Packit 1c1d7e
         var domPopupSearchResults = this.DOMPopupSearchResults();
Packit 1c1d7e
         var left = getXPos(domSearchBox) + 150; // domSearchBox.offsetWidth;
Packit 1c1d7e
         var top  = getYPos(domSearchBox) + 20;  // domSearchBox.offsetHeight + 1;
Packit 1c1d7e
         domPopupSearchResultsWindow.style.display = 'block';
Packit 1c1d7e
         left -= domPopupSearchResults.offsetWidth;
Packit 1c1d7e
         domPopupSearchResultsWindow.style.top     = top  + 'px';
Packit 1c1d7e
         domPopupSearchResultsWindow.style.left    = left + 'px';
Packit 1c1d7e
       }
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    this.lastSearchValue = searchValue;
Packit 1c1d7e
    this.lastResultsPage = resultsPage;
Packit 1c1d7e
  }
Packit 1c1d7e
Packit 1c1d7e
  // -------- Activation Functions
Packit 1c1d7e
Packit 1c1d7e
  // Activates or deactivates the search panel, resetting things to
Packit 1c1d7e
  // their default values if necessary.
Packit 1c1d7e
  this.Activate = function(isActive)
Packit 1c1d7e
  {
Packit 1c1d7e
    if (isActive || // open it
Packit 1c1d7e
        this.DOMPopupSearchResultsWindow().style.display == 'block'
Packit 1c1d7e
       )
Packit 1c1d7e
    {
Packit 1c1d7e
      this.DOMSearchBox().className = 'MSearchBoxActive';
Packit 1c1d7e
Packit 1c1d7e
      var searchField = this.DOMSearchField();
Packit 1c1d7e
Packit 1c1d7e
      if (searchField.value == this.searchLabel) // clear "Search" term upon entry
Packit 1c1d7e
      {
Packit 1c1d7e
        searchField.value = '';
Packit 1c1d7e
        this.searchActive = true;
Packit 1c1d7e
      }
Packit 1c1d7e
    }
Packit 1c1d7e
    else if (!isActive) // directly remove the panel
Packit 1c1d7e
    {
Packit 1c1d7e
      this.DOMSearchBox().className = 'MSearchBoxInactive';
Packit 1c1d7e
      this.DOMSearchField().value   = this.searchLabel;
Packit 1c1d7e
      this.searchActive             = false;
Packit 1c1d7e
      this.lastSearchValue          = ''
Packit 1c1d7e
      this.lastResultsPage          = '';
Packit 1c1d7e
    }
Packit 1c1d7e
  }
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
// -----------------------------------------------------------------------
Packit 1c1d7e
Packit 1c1d7e
// The class that handles everything on the search results page.
Packit 1c1d7e
function SearchResults(name)
Packit 1c1d7e
{
Packit 1c1d7e
    // The number of matches from the last run of <Search()>.
Packit 1c1d7e
    this.lastMatchCount = 0;
Packit 1c1d7e
    this.lastKey = 0;
Packit 1c1d7e
    this.repeatOn = false;
Packit 1c1d7e
Packit 1c1d7e
    // Toggles the visibility of the passed element ID.
Packit 1c1d7e
    this.FindChildElement = function(id)
Packit 1c1d7e
    {
Packit 1c1d7e
      var parentElement = document.getElementById(id);
Packit 1c1d7e
      var element = parentElement.firstChild;
Packit 1c1d7e
Packit 1c1d7e
      while (element && element!=parentElement)
Packit 1c1d7e
      {
Packit 1c1d7e
        if (element.nodeName == 'DIV' && element.className == 'SRChildren')
Packit 1c1d7e
        {
Packit 1c1d7e
          return element;
Packit 1c1d7e
        }
Packit 1c1d7e
Packit 1c1d7e
        if (element.nodeName == 'DIV' && element.hasChildNodes())
Packit 1c1d7e
        {
Packit 1c1d7e
           element = element.firstChild;
Packit 1c1d7e
        }
Packit 1c1d7e
        else if (element.nextSibling)
Packit 1c1d7e
        {
Packit 1c1d7e
           element = element.nextSibling;
Packit 1c1d7e
        }
Packit 1c1d7e
        else
Packit 1c1d7e
        {
Packit 1c1d7e
          do
Packit 1c1d7e
          {
Packit 1c1d7e
            element = element.parentNode;
Packit 1c1d7e
          }
Packit 1c1d7e
          while (element && element!=parentElement && !element.nextSibling);
Packit 1c1d7e
Packit 1c1d7e
          if (element && element!=parentElement)
Packit 1c1d7e
          {
Packit 1c1d7e
            element = element.nextSibling;
Packit 1c1d7e
          }
Packit 1c1d7e
        }
Packit 1c1d7e
      }
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    this.Toggle = function(id)
Packit 1c1d7e
    {
Packit 1c1d7e
      var element = this.FindChildElement(id);
Packit 1c1d7e
      if (element)
Packit 1c1d7e
      {
Packit 1c1d7e
        if (element.style.display == 'block')
Packit 1c1d7e
        {
Packit 1c1d7e
          element.style.display = 'none';
Packit 1c1d7e
        }
Packit 1c1d7e
        else
Packit 1c1d7e
        {
Packit 1c1d7e
          element.style.display = 'block';
Packit 1c1d7e
        }
Packit 1c1d7e
      }
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    // Searches for the passed string.  If there is no parameter,
Packit 1c1d7e
    // it takes it from the URL query.
Packit 1c1d7e
    //
Packit 1c1d7e
    // Always returns true, since other documents may try to call it
Packit 1c1d7e
    // and that may or may not be possible.
Packit 1c1d7e
    this.Search = function(search)
Packit 1c1d7e
    {
Packit 1c1d7e
      if (!search) // get search word from URL
Packit 1c1d7e
      {
Packit 1c1d7e
        search = window.location.search;
Packit 1c1d7e
        search = search.substring(1);  // Remove the leading '?'
Packit 1c1d7e
        search = unescape(search);
Packit 1c1d7e
      }
Packit 1c1d7e
Packit 1c1d7e
      search = search.replace(/^ +/, ""); // strip leading spaces
Packit 1c1d7e
      search = search.replace(/ +$/, ""); // strip trailing spaces
Packit 1c1d7e
      search = search.toLowerCase();
Packit 1c1d7e
      search = convertToId(search);
Packit 1c1d7e
Packit 1c1d7e
      var resultRows = document.getElementsByTagName("div");
Packit 1c1d7e
      var matches = 0;
Packit 1c1d7e
Packit 1c1d7e
      var i = 0;
Packit 1c1d7e
      while (i < resultRows.length)
Packit 1c1d7e
      {
Packit 1c1d7e
        var row = resultRows.item(i);
Packit 1c1d7e
        if (row.className == "SRResult")
Packit 1c1d7e
        {
Packit 1c1d7e
          var rowMatchName = row.id.toLowerCase();
Packit 1c1d7e
          rowMatchName = rowMatchName.replace(/^sr\d*_/, ''); // strip 'sr123_'
Packit 1c1d7e
Packit 1c1d7e
          if (search.length<=rowMatchName.length &&
Packit 1c1d7e
             rowMatchName.substr(0, search.length)==search)
Packit 1c1d7e
          {
Packit 1c1d7e
            row.style.display = 'block';
Packit 1c1d7e
            matches++;
Packit 1c1d7e
          }
Packit 1c1d7e
          else
Packit 1c1d7e
          {
Packit 1c1d7e
            row.style.display = 'none';
Packit 1c1d7e
          }
Packit 1c1d7e
        }
Packit 1c1d7e
        i++;
Packit 1c1d7e
      }
Packit 1c1d7e
      document.getElementById("Searching").style.display='none';
Packit 1c1d7e
      if (matches == 0) // no results
Packit 1c1d7e
      {
Packit 1c1d7e
        document.getElementById("NoMatches").style.display='block';
Packit 1c1d7e
      }
Packit 1c1d7e
      else // at least one result
Packit 1c1d7e
      {
Packit 1c1d7e
        document.getElementById("NoMatches").style.display='none';
Packit 1c1d7e
      }
Packit 1c1d7e
      this.lastMatchCount = matches;
Packit 1c1d7e
      return true;
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    // return the first item with index index or higher that is visible
Packit 1c1d7e
    this.NavNext = function(index)
Packit 1c1d7e
    {
Packit 1c1d7e
      var focusItem;
Packit 1c1d7e
      while (1)
Packit 1c1d7e
      {
Packit 1c1d7e
        var focusName = 'Item'+index;
Packit 1c1d7e
        focusItem = document.getElementById(focusName);
Packit 1c1d7e
        if (focusItem && focusItem.parentNode.parentNode.style.display=='block')
Packit 1c1d7e
        {
Packit 1c1d7e
          break;
Packit 1c1d7e
        }
Packit 1c1d7e
        else if (!focusItem) // last element
Packit 1c1d7e
        {
Packit 1c1d7e
          break;
Packit 1c1d7e
        }
Packit 1c1d7e
        focusItem=null;
Packit 1c1d7e
        index++;
Packit 1c1d7e
      }
Packit 1c1d7e
      return focusItem;
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    this.NavPrev = function(index)
Packit 1c1d7e
    {
Packit 1c1d7e
      var focusItem;
Packit 1c1d7e
      while (1)
Packit 1c1d7e
      {
Packit 1c1d7e
        var focusName = 'Item'+index;
Packit 1c1d7e
        focusItem = document.getElementById(focusName);
Packit 1c1d7e
        if (focusItem && focusItem.parentNode.parentNode.style.display=='block')
Packit 1c1d7e
        {
Packit 1c1d7e
          break;
Packit 1c1d7e
        }
Packit 1c1d7e
        else if (!focusItem) // last element
Packit 1c1d7e
        {
Packit 1c1d7e
          break;
Packit 1c1d7e
        }
Packit 1c1d7e
        focusItem=null;
Packit 1c1d7e
        index--;
Packit 1c1d7e
      }
Packit 1c1d7e
      return focusItem;
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    this.ProcessKeys = function(e)
Packit 1c1d7e
    {
Packit 1c1d7e
      if (e.type == "keydown")
Packit 1c1d7e
      {
Packit 1c1d7e
        this.repeatOn = false;
Packit 1c1d7e
        this.lastKey = e.keyCode;
Packit 1c1d7e
      }
Packit 1c1d7e
      else if (e.type == "keypress")
Packit 1c1d7e
      {
Packit 1c1d7e
        if (!this.repeatOn)
Packit 1c1d7e
        {
Packit 1c1d7e
          if (this.lastKey) this.repeatOn = true;
Packit 1c1d7e
          return false; // ignore first keypress after keydown
Packit 1c1d7e
        }
Packit 1c1d7e
      }
Packit 1c1d7e
      else if (e.type == "keyup")
Packit 1c1d7e
      {
Packit 1c1d7e
        this.lastKey = 0;
Packit 1c1d7e
        this.repeatOn = false;
Packit 1c1d7e
      }
Packit 1c1d7e
      return this.lastKey!=0;
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    this.Nav = function(evt,itemIndex)
Packit 1c1d7e
    {
Packit 1c1d7e
      var e  = (evt) ? evt : window.event; // for IE
Packit 1c1d7e
      if (e.keyCode==13) return true;
Packit 1c1d7e
      if (!this.ProcessKeys(e)) return false;
Packit 1c1d7e
Packit 1c1d7e
      if (this.lastKey==38) // Up
Packit 1c1d7e
      {
Packit 1c1d7e
        var newIndex = itemIndex-1;
Packit 1c1d7e
        var focusItem = this.NavPrev(newIndex);
Packit 1c1d7e
        if (focusItem)
Packit 1c1d7e
        {
Packit 1c1d7e
          var child = this.FindChildElement(focusItem.parentNode.parentNode.id);
Packit 1c1d7e
          if (child && child.style.display == 'block') // children visible
Packit 1c1d7e
          {
Packit 1c1d7e
            var n=0;
Packit 1c1d7e
            var tmpElem;
Packit 1c1d7e
            while (1) // search for last child
Packit 1c1d7e
            {
Packit 1c1d7e
              tmpElem = document.getElementById('Item'+newIndex+'_c'+n);
Packit 1c1d7e
              if (tmpElem)
Packit 1c1d7e
              {
Packit 1c1d7e
                focusItem = tmpElem;
Packit 1c1d7e
              }
Packit 1c1d7e
              else // found it!
Packit 1c1d7e
              {
Packit 1c1d7e
                break;
Packit 1c1d7e
              }
Packit 1c1d7e
              n++;
Packit 1c1d7e
            }
Packit 1c1d7e
          }
Packit 1c1d7e
        }
Packit 1c1d7e
        if (focusItem)
Packit 1c1d7e
        {
Packit 1c1d7e
          focusItem.focus();
Packit 1c1d7e
        }
Packit 1c1d7e
        else // return focus to search field
Packit 1c1d7e
        {
Packit 1c1d7e
           parent.document.getElementById("MSearchField").focus();
Packit 1c1d7e
        }
Packit 1c1d7e
      }
Packit 1c1d7e
      else if (this.lastKey==40) // Down
Packit 1c1d7e
      {
Packit 1c1d7e
        var newIndex = itemIndex+1;
Packit 1c1d7e
        var focusItem;
Packit 1c1d7e
        var item = document.getElementById('Item'+itemIndex);
Packit 1c1d7e
        var elem = this.FindChildElement(item.parentNode.parentNode.id);
Packit 1c1d7e
        if (elem && elem.style.display == 'block') // children visible
Packit 1c1d7e
        {
Packit 1c1d7e
          focusItem = document.getElementById('Item'+itemIndex+'_c0');
Packit 1c1d7e
        }
Packit 1c1d7e
        if (!focusItem) focusItem = this.NavNext(newIndex);
Packit 1c1d7e
        if (focusItem)  focusItem.focus();
Packit 1c1d7e
      }
Packit 1c1d7e
      else if (this.lastKey==39) // Right
Packit 1c1d7e
      {
Packit 1c1d7e
        var item = document.getElementById('Item'+itemIndex);
Packit 1c1d7e
        var elem = this.FindChildElement(item.parentNode.parentNode.id);
Packit 1c1d7e
        if (elem) elem.style.display = 'block';
Packit 1c1d7e
      }
Packit 1c1d7e
      else if (this.lastKey==37) // Left
Packit 1c1d7e
      {
Packit 1c1d7e
        var item = document.getElementById('Item'+itemIndex);
Packit 1c1d7e
        var elem = this.FindChildElement(item.parentNode.parentNode.id);
Packit 1c1d7e
        if (elem) elem.style.display = 'none';
Packit 1c1d7e
      }
Packit 1c1d7e
      else if (this.lastKey==27) // Escape
Packit 1c1d7e
      {
Packit 1c1d7e
        parent.searchBox.CloseResultsWindow();
Packit 1c1d7e
        parent.document.getElementById("MSearchField").focus();
Packit 1c1d7e
      }
Packit 1c1d7e
      else if (this.lastKey==13) // Enter
Packit 1c1d7e
      {
Packit 1c1d7e
        return true;
Packit 1c1d7e
      }
Packit 1c1d7e
      return false;
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    this.NavChild = function(evt,itemIndex,childIndex)
Packit 1c1d7e
    {
Packit 1c1d7e
      var e  = (evt) ? evt : window.event; // for IE
Packit 1c1d7e
      if (e.keyCode==13) return true;
Packit 1c1d7e
      if (!this.ProcessKeys(e)) return false;
Packit 1c1d7e
Packit 1c1d7e
      if (this.lastKey==38) // Up
Packit 1c1d7e
      {
Packit 1c1d7e
        if (childIndex>0)
Packit 1c1d7e
        {
Packit 1c1d7e
          var newIndex = childIndex-1;
Packit 1c1d7e
          document.getElementById('Item'+itemIndex+'_c'+newIndex).focus();
Packit 1c1d7e
        }
Packit 1c1d7e
        else // already at first child, jump to parent
Packit 1c1d7e
        {
Packit 1c1d7e
          document.getElementById('Item'+itemIndex).focus();
Packit 1c1d7e
        }
Packit 1c1d7e
      }
Packit 1c1d7e
      else if (this.lastKey==40) // Down
Packit 1c1d7e
      {
Packit 1c1d7e
        var newIndex = childIndex+1;
Packit 1c1d7e
        var elem = document.getElementById('Item'+itemIndex+'_c'+newIndex);
Packit 1c1d7e
        if (!elem) // last child, jump to parent next parent
Packit 1c1d7e
        {
Packit 1c1d7e
          elem = this.NavNext(itemIndex+1);
Packit 1c1d7e
        }
Packit 1c1d7e
        if (elem)
Packit 1c1d7e
        {
Packit 1c1d7e
          elem.focus();
Packit 1c1d7e
        }
Packit 1c1d7e
      }
Packit 1c1d7e
      else if (this.lastKey==27) // Escape
Packit 1c1d7e
      {
Packit 1c1d7e
        parent.searchBox.CloseResultsWindow();
Packit 1c1d7e
        parent.document.getElementById("MSearchField").focus();
Packit 1c1d7e
      }
Packit 1c1d7e
      else if (this.lastKey==13) // Enter
Packit 1c1d7e
      {
Packit 1c1d7e
        return true;
Packit 1c1d7e
      }
Packit 1c1d7e
      return false;
Packit 1c1d7e
    }
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
function setKeyActions(elem,action)
Packit 1c1d7e
{
Packit 1c1d7e
  elem.setAttribute('onkeydown',action);
Packit 1c1d7e
  elem.setAttribute('onkeypress',action);
Packit 1c1d7e
  elem.setAttribute('onkeyup',action);
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
function setClassAttr(elem,attr)
Packit 1c1d7e
{
Packit 1c1d7e
  elem.setAttribute('class',attr);
Packit 1c1d7e
  elem.setAttribute('className',attr);
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
function createResults()
Packit 1c1d7e
{
Packit 1c1d7e
  var results = document.getElementById("SRResults");
Packit 1c1d7e
  for (var e=0; e
Packit 1c1d7e
  {
Packit 1c1d7e
    var id = searchData[e][0];
Packit 1c1d7e
    var srResult = document.createElement('div');
Packit 1c1d7e
    srResult.setAttribute('id','SR_'+id);
Packit 1c1d7e
    setClassAttr(srResult,'SRResult');
Packit 1c1d7e
    var srEntry = document.createElement('div');
Packit 1c1d7e
    setClassAttr(srEntry,'SREntry');
Packit 1c1d7e
    var srLink = document.createElement('a');
Packit 1c1d7e
    srLink.setAttribute('id','Item'+e);
Packit 1c1d7e
    setKeyActions(srLink,'return searchResults.Nav(event,'+e+')');
Packit 1c1d7e
    setClassAttr(srLink,'SRSymbol');
Packit 1c1d7e
    srLink.innerHTML = searchData[e][1][0];
Packit 1c1d7e
    srEntry.appendChild(srLink);
Packit 1c1d7e
    if (searchData[e][1].length==2) // single result
Packit 1c1d7e
    {
Packit 1c1d7e
      srLink.setAttribute('href',searchData[e][1][1][0]);
Packit 1c1d7e
      if (searchData[e][1][1][1])
Packit 1c1d7e
      {
Packit 1c1d7e
       srLink.setAttribute('target','_parent');
Packit 1c1d7e
      }
Packit 1c1d7e
      var srScope = document.createElement('span');
Packit 1c1d7e
      setClassAttr(srScope,'SRScope');
Packit 1c1d7e
      srScope.innerHTML = searchData[e][1][1][2];
Packit 1c1d7e
      srEntry.appendChild(srScope);
Packit 1c1d7e
    }
Packit 1c1d7e
    else // multiple results
Packit 1c1d7e
    {
Packit 1c1d7e
      srLink.setAttribute('href','javascript:searchResults.Toggle("SR_'+id+'")');
Packit 1c1d7e
      var srChildren = document.createElement('div');
Packit 1c1d7e
      setClassAttr(srChildren,'SRChildren');
Packit 1c1d7e
      for (var c=0; c
Packit 1c1d7e
      {
Packit 1c1d7e
        var srChild = document.createElement('a');
Packit 1c1d7e
        srChild.setAttribute('id','Item'+e+'_c'+c);
Packit 1c1d7e
        setKeyActions(srChild,'return searchResults.NavChild(event,'+e+','+c+')');
Packit 1c1d7e
        setClassAttr(srChild,'SRScope');
Packit 1c1d7e
        srChild.setAttribute('href',searchData[e][1][c+1][0]);
Packit 1c1d7e
        if (searchData[e][1][c+1][1])
Packit 1c1d7e
        {
Packit 1c1d7e
         srChild.setAttribute('target','_parent');
Packit 1c1d7e
        }
Packit 1c1d7e
        srChild.innerHTML = searchData[e][1][c+1][2];
Packit 1c1d7e
        srChildren.appendChild(srChild);
Packit 1c1d7e
      }
Packit 1c1d7e
      srEntry.appendChild(srChildren);
Packit 1c1d7e
    }
Packit 1c1d7e
    srResult.appendChild(srEntry);
Packit 1c1d7e
    results.appendChild(srResult);
Packit 1c1d7e
  }
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
function init_search()
Packit 1c1d7e
{
Packit 1c1d7e
  var results = document.getElementById("MSearchSelectWindow");
Packit 1c1d7e
  for (var key in indexSectionLabels)
Packit 1c1d7e
  {
Packit 1c1d7e
    var link = document.createElement('a');
Packit 1c1d7e
    link.setAttribute('class','SelectItem');
Packit 1c1d7e
    link.setAttribute('onclick','searchBox.OnSelectItem('+key+')');
Packit 1c1d7e
    link.href='javascript:void(0)';
Packit 1c1d7e
    link.innerHTML=' '+indexSectionLabels[key];
Packit 1c1d7e
    results.appendChild(link);
Packit 1c1d7e
  }
Packit 1c1d7e
  searchBox.OnSelectItem(0);
Packit 1c1d7e
}
Packit 1c1d7e
/* @license-end */