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