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