annotate doc/html/search/search.js @ 23:92ee4ace9d46 develop

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